Antkeeper  0.0.1
nest-selection-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 #include "game/ant/ant-genome.hpp"
23 #include "game/ant/ant-phenome.hpp"
48 #include "game/controls.hpp"
49 #include "game/spawn.hpp"
56 #include "game/world.hpp"
59 #include <engine/config.hpp>
61 #include <engine/input/mouse.hpp>
76 
78  game_state(ctx)
79 {
80  debug::log_trace("Entering nest selection state...");
81 
82  // Create world if not yet created
83  if (ctx.entities.find("earth") == ctx.entities.end())
84  {
85  // Create cosmos
87 
88  // Create observer
90  }
91 
92  ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
94 
95  debug::log_trace("Generating genome...");
96  std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
97  debug::log_trace("Generated genome");
98 
99  debug::log_trace("Building worker phenome...");
100  ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen);
101  debug::log_trace("Built worker phenome...");
102 
103  debug::log_trace("Generating worker model...");
104  worker_model = ant_morphogenesis(worker_phenome);
105  debug::log_trace("Generated worker model");
106 
107  // Create floor plane
108 
109  auto floor_archetype = ctx.resource_manager->load<entity::archetype>("desert-scrub-plane.ent");
110  auto floor_eid = floor_archetype->create(*ctx.entity_registry);
111 
113  (
114  floor_eid,
115  [](auto& component)
116  {
117  component.local.rotation = math::angle_axis(math::radians(3.0f), math::fvec3{1.0f, 0.0f, 0.0f});
118  }
119  );
120 
121  auto floor_body = std::make_unique<physics::rigid_body>();
122  auto floor_collider = std::make_shared<physics::plane_collider>(math::fvec3{0.0f, 1.0f, 0.0f});
123  floor_collider->set_layer_mask(0b11);
124  floor_collider->set_material(std::make_shared<physics::collider_material>(1.0f, 0.5f, 1.0f));
125  floor_body->set_mass(0.0f);
126  floor_body->set_inertia(0.0f);
127  floor_body->set_collider(std::move(floor_collider));
128  ctx.entity_registry->emplace<rigid_body_component>(floor_eid, std::move(floor_body));
129 
130  // Create worker entity(s)
131 
132 
133  auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
134 
135  worker_ant_eid = ctx.entity_registry->create();
136  transform_component worker_transform_component;
137  worker_transform_component.local = math::transform<float>::identity();
138  worker_transform_component.local.translation = {0, 0.5f, -4};
139  worker_transform_component.world = worker_transform_component.local;
140  ctx.entity_registry->emplace<transform_component>(worker_ant_eid, worker_transform_component);
141  ctx.entity_registry->emplace<scene_component>(worker_ant_eid, std::move(worker_skeletal_mesh), std::uint8_t{1});
142 
143 
144 
145  auto worker_collider = std::make_shared<physics::box_collider>(math::fvec3{-1.0f, -1.0f, -1.0f}, math::fvec3{1.0f, 1.0f, 1.0f});
146  //auto worker_collider = std::make_shared<physics::sphere_collider>(1.0f);
147  worker_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
148 
149  auto worker_body = std::make_unique<physics::rigid_body>();
150  worker_body->set_position(worker_transform_component.local.translation);
151  worker_body->set_previous_position(worker_transform_component.local.translation);
152  worker_body->set_mass(0.1f);
153  worker_body->set_inertia(0.05f);
154  worker_body->set_angular_damping(0.5f);
155  worker_body->set_collider(std::move(worker_collider));
156  //ctx.entity_registry->emplace<rigid_body_component>(worker_ant_eid, std::move(worker_body));
157 
158 
159  auto cocoon_eid = ctx.entity_registry->create();
160  ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::make_shared<scene::static_mesh>(worker_phenome.pupa->cocoon_model), std::uint8_t{1});
161 
162 
163  larva_eid = ctx.entity_registry->create();
164 
165  auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
166  //auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(ctx.resource_manager->load<render::model>("snake.mdl"));
167  const auto& larva_skeleton = larva_skeletal_mesh->get_model()->get_skeleton();
168 
169  auto larva_ik_rig = std::make_shared<ik_rig>(*larva_skeletal_mesh);
170 
171  auto no_twist_constraint = std::make_shared<swing_twist_ik_constraint>();
172  no_twist_constraint->set_twist_limit(0.0f, 0.0f);
173 
174  //auto euler_constraint = std::make_shared<euler_ik_constraint>();
175  //euler_constraint->set_limits({0.0f, -math::radians(90.0f), 0.0f}, {math::radians(90.0f), math::radians(90.0f), 0.0f});
176 
177  for (std::size_t i = 0; i < larva_skeleton.get_bone_count(); ++i)
178  {
179  larva_ik_rig->set_constraint(static_cast<bone_index_type>(i), no_twist_constraint);
180  }
181 
182  const auto larva_ik_root_bone_index = *larva_skeleton.get_bone_index("abdomen3");
183  const auto larva_ik_effector_bone_index = *larva_skeleton.get_bone_index("head");
184 
185  const auto& larva_head_absolute_transform = larva_skeletal_mesh->get_pose().get_absolute_transform(larva_ik_effector_bone_index);
186  const auto& larva_head_relative_transform = larva_skeletal_mesh->get_pose().get_relative_transform(larva_ik_effector_bone_index);
187 
188  larva_ik_solver = std::make_shared<ccd_ik_solver>(*larva_ik_rig, larva_ik_root_bone_index, larva_ik_effector_bone_index);
189  larva_ik_solver->set_effector_position(larva_head_relative_transform * math::fvec3{0.0f, 0.0f, -0.0f});
190  larva_ik_solver->set_goal_center(larva_head_absolute_transform.translation + math::fvec3{0.2f, 0.2f, 0.5f});
191 
192 
193 
194  larva_ik_rig->add_solver(larva_ik_solver);
195 
196  //larva_skeletal_mesh->get_pose().set_relative_rotation(larva_ik_root_bone_index, math::angle_axis(math::radians(45.0f), math::fvec3{1.0f, 0.0f, 0.0f}));
197  //larva_skeletal_mesh->get_pose().update();
198 
199  ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{1});
200  ctx.entity_registry->emplace<ik_component>(larva_eid, std::move(larva_ik_rig));
201 
202 
203  // Set world time
204  ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
205 
206  // Init time scale
207  double time_scale = 60.0;
208 
209  // Set time scale
210  ::world::set_time_scale(ctx, time_scale);
211 
212  // Setup and enable sky and ground passes
213  ctx.sky_pass->set_enabled(true);
214 
215  // Set camera exposure
216  const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
217  ctx.surface_camera->set_exposure_value(ev100_sunny16);
218 
219  const auto& viewport_size = ctx.window->get_viewport_size();
220  const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
221 
222  // Init first person camera rig parameters
223  first_person_camera_rig_translation_spring_angular_frequency = physics::s_to_rads(0.125f);
224  first_person_camera_rig_rotation_spring_angular_frequency = physics::s_to_rads(0.125f);
225  first_person_camera_rig_fov_spring_angular_frequency = physics::s_to_rads(0.125f);
226  first_person_camera_rig_min_elevation = 0.25f;
227  first_person_camera_rig_max_elevation = 150.0f;
228  first_person_camera_near_fov = math::vertical_fov(math::radians(100.0f), aspect_ratio);
229  first_person_camera_far_fov = math::vertical_fov(math::radians(60.0f), aspect_ratio);
230  first_person_camera_near_speed = 5.0f;
231  first_person_camera_far_speed = 140.0f;
232  first_person_camera_rig_pedestal_speed = 2.0f;
233  first_person_camera_rig_pedestal = 0.0f;
234 
235  // Create first person camera rig
236  create_first_person_camera_rig();
237 
238  // Satisfy first person camera rig constraints
239  satisfy_first_person_camera_rig_constraints();
240 
241  // Setup controls
242  setup_controls();
243 
244  auto color_checker_archetype = ctx.resource_manager->load<entity::archetype>("color-checker.ent");
245  color_checker_archetype->create(*ctx.entity_registry);
246  // auto ruler_archetype = ctx.resource_manager->load<entity::archetype>("ruler-10cm.ent");
247  // ruler_archetype->create(*ctx.entity_registry);
248 
249 
250 
251  auto yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-l.ent");
252  auto yucca_eid = yucca_archetype->create(*ctx.entity_registry);
253  ::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 0, 70});
254 
255  yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-m.ent");
256  yucca_eid = yucca_archetype->create(*ctx.entity_registry);
257  ::command::warp_to(*ctx.entity_registry, yucca_eid, {400, 0, 200});
258 
259  yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-s.ent");
260  yucca_eid = yucca_archetype->create(*ctx.entity_registry);
261  ::command::warp_to(*ctx.entity_registry, yucca_eid, {-300, 0, -300});
262 
263  auto cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-l.ent");
264  auto cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
265  ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {-100, 0, -200});
266 
267  cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-m.ent");
268  cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
269  ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {100, 0, -70});
270 
271  cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-s.ent");
272  cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
273  ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {50, 0, 80});
274 
275  // auto cactus_seed_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-seed.ent");
276  // auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry);
277  // ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {0, 1, -5});
278 
279 
280  // Create spring
281  /*
282  auto spring_eid = ctx.entity_registry->create();
283  auto spring = std::make_unique<physics::spring_constraint>();
284  spring->attach_a();
285  spring->attach_b();
286  spring->set_resting_length(10.0f);
287  spring->set_stiffness(2.0f);
288  spring->set_damping(1.0f);
289  ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
290  */
291 
292  sky_probe = std::make_shared<scene::light_probe>();
293  const std::uint32_t sky_probe_face_size = 128;
294  const auto sky_probe_mip_levels = static_cast<std::uint32_t>(std::bit_width(sky_probe_face_size));
295  sky_probe->set_luminance_texture
296  (
297  std::make_shared<gl::texture_cube>
298  (
299  std::make_shared<gl::image_view_cube>
300  (
301  std::make_shared<gl::image_cube>
302  (
304  sky_probe_face_size,
305  sky_probe_mip_levels
306  ),
308  0,
309  sky_probe_mip_levels
310  ),
311  std::make_shared<gl::sampler>
312  (
318  )
319  )
320  );
321  ctx.sky_pass->set_sky_probe(sky_probe);
322  ctx.surface_scene->add_object(*sky_probe);
323 
324  // Create sphere
325  auto sphere_eid = ctx.entity_registry->create();
326  auto sphere_static_mesh = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("diffuse-spheres.mdl"));
327  ctx.entity_registry->emplace<scene_component>(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{1});
329  (
330  sphere_eid,
331  [&](auto& component)
332  {
333  component.object->set_translation({0.0f, 10.0f, 0.0f});
334  }
335  );
336 
337  // Queue enable game controls
338  ctx.function_queue.push
339  (
340  [&ctx]()
341  {
343  }
344  );
345 
346  // Queue fade in
347  ctx.fade_transition_color->set({0, 0, 0});
348  ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
349 
350  // Refresh frame scheduler
352 
353  debug::log_trace("Entered nest selection state");
354 }
355 
357 {
358  debug::log_trace("Exiting nest selection state...");
359 
360  // Disable game controls
362 
363  destroy_first_person_camera_rig();
364 
365  debug::log_trace("Exited nest selection state");
366 }
367 
368 void nest_selection_state::create_first_person_camera_rig()
369 {
370  // Construct first person camera rig transform component
371  transform_component first_person_camera_rig_transform;
372  first_person_camera_rig_transform.local = math::transform<float>::identity();
373  first_person_camera_rig_transform.local.translation = {0, 10, 0};
374  first_person_camera_rig_transform.world = first_person_camera_rig_transform.local;
375 
376  // Construct first person camera rig locomotion component
377  winged_locomotion_component first_person_camera_rig_locomotion;
378 
379  // Construct first person camera rig physics component
380  auto first_person_camera_rig_body = std::make_unique<physics::rigid_body>();
381  first_person_camera_rig_body->set_position({0, 10, 0});
382  first_person_camera_rig_body->set_mass(1.0f);
383  first_person_camera_rig_body->set_linear_damping(10.0f);
384  first_person_camera_rig_body->set_angular_damping(0.5f);
385  auto first_person_camera_rig_collider = std::make_shared<physics::sphere_collider>(1.0f);
386  auto camera_collider_material = std::make_shared<physics::collider_material>(0.0f, 0.0f, 0.0f);
387  camera_collider_material->set_restitution_combine_mode(physics::restitution_combine_mode::minimum);
388  camera_collider_material->set_friction_combine_mode(physics::friction_combine_mode::minimum);
389 
390  first_person_camera_rig_collider->set_layer_mask(0b10);
391  first_person_camera_rig_collider->set_material(std::move(camera_collider_material));
392  first_person_camera_rig_body->set_collider(std::move(first_person_camera_rig_collider));
393 
394  // Construct first person camera rig scene component
395  scene_component first_person_camera_rig_camera;
396  first_person_camera_rig_camera.object = ctx.surface_camera;
397 
398  // Construct first person camera rig entity
399  first_person_camera_rig_eid = ctx.entity_registry->create();
400  ctx.entity_registry->emplace<scene_component>(first_person_camera_rig_eid, first_person_camera_rig_camera);
401  ctx.entity_registry->emplace<transform_component>(first_person_camera_rig_eid, first_person_camera_rig_transform);
402  ctx.entity_registry->emplace<rigid_body_component>(first_person_camera_rig_eid, std::move(first_person_camera_rig_body));
403  ctx.entity_registry->emplace<winged_locomotion_component>(first_person_camera_rig_eid, first_person_camera_rig_locomotion);
404 }
405 
406 void nest_selection_state::destroy_first_person_camera_rig()
407 {
408  ctx.entity_registry->destroy(first_person_camera_rig_eid);
409 }
410 
411 void nest_selection_state::set_first_person_camera_rig_pedestal(float pedestal)
412 {
413 
414 }
415 
416 void nest_selection_state::move_first_person_camera_rig(const math::fvec2& direction, float factor)
417 {
418 
419 }
420 
421 void nest_selection_state::satisfy_first_person_camera_rig_constraints()
422 {
423 
424 }
425 
426 void nest_selection_state::setup_controls()
427 {
428 
429  constexpr float movement_speed = 200.0f;
430 
431  auto move_first_person_camera_rig = [&](const math::fvec2& direction, float speed)
432  {
433  const transform_component& first_person_camera_rig_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
434 
435  const math::fquat yaw_rotation = math::angle_axis(static_cast<float>(first_person_camera_yaw), math::fvec3{0.0f, 1.0f, 0.0f});
436 
437  const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]};
438 
439  const math::fvec3 force = rotated_direction * speed;
440 
441 
442  moving = true;
443  movement_direction = direction;
444  this->movement_speed = speed;
445 
447  (
448  first_person_camera_rig_eid,
449  [&](auto& component)
450  {
451  component.force = force;
452  }
453  );
454  };
455 
456  auto stop_first_person_camera_rig = [&]()
457  {
458  moving = false;
459 
461  (
462  first_person_camera_rig_eid,
463  [&](auto& component)
464  {
465  component.force = {0.0f, 0.0f, 0.0f};
466  }
467  );
468  };
469 
470  // Mouse look
471  mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
472  (
473  [&, move_first_person_camera_rig](const auto& event)
474  {
475  if (adjust_time)
476  {
477  const double sensitivity = 1.0 / static_cast<double>(ctx.window->get_viewport_size().x());
478  const double t = ctx.astronomy_system->get_time();
479  ::world::set_time(ctx, t + static_cast<double>(event.difference.x()) * sensitivity);
480 
481  /*
482  sky_probe->update_illuminance_matrices();
483 
484  const auto matrices = sky_probe->get_illuminance_matrices();
485  for (std::size_t i = 0; i < 3; ++i)
486  {
487  const auto m = matrices[i];
488  debug::log_warning("\nmat4({},{},{},{},\n{},{},{},{},\n{},{},{},{},\n{},{},{},{});", m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3]);
489  }
490  */
491  }
492 
493  if (adjust_exposure)
494  {
495  const float sensitivity = 8.0f / static_cast<float>(ctx.window->get_viewport_size().y());
496  ctx.surface_camera->set_exposure_value(ctx.surface_camera->get_exposure_value() + static_cast<float>(event.difference.y()) * sensitivity);
497  }
498 
499  if (!mouse_look)
500  {
501  return;
502  }
503 
504  first_person_camera_yaw -= ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
505  first_person_camera_pitch += ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
506  first_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, first_person_camera_pitch));
507 
508  const math::dquat yaw_rotation = math::angle_axis(first_person_camera_yaw, {0.0f, 1.0, 0.0});
509  const math::dquat pitch_rotation = math::angle_axis(first_person_camera_pitch, {-1.0, 0.0, 0.0});
510  const math::fquat first_person_camera_orientation = math::fquat(math::normalize(yaw_rotation * pitch_rotation));
511 
513  (
514  first_person_camera_rig_eid,
515  [&](auto& component)
516  {
517  component.object->set_rotation(first_person_camera_orientation);
518  }
519  );
520 
522  (
523  first_person_camera_rig_eid,
524  [&](auto& component)
525  {
526  component.body->set_previous_orientation(first_person_camera_orientation);
527  component.body->set_orientation(first_person_camera_orientation);
528  }
529  );
530 
532  (
533  first_person_camera_rig_eid,
534  [&](auto& component)
535  {
536  component.local.rotation = first_person_camera_orientation;
537  component.world.rotation = first_person_camera_orientation;
538  }
539  );
540 
541  if (moving)
542  {
543  move_first_person_camera_rig(movement_direction, this->movement_speed);
544  }
545  }
546  );
547 
548  // Move forward
549  action_subscriptions.emplace_back
550  (
552  (
553  [&, move_first_person_camera_rig](const auto& event)
554  {
555  move_first_person_camera_rig({0.0f, -1.0f}, movement_speed * event.input_value);
556  }
557  )
558  );
559  action_subscriptions.emplace_back
560  (
562  (
563  [&, stop_first_person_camera_rig](const auto& event)
564  {
565  stop_first_person_camera_rig();
566  }
567  )
568  );
569 
570  // Move back
571  action_subscriptions.emplace_back
572  (
574  (
575  [&, move_first_person_camera_rig](const auto& event)
576  {
577  move_first_person_camera_rig({0, 1}, movement_speed * event.input_value);
578  }
579  )
580  );
581  action_subscriptions.emplace_back
582  (
584  (
585  [&, stop_first_person_camera_rig](const auto& event)
586  {
587  stop_first_person_camera_rig();
588  }
589  )
590  );
591 
592  // Move left
593  action_subscriptions.emplace_back
594  (
596  (
597  [&, move_first_person_camera_rig](const auto& event)
598  {
599  move_first_person_camera_rig({-1, 0}, movement_speed * event.input_value);
600  }
601  )
602  );
603  action_subscriptions.emplace_back
604  (
606  (
607  [&, stop_first_person_camera_rig](const auto& event)
608  {
609  stop_first_person_camera_rig();
610  }
611  )
612  );
613 
614  // Move right
615  action_subscriptions.emplace_back
616  (
618  (
619  [&, move_first_person_camera_rig](const auto& event)
620  {
621  move_first_person_camera_rig({1, 0}, movement_speed * event.input_value);
622  }
623  )
624  );
625  action_subscriptions.emplace_back
626  (
628  (
629  [&, stop_first_person_camera_rig](const auto& event)
630  {
631  stop_first_person_camera_rig();
632  }
633  )
634  );
635 
636  // Move up
637  action_subscriptions.emplace_back
638  (
640  (
641  [&](const auto& event)
642  {
644  (
645  first_person_camera_rig_eid,
646  [&](auto& component)
647  {
648  component.body->apply_central_impulse({0, 5.0f, 0});
649  }
650  );
651  }
652  )
653  );
654 
655  // Move down
656  action_subscriptions.emplace_back
657  (
659  (
660  [&](const auto& event)
661  {
663  (
664  first_person_camera_rig_eid,
665  [&](auto& component)
666  {
667  component.body->apply_central_impulse({0, -5.0f, 0});
668  }
669  );
670  }
671  )
672  );
673 
674  /*
675  // Focus
676  action_subscriptions.emplace_back
677  (
678  ctx.focus_action.get_activated_channel().subscribe
679  (
680  [&](const auto& event)
681  {
682  auto projectile_eid = ctx.entity_registry->create();
683 
684  const auto& camera_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
685 
686  scene_component projectile_scene;
687 
688 
689  transform_component projectile_transform;
690  projectile_transform.local = camera_transform.world;
691  projectile_transform.world = projectile_transform.local;
692 
693  auto projectile_body = std::make_unique<physics::rigid_body>();
694  projectile_body->set_position(camera_transform.world.translation);
695  projectile_body->set_previous_position(camera_transform.world.translation);
696  projectile_body->set_mass(0.1f);
697  projectile_body->set_inertia(0.05f);
698  projectile_body->set_angular_damping(0.5f);
699 
700  if (ctx.mouse_look_action.is_active())
701  {
702  auto projectile_collider = std::make_shared<physics::sphere_collider>(1.0f);
703  //auto projectile_collider = std::make_shared<physics::box_collider>(math::fvec3{-1.0f, -1.0f, -1.0f}, math::fvec3{1.0f, 1.0f, 1.0f});
704  projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
705  projectile_body->set_collider(std::move(projectile_collider));
706 
707  projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("sphere.mdl"));
708  //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("cube.mdl"));
709  }
710  else
711  {
712  auto projectile_collider = std::make_shared<physics::capsule_collider>(geom::capsule<float>{{{0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f}}, 0.6f});
713  projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
714  projectile_body->set_collider(std::move(projectile_collider));
715 
716 
717  //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("capsule.mdl"));
718 
719  auto projectile_mesh = std::make_shared<scene::skeletal_mesh>(worker_model);
720  projectile_mesh->get_pose() = *worker_model->get_skeleton().get_pose("pupa");
721  projectile_scene.object = projectile_mesh;
722  }
723 
724  projectile_body->apply_central_impulse(camera_transform.world.rotation * math::fvec3{0.0f, 0.0f, -10.0f});
725 
726 
727  // auto spring_eid = ctx.entity_registry->create();
728  // auto spring = std::make_unique<physics::spring_constraint>();
729  // spring->attach_a(*ctx.entity_registry->get<rigid_body_component>(first_person_camera_rig_eid).body, {0.0f, 0.0f, 0.0f});
730  // spring->attach_b(*projectile_body, {0.0f, 0.0f, 0.0f});
731  // spring->set_resting_length(10.0f);
732  // spring->set_stiffness(2.0f);
733  // spring->set_damping(1.0f);
734  // ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
735 
736  ctx.entity_registry->emplace<transform_component>(projectile_eid, projectile_transform);
737  ctx.entity_registry->emplace<scene_component>(projectile_eid, std::move(projectile_scene));
738  ctx.entity_registry->emplace<rigid_body_component>(projectile_eid, std::move(projectile_body));
739 
740 
741  // body.linear_momentum = math::fvec3::zero();
742  // body.angular_momentum = math::fvec3::zero();
743  // body.linear_velocity = math::fvec3::zero();
744  // body.angular_velocity = math::fvec3::zero();
745 
746  //body.apply_central_impulse({0.0f, 100.5f, 0.0f});
747 
748  // ctx.entity_registry->patch<constraint_stack_node_component>
749  // (
750  // first_person_camera_rig_track_to_eid,
751  // [&](auto& component)
752  // {
753  // component.active = true;
754  // }
755  // );
756  }
757  )
758  );
759  action_subscriptions.emplace_back
760  (
761  ctx.focus_action.get_deactivated_channel().subscribe
762  (
763  [&](const auto& event)
764  {
765 
766  }
767  )
768  );
769  */
770 }
771 
772 void nest_selection_state::enable_controls()
773 {
774 
775 }
776 
777 void nest_selection_state::disable_controls()
778 {
779 }
780 
@ queen
Queen caste.
std::unique_ptr< ant_genome > ant_cladogenesis(const ant_gene_pool &pool, URBG &urbg)
Generates an ant genome from a gene pool.
std::unique_ptr< render::model > ant_morphogenesis(const ant_phenome &phenome)
Generates a 3D model of an ant given its phenome.
std::uint16_t bone_index_type
Bone index type.
Definition: bone.hpp:31
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< scene::collection > surface_scene
Definition: game.hpp:356
input::action move_up_action
Definition: game.hpp:220
::frame_scheduler frame_scheduler
Definition: game.hpp:423
input::action move_down_action
Definition: game.hpp:221
input::action move_right_action
Definition: game.hpp:219
std::unique_ptr< screen_transition > fade_transition
Definition: game.hpp:371
std::shared_ptr< scene::camera > surface_camera
Definition: game.hpp:357
std::shared_ptr< ecoregion > active_ecoregion
Definition: game.hpp:426
input::action move_left_action
Definition: game.hpp:218
input::action move_forward_action
Definition: game.hpp:216
std::unique_ptr<::astronomy_system > astronomy_system
Definition: game.hpp:416
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
double mouse_tilt_factor
Definition: game.hpp:278
std::shared_ptr< render::matvar_fvec3 > fade_transition_color
Definition: game.hpp:372
std::unique_ptr< entity::registry > entity_registry
Definition: game.hpp:392
input::action move_back_action
Definition: game.hpp:217
std::unique_ptr< app::input_manager > input_manager
Definition: game.hpp:172
std::unordered_map< hash::fnv1a32_t, entity::id > entities
Definition: game.hpp:393
double mouse_pan_factor
Definition: game.hpp:277
::event::channel< action_active_event > & get_active_channel() noexcept
Returns the channel through which action active events are published.
Definition: action.hpp:97
::event::channel< action_deactivated_event > & get_deactivated_channel() noexcept
Returns the channel through which action deactivated events are published.
Definition: action.hpp:103
::event::channel< action_activated_event > & get_activated_channel() noexcept
Returns the channel through which action activated events are published.
Definition: action.hpp:91
void transition(float duration, bool reverse, animation< float >::interpolator_type interpolator, bool hide=true, const std::function< void()> &callback=nullptr)
void enable_game_controls(::game &ctx)
Definition: controls.cpp:412
void disable_game_controls(::game &ctx)
Definition: controls.cpp:417
void warp_to(entity::registry &registry, entity::id eid, const math::fvec3 &position)
Definition: commands.cpp:78
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.
quat< float > fquat
Quaternion with single-precision floating-point scalars.
Definition: quaternion.hpp:218
T vertical_fov(T h, T r)
Calculates a vertical FoV given a horizontal FoV and aspect ratio.
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1328
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
Definition: quaternion.hpp:679
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
constexpr vector< T, N > min(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the minimum elements of two vectors.
Definition: vector.hpp:1347
T from_settings(T n, T t, T s)
Exposure value from exposure settings.
Definition: exposure.hpp:75
@ minimum
Coefficient of restitution is calculated as min(a, b).
@ minimum
Coefficient of friction is calculated as min(a, b).
constexpr T s_to_rads(T t) noexcept
Converts oscillation period to angular frequency.
Definition: frequency.hpp:67
void cosmogenesis(::game &ctx)
Creates the cosmos.
Definition: world.cpp:86
void create_observer(::game &ctx)
Creates the observer.
Definition: world.cpp:98
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< render::model > model
3D model of the larva.
Complete set of ant phenes.
Definition: ant-phenome.hpp:52
const ant_pupa_phene * pupa
Definition: ant-phenome.hpp:66
const ant_larva_phene * larva
Definition: ant-phenome.hpp:74
std::shared_ptr< render::model > cocoon_model
3D model of the cocoon, if present.
Container for templated easing functions.
Definition: ease.hpp:71
Entity type template.
Definition: archetype.hpp:34
entity::id create(entity::registry &registry) const
Creates an instance of this archetype.
Definition: archetype.cpp:25
Event generated when a mouse has been moved.
Quaternion composed of a real scalar part and imaginary vector part.
Definition: quaternion.hpp:39
static constexpr transform identity() noexcept
Returns an identity transform.
Definition: transform.hpp:107
vector_type translation
Translation vector.
Definition: transform.hpp:50
n-dimensional vector.
Definition: vector.hpp:44
std::unique_ptr< physics::rigid_body > body
std::shared_ptr< scene::object_base > object
math::transform< float > world
math::transform< float > local