Antkeeper  0.0.1
treadmill-experiment-state.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
21 
23 #include "game/ant/ant-genome.hpp"
25 #include "game/ant/ant-phenome.hpp"
56 #include "game/controls.hpp"
57 #include "game/spawn.hpp"
65 #include "game/world.hpp"
68 #include <engine/config.hpp>
70 #include <engine/input/mouse.hpp>
89 #include <engine/color/color.hpp>
92 #include <engine/ai/navmesh.hpp>
94 
96  game_state(ctx)
97 {
98  debug::log_trace("Entering nest view state...");
99 
101 
102  ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
104 
105  debug::log_trace("Generating genome...");
106  std::shared_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
107  debug::log_trace("Generated genome");
108 
109  debug::log_trace("Building worker phenome...");
110  worker_phenome = std::make_shared<ant_phenome>(*genome, ant_caste_type::worker);
111  debug::log_trace("Built worker phenome...");
112 
113  debug::log_trace("Generating worker model...");
114  std::shared_ptr<render::model> worker_model = ant_morphogenesis(*worker_phenome);
115  debug::log_trace("Generated worker model");
116 
117  // Create nest exterior
118  {
119  scene_component nest_exterior_scene_component;
120  nest_exterior_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("cube-nest-200mm-exterior.mdl"));
121  nest_exterior_scene_component.layer_mask = 1;
122 
123  auto nest_exterior_mesh = ctx.resource_manager->load<geom::brep_mesh>("cube-nest-200mm-exterior.msh");
124 
125  auto nest_exterior_rigid_body = std::make_unique<physics::rigid_body>();
126  nest_exterior_rigid_body->set_mass(0.0f);
127  nest_exterior_rigid_body->set_collider(std::make_shared<physics::mesh_collider>(std::move(nest_exterior_mesh)));
128  nest_exterior_rigid_body->set_position({10, -20, -5});
129  nest_exterior_rigid_body->set_orientation(math::angle_axis(math::radians(30.0f), math::fvec3{1, 0, 0}));
130  nest_exterior_rigid_body->set_scale({0.5f, 1.0f, 0.75f});
131 
132  auto nest_exterior_eid = ctx.entity_registry->create();
133  ctx.entity_registry->emplace<scene_component>(nest_exterior_eid, std::move(nest_exterior_scene_component));
134  ctx.entity_registry->emplace<rigid_body_component>(nest_exterior_eid, std::move(nest_exterior_rigid_body));
135  }
136 
137  // Create nest interior
138  {
139  scene_component nest_interior_scene_component;
140  nest_interior_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("soil-nest.mdl"));
141  nest_interior_scene_component.object->set_layer_mask(0b10);
142  nest_interior_scene_component.layer_mask = 1;
143 
144  auto nest_interior_mesh = ctx.resource_manager->load<geom::brep_mesh>("soil-nest.msh");
145 
146  auto nest_interior_rigid_body = std::make_unique<physics::rigid_body>();
147  nest_interior_rigid_body->set_mass(0.0f);
148  nest_interior_rigid_body->set_collider(std::make_shared<physics::mesh_collider>(std::move(nest_interior_mesh)));
149  nest_interior_rigid_body->get_collider()->set_layer_mask(0b10);
150 
151  auto nest_interior_eid = ctx.entity_registry->create();
152  ctx.entity_registry->emplace<scene_component>(nest_interior_eid, std::move(nest_interior_scene_component));
153  ctx.entity_registry->emplace<rigid_body_component>(nest_interior_eid, std::move(nest_interior_rigid_body));
154  }
155 
156  // Generate terrain
157  {
158  auto heightmap = ctx.resource_manager->load<gl::image_2d>("chiricahua-s.png");
159  auto subdivisions = math::uvec2{0, 0};
160  // auto subdivisions = math::uvec2{3, 3};
161  auto transform = math::transform<float>::identity();
162  transform.scale.x() = 2000.0f;
163  transform.scale.y() = 400.0f;
164  transform.scale.z() = transform.scale.x();
165  // transform.scale *= 0.001f;
166  transform.translation.y() = -transform.scale.y() * 0.5f;
167  // transform.rotation = math::angle_axis(math::radians(45.0f), math::fvec3{0, 0, 1});
168  auto material = ctx.resource_manager->load<render::material>("desert-sand.mtl");
169  ctx.terrain_system->generate(heightmap, subdivisions, transform, material);
170  }
171 
172  // Generate vegetation
173  {
174  auto planet_eid = ctx.entity_registry->create();
176  scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("yucca-plant-l.mdl"));
177  scene.object->set_translation({0, 0, 0});
178  scene.layer_mask = 1;
179 
180  const auto placement_ray = geom::ray<float, 3>{{50.0f, 0.0f, 70.0f}, {0.0f, -1.0f, 0.0f}};
181  if (auto trace = ctx.physics_system->trace(placement_ray, entt::null, 1u))
182  {
183  const auto hit_distance = std::get<1>(*trace);
184  const auto& hit_normal = std::get<3>(*trace);
185 
186  scene.object->set_translation(placement_ray.extrapolate(hit_distance));
187  scene.object->set_rotation(math::rotation(math::fvec3{0, 1, 0}, hit_normal));
188  }
189 
190  ctx.entity_registry->emplace<scene_component>(planet_eid, std::move(scene));
191  }
192 
193 
194  // Create rectangle light
195  {
196  area_light = std::make_unique<scene::rectangle_light>();
197  area_light->set_luminous_flux(12.57f * 100.0f);
198  area_light->set_color_temperature(20000.0f);
199  area_light->set_translation({0.0f, 0.0f, 0.0f});
200  area_light->set_rotation(math::fquat::rotate_x(math::radians(90.0f)));
201  area_light->set_size({1.0f, 2.0f});
202  area_light->set_layer_mask(0b10);
203  ctx.surface_scene->add_object(*area_light);
204 
205  // Create light rectangle
206  auto light_rectangle_model = ctx.resource_manager->load<render::model>("light-rectangle.mdl");
207  auto light_rectangle_material = std::make_shared<render::material>(*light_rectangle_model->get_groups().front().material);
208  light_rectangle_emissive = std::static_pointer_cast<render::matvar_fvec3>(light_rectangle_material->get_variable("emissive"));
209  light_rectangle_emissive->set(area_light->get_colored_luminance());
210  auto light_rectangle_static_mesh = std::make_shared<scene::static_mesh>(light_rectangle_model);
211  light_rectangle_static_mesh->set_material(0, light_rectangle_material);
212  light_rectangle_static_mesh->set_transform(area_light->get_transform());
213  light_rectangle_static_mesh->set_layer_mask(area_light->get_layer_mask());
214  auto light_rectangle_eid = ctx.entity_registry->create();
215  ctx.entity_registry->emplace<scene_component>(light_rectangle_eid, std::move(light_rectangle_static_mesh), std::uint8_t{1});
216  }
217 
218  // Create worker
219  auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
220  worker_skeletal_mesh->set_layer_mask(0b11);
221 
222  // Create worker IK rig
223  const auto& worker_skeleton = worker_model->get_skeleton();
224  worker_ik_rig = std::make_shared<ik_rig>(*worker_skeletal_mesh);
225  auto mesocoxa_ik_constraint = std::make_shared<euler_ik_constraint>();
226  mesocoxa_ik_constraint->set_min_angles({-math::pi<float>, -math::pi<float>, -math::pi<float>});
227  mesocoxa_ik_constraint->set_max_angles({ math::pi<float>, math::pi<float>, math::pi<float>});
228  worker_ik_rig->set_constraint(*worker_skeleton.get_bone_index("mesocoxa_l"), std::move(mesocoxa_ik_constraint));
229 
230  // Pose worker
231  worker_skeletal_mesh->get_pose() = *worker_model->get_skeleton().get_pose("midswing");
232 
233  worker_eid = ctx.entity_registry->create();
234 
235 
236  pose_component worker_pose_component;
237  worker_pose_component.current_pose = worker_skeletal_mesh->get_skeleton()->get_rest_pose();
238  worker_pose_component.previous_pose = worker_pose_component.current_pose;
239 
240 
241 
242  ant_caste_component worker_caste_component;
243  worker_caste_component.type = ant_caste_type::worker;
244  worker_caste_component.phenome = worker_phenome;
245 
246  rigid_body_component worker_rigid_body_component;
247  worker_rigid_body_component.body = std::make_unique<physics::rigid_body>();
248  worker_rigid_body_component.body->set_mass(0.0f);
249  auto rigid_body_transform = worker_rigid_body_component.body->get_transform();
250  rigid_body_transform.scale = math::fvec3::one() * worker_phenome->body_size->mean_mesosoma_length;
251  worker_rigid_body_component.body->set_transform(rigid_body_transform);
252 
253  legged_locomotion_component worker_locomotion_component;
254  worker_locomotion_component.midstance_pose = worker_model->get_skeleton().get_pose("midstance");
255  worker_locomotion_component.midswing_pose = worker_model->get_skeleton().get_pose("midswing");
256  worker_locomotion_component.liftoff_pose = worker_model->get_skeleton().get_pose("liftoff");
257  worker_locomotion_component.touchdown_pose = worker_model->get_skeleton().get_pose("touchdown");
258  worker_locomotion_component.body_bone = *worker_skeleton.get_bone_index("mesosoma");
259  worker_locomotion_component.tip_bones =
260  {
261  *worker_skeleton.get_bone_index("protarsomere1_l"),
262  *worker_skeleton.get_bone_index("mesotarsomere1_l"),
263  *worker_skeleton.get_bone_index("metatarsomere1_l"),
264  *worker_skeleton.get_bone_index("protarsomere1_r"),
265  *worker_skeleton.get_bone_index("mesotarsomere1_r"),
266  *worker_skeleton.get_bone_index("metatarsomere1_r")
267  };
268  worker_locomotion_component.leg_bone_count = 4;
269  worker_locomotion_component.gait = std::make_shared<::gait>();
270  worker_locomotion_component.gait->frequency = 4.0f;
271  worker_locomotion_component.gait->steps.resize(6);
272  for (std::size_t i = 0; i < 6; ++i)
273  {
274  const float duty_factors[3] = {0.52f, 0.62f, 0.54f};
275  auto& step = worker_locomotion_component.gait->steps[i];
276  step.duty_factor = duty_factors[i % 3];
277  step.delay = (i % 2) ? 0.5f : 0.0f;
278  }
279  worker_locomotion_component.standing_height = worker_phenome->legs->standing_height;
280  worker_locomotion_component.stride_length = worker_phenome->legs->stride_length * worker_rigid_body_component.body->get_transform().scale.x();
281  worker_locomotion_component.max_angular_frequency = worker_phenome->legs->max_angular_frequency;
282 
283  navmesh_agent_component worker_navmesh_agent_component;
284 
285  ovary_component worker_ovary_component;
286  worker_ovary_component.egg_capacity = 4;
287  worker_ovary_component.egg_production_duration = 1.0f;
288  worker_ovary_component.oviposition_duration = 3.0f;
289  worker_ovary_component.ovipositor_bone = *worker_skeleton.get_bone_index("gaster");
290  worker_ovary_component.oviposition_path = {{0.0f, -0.141708f, -0.799793f}, {0.0f, -0.187388f, -1.02008f}};
291 
292  ctx.entity_registry->emplace<scene_component>(worker_eid, std::move(worker_skeletal_mesh), std::uint8_t{1});
293  ctx.entity_registry->emplace<navmesh_agent_component>(worker_eid, std::move(worker_navmesh_agent_component));
294  ctx.entity_registry->emplace<pose_component>(worker_eid, std::move(worker_pose_component));
295  ctx.entity_registry->emplace<legged_locomotion_component>(worker_eid, std::move(worker_locomotion_component));
296  ctx.entity_registry->emplace<ant_caste_component>(worker_eid, std::move(worker_caste_component));
297  ctx.entity_registry->emplace<rigid_body_component>(worker_eid, std::move(worker_rigid_body_component));
298  ctx.entity_registry->emplace<ovary_component>(worker_eid, std::move(worker_ovary_component));
299  ctx.entity_registry->emplace<ant_genome_component>(worker_eid, genome);
300 
301  // Set ant as controlled ant
302  ctx.controlled_ant_eid = worker_eid;
303 
304  // Create color checker
305  auto color_checker_eid = ctx.entity_registry->create();
306  scene_component color_checker_scene_component;
307  color_checker_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("color-checker.mdl"));
308  color_checker_scene_component.object->set_translation({0, 0, 4});
309  color_checker_scene_component.layer_mask = 1;
310  ctx.entity_registry->emplace<scene_component>(color_checker_eid, std::move(color_checker_scene_component));
311 
312  // Set world time
313  ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
314 
315  // Init time scale
316  double time_scale = 0.0;
317 
318  // Set time scale
319  ::world::set_time_scale(ctx, time_scale);
320 
321  // Setup and enable sky and ground passes
322  ctx.sky_pass->set_enabled(true);
323 
324  sky_probe = std::make_shared<scene::light_probe>();
325  const std::uint32_t sky_probe_face_size = 128;
326  const auto sky_probe_mip_levels = static_cast<std::uint32_t>(std::bit_width(sky_probe_face_size));
327  sky_probe->set_luminance_texture
328  (
329  std::make_shared<gl::texture_cube>
330  (
331  std::make_shared<gl::image_view_cube>
332  (
333  std::make_shared<gl::image_cube>
334  (
336  sky_probe_face_size,
337  sky_probe_mip_levels
338  ),
340  0,
341  sky_probe_mip_levels
342  ),
343  std::make_shared<gl::sampler>
344  (
350  )
351  )
352  );
353 
354  ctx.sky_pass->set_sky_probe(sky_probe);
355  ctx.surface_scene->add_object(*sky_probe);
356 
357  // Set camera exposure
358  const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
359  ctx.surface_camera->set_exposure_value(ev100_sunny16);
360 
361  const auto& viewport_size = ctx.window->get_viewport_size();
362  const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
363 
364  // Create third person camera rig
365  create_third_person_camera_rig();
366 
367  // Setup controls
368  setup_controls();
369 
370  // Queue enable game controls
371  ctx.function_queue.push
372  (
373  [&ctx]()
374  {
378  }
379  );
380 
381  // Queue fade in
382  ctx.fade_transition_color->set({0, 0, 0});
383  ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
384 
385  // Refresh frame scheduler
387 
388  debug::log_trace("Entered nest view state");
389 }
390 
392 {
393  debug::log_trace("Exiting nest view state...");
394 
395  // Disable game controls
399 
400  ctx.controlled_ant_eid = entt::null;
401 
402  destroy_third_person_camera_rig();
403 
404  debug::log_trace("Exited nest view state");
405 }
406 
407 void treadmill_experiment_state::create_third_person_camera_rig()
408 {
409  const auto& subject_rigid_body = *ctx.entity_registry->get<rigid_body_component>(ctx.controlled_ant_eid).body;
410  const auto subject_scale = static_cast<double>(subject_rigid_body.get_transform().scale.x());
411 
412  spring_arm_component spring_arm;
413  spring_arm.parent_eid = ctx.controlled_ant_eid;
414  spring_arm.near_focal_plane_height = 8.0 * subject_scale;
415  spring_arm.far_focal_plane_height = 80.0 * subject_scale;
416  spring_arm.near_hfov = math::radians(90.0);
417  // spring_arm.far_hfov = math::radians(45.0);
418  spring_arm.far_hfov = math::radians(90.0);
419  spring_arm.zoom = 0.25;
420  spring_arm.focal_point_offset = {0, static_cast<double>(worker_phenome->legs->standing_height) * subject_scale, 0};
421 
422  spring_arm.focal_point_spring.set_damping_ratio(1.0);
423  spring_arm.focal_point_spring.set_period(0.01);
424 
425  spring_arm.angles_spring.set_damping_ratio(1.0);
426  spring_arm.angles_spring.set_period(0.25);
427 
428  spring_arm.min_angles.x() = -math::half_pi<double>;
429  spring_arm.max_angles.x() = 0.0;
430 
431  third_person_camera_rig_eid = ctx.entity_registry->create();
432  ctx.entity_registry->emplace<scene_component>(third_person_camera_rig_eid, ctx.surface_camera, std::uint8_t{1});
433  ctx.entity_registry->emplace<spring_arm_component>(third_person_camera_rig_eid, std::move(spring_arm));
434  ctx.active_camera_eid = third_person_camera_rig_eid;
435 }
436 
437 void treadmill_experiment_state::destroy_third_person_camera_rig()
438 {
439  ctx.entity_registry->destroy(third_person_camera_rig_eid);
440 }
441 
442 void treadmill_experiment_state::set_third_person_camera_zoom(double zoom)
443 {
444 }
445 
446 void treadmill_experiment_state::set_third_person_camera_rotation(double yaw, double pitch)
447 {
448 }
449 
450 void treadmill_experiment_state::zoom_third_person_camera(double zoom)
451 {
452 }
453 
454 void treadmill_experiment_state::translate_third_person_camera(const math::dvec3& direction, double magnitude)
455 {
456 }
457 
458 void treadmill_experiment_state::rotate_third_person_camera(const input::mouse_moved_event& event)
459 {
460 }
461 
462 void treadmill_experiment_state::handle_mouse_motion(const input::mouse_moved_event& event)
463 {
464  ctx.surface_material_pass->set_mouse_position(math::fvec2(event.position));
465 
466  if (!mouse_look && !mouse_grip && !mouse_zoom)
467  {
468  return;
469  }
470 
471  if (mouse_grip)
472  {
473  const math::dvec2 viewport_size = math::dvec2(ctx.window->get_viewport_size());
474 
475  math::dvec3 translation
476  {
477  third_person_camera_focal_plane_width * (static_cast<double>(-event.difference.x()) / (viewport_size.x() - 1.0)),
478  0.0,
479  third_person_camera_focal_plane_height * (static_cast<double>(-event.difference.y()) / (viewport_size.y() - 1.0)),
480  };
481 
482  if (third_person_camera_pitch < 0.0)
483  {
484  translation.z() *= -1.0;
485  }
486 
487  third_person_camera_focal_point += third_person_camera_yaw_rotation * translation;
488  }
489 
490  if (mouse_look)
491  {
492  rotate_third_person_camera(event);
493  }
494 
495  if (mouse_zoom)
496  {
497  const double zoom_speed = -1.0 / static_cast<double>(ctx.window->get_viewport_size().y());
498  zoom_third_person_camera(static_cast<double>(event.difference.y()) * zoom_speed);
499  }
500 
501  update_third_person_camera();
502 }
503 
504 void treadmill_experiment_state::update_third_person_camera()
505 {
506 }
507 
508 void treadmill_experiment_state::load_camera_preset(std::uint8_t index)
509 {
510 
511 }
512 
513 void treadmill_experiment_state::save_camera_preset(std::uint8_t index)
514 {
515 
516 }
517 
518 void treadmill_experiment_state::load_or_save_camera_preset(std::uint8_t index)
519 {
520 
521 }
522 
523 geom::ray<float, 3> treadmill_experiment_state::get_mouse_ray(const math::vec2<std::int32_t>& mouse_position) const
524 {
525  // Get window viewport size
526  const auto& viewport_size = ctx.window->get_viewport_size();
527 
528  // Transform mouse coordinates from window space to NDC space
529  const math::fvec2 mouse_ndc =
530  {
531  static_cast<float>(mouse_position.x()) / static_cast<float>(viewport_size.x() - 1) * 2.0f - 1.0f,
532  (1.0f - static_cast<float>(mouse_position.y()) / static_cast<float>(viewport_size.y() - 1)) * 2.0f - 1.0f
533  };
534 
535  const auto& scene_component = ctx.entity_registry->get<::scene_component>(third_person_camera_rig_eid);
536  const auto& camera = static_cast<const scene::camera&>(*scene_component.object);
537 
538  return camera.pick(mouse_ndc);
539 }
540 
541 void treadmill_experiment_state::setup_controls()
542 {
543  // Enable/toggle mouse grip
544  action_subscriptions.emplace_back
545  (
547  (
548  [&](const auto& event)
549  {
550  mouse_grip = ctx.toggle_mouse_grip ? !mouse_grip : true;
551 
552  if (mouse_grip)
553  {
554  const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
555 
556  // Cast ray to plane
557  const auto mouse_ray = get_mouse_ray(mouse_position);
558  const auto intersection = geom::intersection(mouse_ray, mouse_grip_plane);
559  if (intersection)
560  {
561  mouse_grip_point = mouse_ray.origin + mouse_ray.direction * (*intersection);
562  }
563  }
564 
565  // BVH picking test
566  const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
567  const auto mouse_ray = get_mouse_ray(mouse_position);
568 
569  const auto& camera_object = *ctx.entity_registry->get<::scene_component>(ctx.active_camera_eid).object;
570 
571  if (auto trace = ctx.physics_system->trace(mouse_ray, entt::null, camera_object.get_layer_mask()))
572  {
573  // debug::log_debug("HIT! EID: {}; distance: {}; face: {}", static_cast<int>(std::get<0>(*trace)), std::get<1>(*trace), std::get<2>(*trace));
574 
575  const auto& hit_rigid_body = *ctx.entity_registry->get<rigid_body_component>(std::get<0>(*trace)).body;
576  const auto& hit_collider = *hit_rigid_body.get_collider();
577  const auto hit_distance = std::get<1>(*trace);
578  const auto& hit_normal = std::get<3>(*trace);
579 
580  geom::brep_mesh* hit_mesh = nullptr;
581  geom::brep_face* hit_face = nullptr;
582  if (hit_collider.type() == physics::collider_type::mesh)
583  {
584  hit_mesh = static_cast<const physics::mesh_collider&>(hit_collider).get_mesh().get();
585  hit_face = hit_mesh->faces()[std::get<2>(*trace)];
586  }
587 
588  // Update agent transform
589  auto& agent_rigid_body = *ctx.entity_registry->get<rigid_body_component>(worker_eid).body;
590  auto agent_transform = agent_rigid_body.get_transform();
591  agent_transform.translation = mouse_ray.extrapolate(hit_distance);
592  agent_transform.rotation = math::rotation(math::fvec3{0, 1, 0}, hit_normal);
593  agent_rigid_body.set_transform(agent_transform);
594  agent_rigid_body.set_previous_transform(agent_transform);
595 
596  // Update agent navmesh
598  (
599  worker_eid,
600  [&](auto& component)
601  {
602  component.navmesh_eid = std::get<0>(*trace);
603  component.mesh = hit_mesh;
604  component.face = hit_face;
605  component.surface_normal = hit_normal;
606  }
607  );
608  }
609  }
610  )
611  );
612 }
@ worker
Worker caste.
std::unique_ptr< ant_genome > ant_cladogenesis(const ant_gene_pool &pool, URBG &urbg)
Generates an ant genome from a gene pool.
void disable_ant_controls(::game &ctx)
void enable_ant_controls(::game &ctx)
std::unique_ptr< render::model > ant_morphogenesis(const ant_phenome &phenome)
Generates a 3D model of an ant given its phenome.
void disable_camera_controls(::game &ctx)
void enable_camera_controls(::game &ctx)
void refresh() noexcept
Resets the accumulated time (at) and frame timer, but not the elapsed fixed-rate update time.
Abstract base class for game states.
Definition: game-state.hpp:29
::game & ctx
Definition: game-state.hpp:44
Definition: game.hpp:121
std::unique_ptr<::terrain_system > terrain_system
Definition: game.hpp:412
std::unique_ptr< render::material_pass > surface_material_pass
Definition: game.hpp:328
std::unique_ptr< scene::collection > surface_scene
Definition: game.hpp:356
::frame_scheduler frame_scheduler
Definition: game.hpp:423
entity::id active_camera_eid
Definition: game.hpp:395
std::unique_ptr< screen_transition > fade_transition
Definition: game.hpp:371
std::shared_ptr< scene::camera > surface_camera
Definition: game.hpp:357
scene::collection * active_scene
Definition: game.hpp:364
std::shared_ptr< ecoregion > active_ecoregion
Definition: game.hpp:426
std::mt19937 rng
Definition: game.hpp:389
std::unique_ptr< resource_manager > resource_manager
Definition: game.hpp:152
std::unique_ptr< render::sky_pass > sky_pass
Definition: game.hpp:327
std::shared_ptr< app::window > window
Definition: game.hpp:166
std::queue< std::function< void()> > function_queue
Definition: game.hpp:303
std::shared_ptr< render::matvar_fvec3 > fade_transition_color
Definition: game.hpp:372
input::action camera_mouse_pick_action
Definition: game.hpp:227
std::unique_ptr<::physics_system > physics_system
Definition: game.hpp:409
entity::id controlled_ant_eid
Definition: game.hpp:394
std::unique_ptr< entity::registry > entity_registry
Definition: game.hpp:392
std::unique_ptr< app::input_manager > input_manager
Definition: game.hpp:172
Boundary representation (B-rep) of a mesh.
Definition: brep-mesh.hpp:34
2D image.
Definition: image.hpp:274
::event::channel< action_activated_event > & get_activated_channel() noexcept
Returns the channel through which action activated events are published.
Definition: action.hpp:91
const skeleton * get_skeleton() const noexcept
Returns the skeleton with which the pose is associated.
Definition: pose.hpp:104
A material is associated with exactly one shader program and contains a set of material properties wh...
Definition: material.hpp:37
void set_rotation(const quaternion_type &rotation)
Sets the rotation of the object.
Definition: object.hpp:96
void set_translation(const vector_type &translation)
Sets the translation of the object.
Definition: object.hpp:85
Abstract base class for lights, cameras, model instances, and other scene objects.
Definition: object.hpp:172
void transition(float duration, bool reverse, animation< float >::interpolator_type interpolator, bool hide=true, const std::function< void()> &callback=nullptr)
const animation_pose * get_pose(hash::fnv1a32_t name) const
Finds a pose from the poses's name.
Definition: skeleton.cpp:123
const rest_pose & get_rest_pose() const noexcept
Returns the skeleton's rest pose.
Definition: skeleton.hpp:187
void enable_game_controls(::game &ctx)
Definition: controls.cpp:412
void disable_game_controls(::game &ctx)
Definition: controls.cpp:417
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
Definition: log.hpp:88
Publish-subscribe messaging.
Definition: channel.hpp:32
@ clamp_to_edge
Clamp to edge wrap mode.
@ linear
Linear filtering.
@ linear
Linear filtering.
dvec< 2 > dvec2
n-dimensional vector of double-precision floating-point numbers.
Definition: vector.hpp:437
constexpr T trace(const matrix< T, N, N > &m) noexcept
Calculates the trace of a square matrix.
quaternion< T > angle_axis(T angle, const vec3< T > &axis)
Creates a rotation from an angle and axis.
Definition: quaternion.hpp:685
constexpr T radians(T degrees) noexcept
Converts an angle given in degrees to radians.
Definition: angles.hpp:48
quaternion< T > rotation(const vec3< T > &from, const vec3< T > &to, T tolerance=T{1e-6})
Constructs a quaternion representing the minimum rotation from one direction to another direction.
Definition: quaternion.hpp:691
T from_settings(T n, T t, T s)
Exposure value from exposure settings.
Definition: exposure.hpp:75
3D scene.
Definition: context.hpp:28
void enter_ecoregion(::game &ctx, const ecoregion &ecoregion)
Enters a ecoregion.
Definition: world.cpp:429
void set_time_scale(::game &ctx, double scale)
Sets rate at which time passes.
Definition: world.cpp:197
void set_time(::game &ctx, double t)
Sets the current time.
Definition: world.cpp:157
std::shared_ptr< ant_phenome > phenome
Subcaste type.
ant_caste_type type
Caste type.
Container for templated easing functions.
Definition: ease.hpp:71
Half of a line proceeding from an initial point.
Definition: ray.hpp:38
Event generated when a mouse has been moved.
Legged terrestrial locomotion.
float max_angular_frequency
Maximum angular frequency when turning, in radians per second.
std::uint8_t leg_bone_count
Number of bones per leg.
float stride_length
Distance covered in a single gait cycle.
std::vector< bone_index_type > tip_bones
Indices of the the final bones in the legs.
static quaternion rotate_x(scalar_type angle)
Returns a quaternion representing a rotation about the x-axis.
Definition: quaternion.hpp:110
static constexpr transform identity() noexcept
Returns an identity transform.
Definition: transform.hpp:107
n-dimensional vector.
Definition: vector.hpp:44
constexpr element_type & x() noexcept
Returns a reference to the first element.
Definition: vector.hpp:164
constexpr element_type & y() noexcept
Returns a reference to the second element.
Definition: vector.hpp:180
static constexpr vector one() noexcept
Returns a vector of ones, where every element is equal to one.
Definition: vector.hpp:324
geom::line_segment< float, 3 > oviposition_path
Path along which eggs travel while being oviposited, relative to the ovipositor bone.
bone_index_type ovipositor_bone
Bone of the ovipositor.
std::uint16_t egg_capacity
Maximum number of concurrent eggs.
float oviposition_duration
Duration required to lay an egg, in seconds.
float egg_production_duration
Duration required to produce an egg, in seconds.
pose current_pose
Pose of the current state.
pose previous_pose
Pose of the previous state.
std::unique_ptr< physics::rigid_body > body
std::uint8_t layer_mask
std::shared_ptr< scene::object_base > object
Attaches a camera to an entity using springs.
double near_hfov
Horizontal FoV at maximum zoom.
double far_hfov
Horizontal FoV at minimum zoom.
physics::numeric_spring< math::dvec3, double > focal_point_spring
double zoom
Zoom factor, on [0, 1].
math::dvec3 min_angles
Minimum pitch, yaw, and roll angles, in radians.
double far_focal_plane_height
Arm length spring.
math::dvec3 max_angles
Maximum pitch, yaw, and roll angles, in radians.
physics::numeric_spring< math::dvec3, double > angles_spring
Pitch, yaw, and roll angles spring.
entity::id parent_eid
ID of the entity to which the spring arm is attached.
math::dvec3 focal_point_offset
Position of the focal point, relative to the subject.
double near_focal_plane_height
Height of the view frustum at the near clipping distance.
Describes the timing of a single step in a gait.
Definition: step.hpp:27
float delay
Fraction of the gait cycle, on [0, 1], at which the limb enters the swing phase.
Definition: step.hpp:33
float duty_factor
Fraction of the gait cycle, on [0, 1], in which the limb is in the stance phase.
Definition: step.hpp:30