Antkeeper  0.0.1
nest-view-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"
50 #include "game/controls.hpp"
51 #include "game/spawn.hpp"
57 #include "game/world.hpp"
60 #include <engine/config.hpp>
62 #include <engine/input/mouse.hpp>
80 #include <engine/color/color.hpp>
83 #include <engine/ai/navmesh.hpp>
84 
86  game_state(ctx)
87 {
88  debug::log_trace("Entering nest view state...");
89 
90  // Create world if not yet created
91  if (ctx.entities.find("earth") == ctx.entities.end())
92  {
93  // Create cosmos
95 
96  // Create observer
98  }
99 
100  ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
102 
103  debug::log_trace("Generating genome...");
104  std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
105  debug::log_trace("Generated genome");
106 
107  debug::log_trace("Building worker phenome...");
108  worker_phenome = ant_phenome(*genome, ant_caste_type::worker);
109  debug::log_trace("Built worker phenome...");
110 
111  debug::log_trace("Generating worker model...");
112  std::shared_ptr<render::model> worker_model = ant_morphogenesis(worker_phenome);
113  debug::log_trace("Generated worker model");
114 
115  // Create directional light
116  // ctx.underground_directional_light = std::make_unique<scene::directional_light>();
117  // ctx.underground_directional_light->set_color({1.0f, 1.0f, 1.0f});
118  // ctx.underground_directional_light->set_illuminance(2.0f);
119  // ctx.underground_directional_light->set_direction(math::normalize(math::fvec3{0, -1, 0}));
120  // ctx.underground_directional_light->set_shadow_caster(true);
121  // ctx.underground_directional_light->set_shadow_framebuffer(ctx.shadow_map_framebuffer);
122  // ctx.underground_directional_light->set_shadow_bias(0.005f);
123  // ctx.underground_directional_light->set_shadow_cascade_count(4);
124  // ctx.underground_directional_light->set_shadow_cascade_coverage(0.15f);
125  // ctx.underground_directional_light->set_shadow_cascade_distribution(0.8f);
126  // ctx.underground_scene->add_object(*ctx.underground_directional_light);
127 
128  light_probe = std::make_shared<scene::light_probe>();
129  light_probe->set_luminance_texture(ctx.resource_manager->load<gl::texture_cube>("grey-furnace.tex"));
130  ctx.underground_scene->add_object(*light_probe);
131 
132  const math::fvec3 light_color{1.0f, 1.0f, 1.0f};
133 
134  // Create rectangle light
135  ctx.underground_rectangle_light = std::make_unique<scene::rectangle_light>();
136  ctx.underground_rectangle_light->set_color(light_color);
137  ctx.underground_rectangle_light->set_luminous_flux(1500.0f);
138  ctx.underground_rectangle_light->set_translation({0.0f, 10.0f, 0.0f});
140  ctx.underground_rectangle_light->set_scale(7.0f);
142 
143  // Create light rectangle
144  auto light_rectangle_model = ctx.resource_manager->load<render::model>("light-rectangle.mdl");
145  auto light_rectangle_material = std::make_shared<render::material>(*light_rectangle_model->get_groups().front().material);
146  light_rectangle_emissive = std::static_pointer_cast<render::matvar_fvec3>(light_rectangle_material->get_variable("emissive"));
147  light_rectangle_emissive->set(ctx.underground_rectangle_light->get_colored_luminance());
148  auto light_rectangle_static_mesh = std::make_shared<scene::static_mesh>(light_rectangle_model);
149  light_rectangle_static_mesh->set_material(0, light_rectangle_material);
150 
151  auto light_rectangle_eid = ctx.entity_registry->create();
152  ctx.entity_registry->emplace<scene_component>(light_rectangle_eid, std::move(light_rectangle_static_mesh), std::uint8_t{2});
154  (
155  light_rectangle_eid,
156  [&](auto& component)
157  {
158  component.object->set_transform(ctx.underground_rectangle_light->get_transform());
159  }
160  );
161 
162  // Create treadmill
163  auto treadmill_eid = ctx.entity_registry->create();
164  scene_component treadmill_scene_component;
165  treadmill_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("treadmill-5cm.mdl"));
166  treadmill_scene_component.layer_mask = 2;
167  ctx.entity_registry->emplace<scene_component>(treadmill_eid, std::move(treadmill_scene_component));
168 
169  // Create worker
170  auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
171  worker_eid = ctx.entity_registry->create();
172  transform_component worker_transform_component;
173  worker_transform_component.local = math::transform<float>::identity();
174  worker_transform_component.local.translation = {0, 0.1f, 0};
175  worker_transform_component.local.scale = math::fvec3::one() * worker_phenome.body_size->mean_mesosoma_length;
176  worker_transform_component.world = worker_transform_component.local;
177  ctx.entity_registry->emplace<transform_component>(worker_eid, worker_transform_component);
178  ctx.entity_registry->emplace<scene_component>(worker_eid, std::move(worker_skeletal_mesh), std::uint8_t{2});
179 
180  // Create cocoon
181  auto cocoon_eid = ctx.entity_registry->create();
182  auto cocoon_static_mesh = std::make_shared<scene::static_mesh>(worker_phenome.pupa->cocoon_model);
183  cocoon_static_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length);
184  ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::move(cocoon_static_mesh), std::uint8_t{2});
186  (
187  cocoon_eid,
188  [&](auto& component)
189  {
190  component.object->set_translation({-4.0f, 0.0f, 4.0f});
191  }
192  );
193 
194  // Create color checker
195  auto color_checker_eid = ctx.entity_registry->create();
196  scene_component color_checker_scene_component;
197  color_checker_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("color-checker.mdl"));
198  color_checker_scene_component.object->set_translation({0, 0, 4});
199  color_checker_scene_component.layer_mask = 2;
200  ctx.entity_registry->emplace<scene_component>(color_checker_eid, std::move(color_checker_scene_component));
201 
202  // Create larva
203  larva_eid = ctx.entity_registry->create();
204  auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
205  larva_skeletal_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length);
206  ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{2});
208  (
209  larva_eid,
210  [&](auto& component)
211  {
212  component.object->set_translation({4.0f, 0.0f, 4.0f});
213  }
214  );
215 
216  // Create sphere
217  // auto sphere_eid = ctx.entity_registry->create();
218  // auto sphere_static_mesh = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("sphere.mdl"));
219  // ctx.entity_registry->emplace<scene_component>(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{2});
220  // ctx.entity_registry->patch<scene_component>
221  // (
222  // sphere_eid,
223  // [&](auto& component)
224  // {
225  // component.object->set_translation({0.0f, 0.0f, 0.0f});
226  // }
227  // );
228 
229  // Set world time
230  ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
231 
232  // Init time scale
233  double time_scale = 60.0;
234 
235  // Set time scale
236  ::world::set_time_scale(ctx, time_scale);
237 
238  // Setup camera
239  ctx.underground_camera->set_exposure_value(0.0f);
240 
241  const auto& viewport_size = ctx.window->get_viewport_size();
242  const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
243 
244  // Create third person camera rig
245  create_third_person_camera_rig();
246 
247  // Setup controls
248  setup_controls();
249 
250  // Queue enable game controls
251  ctx.function_queue.push
252  (
253  [&ctx]()
254  {
256  }
257  );
258 
259  // Queue fade in
260  ctx.fade_transition_color->set({0, 0, 0});
261  ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
262 
263  // Refresh frame scheduler
265 
266  // Load navmesh
267  navmesh = ctx.resource_manager->load<geom::brep_mesh>("treadmill-5cm.msh");
268 
269  // Generate navmesh attributes
270  geom::generate_face_normals(*navmesh);
272 
273  // Build navmesh BVH
274  debug::log_info("building bvh");
275  navmesh_bvh = std::make_unique<geom::bvh>(*navmesh);
276  debug::log_info("building bvh done");
277 
278  debug::log_trace("Entered nest view state");
279 }
280 
282 {
283  debug::log_trace("Exiting nest view state...");
284 
285  // Disable game controls
287 
288  destroy_third_person_camera_rig();
289 
290  debug::log_trace("Exited nest view state");
291 }
292 
293 void nest_view_state::create_third_person_camera_rig()
294 {
295  // Construct third person camera rig scene component
296  scene_component third_person_camera_rig_camera;
297  third_person_camera_rig_camera.object = ctx.underground_camera;
298  third_person_camera_rig_camera.layer_mask = 2;
299 
300  // Construct third person camera rig entity
301  third_person_camera_rig_eid = ctx.entity_registry->create();
302  ctx.entity_registry->emplace<scene_component>(third_person_camera_rig_eid, third_person_camera_rig_camera);
303 
304  set_third_person_camera_zoom(third_person_camera_zoom);
305  set_third_person_camera_rotation(third_person_camera_yaw, third_person_camera_pitch);
306  update_third_person_camera();
307 }
308 
309 void nest_view_state::destroy_third_person_camera_rig()
310 {
311  ctx.entity_registry->destroy(third_person_camera_rig_eid);
312 }
313 
314 void nest_view_state::set_third_person_camera_zoom(double zoom)
315 {
316  // Clamp zoom
317  third_person_camera_zoom = std::min<double>(std::max<double>(zoom, 0.0), 1.0);
318 
319  // Update FoV
320  third_person_camera_hfov = ease<double, double>::out_sine(third_person_camera_far_hfov, third_person_camera_near_hfov, third_person_camera_zoom);
321  third_person_camera_vfov = math::vertical_fov(third_person_camera_hfov, static_cast<double>(ctx.underground_camera->get_aspect_ratio()));
322 
323  // Update focal plane size
324  third_person_camera_focal_plane_height = ease<double, double>::out_sine(third_person_camera_far_focal_plane_height, third_person_camera_near_focal_plane_height, third_person_camera_zoom);
325  third_person_camera_focal_plane_width = third_person_camera_focal_plane_height * ctx.underground_camera->get_aspect_ratio();
326 
327  // Update focal distance
328  third_person_camera_focal_distance = third_person_camera_focal_plane_height * 0.5 / std::tan(third_person_camera_vfov * 0.5);
329 
330  // update_third_person_camera();
331 }
332 
333 void nest_view_state::set_third_person_camera_rotation(double yaw, double pitch)
334 {
335  third_person_camera_yaw = yaw;
336  third_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, pitch));
337 
338  third_person_camera_yaw_rotation = math::angle_axis(third_person_camera_yaw, {0.0, 1.0, 0.0});
339  third_person_camera_pitch_rotation = math::angle_axis(third_person_camera_pitch, {-1.0, 0.0, 0.0});
340  third_person_camera_orientation = math::normalize(third_person_camera_yaw_rotation * third_person_camera_pitch_rotation);
341 }
342 
343 void nest_view_state::zoom_third_person_camera(double zoom)
344 {
345  set_third_person_camera_zoom(third_person_camera_zoom + zoom);
346 }
347 
348 void nest_view_state::translate_third_person_camera(const math::dvec3& direction, double magnitude)
349 {
350  // Scale translation magnitude by factor of focal plane height
351  magnitude *= third_person_camera_focal_plane_height * third_person_camera_speed;
352 
353  // Rotate translation direction according to camera yaw
354  const math::dvec3 rotated_direction = third_person_camera_yaw_rotation * direction;
355 
356  third_person_camera_focal_point += rotated_direction * magnitude;
357 
358  // update_third_person_camera();
359 }
360 
361 void nest_view_state::rotate_third_person_camera(const input::mouse_moved_event& event)
362 {
363  const double yaw = third_person_camera_yaw - ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
364  const double pitch = third_person_camera_pitch + ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
365 
366  set_third_person_camera_rotation(yaw, pitch);
367 }
368 
369 void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event)
370 {
371  ctx.underground_material_pass->set_mouse_position(math::fvec2(event.position));
372 
373  if (!mouse_look && !mouse_grip && !mouse_zoom)
374  {
375  return;
376  }
377 
378  if (mouse_grip)
379  {
380  const math::dvec2 viewport_size = math::dvec2(ctx.window->get_viewport_size());
381 
382  math::dvec3 translation
383  {
384  third_person_camera_focal_plane_width * (static_cast<double>(-event.difference.x()) / (viewport_size.x() - 1.0)),
385  0.0,
386  third_person_camera_focal_plane_height * (static_cast<double>(-event.difference.y()) / (viewport_size.y() - 1.0)),
387  };
388 
389  if (third_person_camera_pitch < 0.0)
390  {
391  translation.z() *= -1.0;
392  }
393 
394  third_person_camera_focal_point += third_person_camera_yaw_rotation * translation;
395  }
396 
397  if (mouse_look)
398  {
399  rotate_third_person_camera(event);
400  }
401 
402  if (mouse_zoom)
403  {
404  const double zoom_speed = -1.0 / static_cast<double>(ctx.window->get_viewport_size().y());
405  zoom_third_person_camera(static_cast<double>(event.difference.y()) * zoom_speed);
406  }
407 
408  update_third_person_camera();
409 }
410 
411 void nest_view_state::update_third_person_camera()
412 {
413 
414 }
415 
416 geom::ray<float, 3> nest_view_state::get_mouse_ray(const math::vec2<std::int32_t>& mouse_position) const
417 {
418  // Get window viewport size
419  const auto& viewport_size = ctx.window->get_viewport_size();
420 
421  // Transform mouse coordinates from window space to NDC space
422  const math::fvec2 mouse_ndc =
423  {
424  static_cast<float>(mouse_position.x()) / static_cast<float>(viewport_size.x() - 1) * 2.0f - 1.0f,
425  (1.0f - static_cast<float>(mouse_position.y()) / static_cast<float>(viewport_size.y() - 1)) * 2.0f - 1.0f
426  };
427 
428  const auto& scene_component = ctx.entity_registry->get<::scene_component>(third_person_camera_rig_eid);
429  const auto& camera = static_cast<const scene::camera&>(*scene_component.object);
430 
431  return camera.pick(mouse_ndc);
432 }
433 
434 void nest_view_state::setup_controls()
435 {
436  /*
437  // Enable/toggle mouse look
438  action_subscriptions.emplace_back
439  (
440  ctx.mouse_look_action.get_activated_channel().subscribe
441  (
442  [&](const auto& event)
443  {
444  mouse_look = ctx.toggle_mouse_look ? !mouse_look : true;
445 
446  //ctx.input_manager->set_cursor_visible(!mouse_look);
447  ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
448  }
449  )
450  );
451 
452  // Disable mouse look
453  action_subscriptions.emplace_back
454  (
455  ctx.mouse_look_action.get_deactivated_channel().subscribe
456  (
457  [&](const auto& event)
458  {
459  if (!ctx.toggle_mouse_look && mouse_look)
460  {
461  mouse_look = false;
462  //ctx.input_manager->set_cursor_visible(true);
463  ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
464  }
465  }
466  )
467  );
468 
469  // Enable/toggle mouse grip
470  action_subscriptions.emplace_back
471  (
472  ctx.mouse_grip_action.get_activated_channel().subscribe
473  (
474  [&](const auto& event)
475  {
476  mouse_grip = ctx.toggle_mouse_grip ? !mouse_grip : true;
477 
478  if (mouse_grip)
479  {
480  const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
481 
482  // Cast ray to plane
483  const auto mouse_ray = get_mouse_ray(mouse_position);
484  const auto intersection = geom::intersection(mouse_ray, mouse_grip_plane);
485  if (intersection)
486  {
487  mouse_grip_point = mouse_ray.origin + mouse_ray.direction * (*intersection);
488  }
489  }
490 
491  ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
492 
493  // BVH picking test
494  const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
495  const auto mouse_ray = get_mouse_ray(mouse_position);
496 
497  debug::log_info("pick:");
498  float nearest_hit = std::numeric_limits<float>::infinity();
499  bool hit = false;
500  std::uint32_t hit_index;
501  const auto& vertex_positions = navmesh->vertices().attributes().at<math::fvec3>("position");
502  std::size_t test_count = 0;
503 
504 
505  int box_test_passed = 0;
506  navmesh_bvh->visit
507  (
508  mouse_ray,
509  [&](std::uint32_t index)
510  {
511  ++box_test_passed;
512 
513  geom::brep_face* face = navmesh->faces()[index];
514  auto loop = face->loops().begin();
515  const auto& a = vertex_positions[loop->vertex()->index()];
516  const auto& b = vertex_positions[(++loop)->vertex()->index()];
517  const auto& c = vertex_positions[(++loop)->vertex()->index()];
518 
519  if (auto intersection = geom::intersection(mouse_ray, a, b, c))
520  {
521  ++test_count;
522  float t = std::get<0>(*intersection);
523  if (t < nearest_hit)
524  {
525  hit = true;
526  nearest_hit = t;
527  hit_index = index;
528  }
529  }
530 
531 
532  }
533  );
534 
535  debug::log_info("box tests passed: {}", box_test_passed);
536 
537  if (hit)
538  {
539  const auto& navmesh_face_normals = navmesh->faces().attributes().at<math::fvec3>("normal");
540 
541  navmesh_agent_face = navmesh->faces()[hit_index];
542  navmesh_agent_position = mouse_ray.extrapolate(nearest_hit);
543  navmesh_agent_normal = navmesh_face_normals[hit_index];
544 
545 
546  const auto& hit_normal = navmesh_face_normals[hit_index];
547 
548  const float standing_height = worker_phenome.legs->standing_height * worker_phenome.body_size->mean_mesosoma_length;
549  const math::fvec3 translation = navmesh_agent_position + hit_normal * standing_height;
550 
551  const math::fquat rotation = math::rotation(math::fvec3{0, 1, 0}, hit_normal);
552 
553  ctx.entity_registry->patch<scene_component>
554  (
555  worker_eid,
556  [&](auto& component)
557  {
558  component.object->set_translation(translation);
559  component.object->set_rotation(rotation);
560  }
561  );
562 
563  debug::log_info("hit! test count: {}", test_count);
564  }
565  else
566  {
567  debug::log_info("no hit");
568  }
569  }
570  )
571  );
572 
573  // Disable mouse grip
574  action_subscriptions.emplace_back
575  (
576  ctx.mouse_grip_action.get_deactivated_channel().subscribe
577  (
578  [&](const auto& event)
579  {
580  mouse_grip = false;
581  ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
582  }
583  )
584  );
585  */
586 
587  // Mouse look
588  mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
589  (
590  std::bind_front(&nest_view_state::handle_mouse_motion, this)
591  );
592 
593 
594  // Move back
595  action_subscriptions.emplace_back
596  (
598  (
599  [&](const auto& event)
600  {
601  translate_third_person_camera({0.0, 0.0, 1.0}, event.input_value / ctx.fixed_update_rate);
602  update_third_person_camera();
603  }
604  )
605  );
606 
607  // Move left
608  action_subscriptions.emplace_back
609  (
611  (
612  [&](const auto& event)
613  {
614  // translate_third_person_camera({-1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
615  // update_third_person_camera();
616 
618  (
619  worker_eid,
620  [&](auto& component)
621  {
622  auto rotation = math::angle_axis(math::radians(30.0f) * event.input_value / ctx.fixed_update_rate, navmesh_agent_normal);
623  component.object->set_rotation(math::normalize(rotation * component.object->get_rotation()));
624  }
625  );
626  }
627  )
628  );
629 
630  // Move right
631  action_subscriptions.emplace_back
632  (
634  (
635  [&](const auto& event)
636  {
637  // translate_third_person_camera({1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
638  // update_third_person_camera();
639 
641  (
642  worker_eid,
643  [&](auto& component)
644  {
645  auto rotation = math::angle_axis(math::radians(-30.0f) * event.input_value / ctx.fixed_update_rate, navmesh_agent_normal);
646  component.object->set_rotation(math::normalize(rotation * component.object->get_rotation()));
647  }
648  );
649  }
650  )
651  );
652 
653  // Zoom in
654  action_subscriptions.emplace_back
655  (
657  (
658  [&](const auto& event)
659  {
660  zoom_third_person_camera(1.0 / static_cast<double>(third_person_camera_zoom_step_count));
661  update_third_person_camera();
662  }
663  )
664  );
665 
666  // Zoom out
667  action_subscriptions.emplace_back
668  (
670  (
671  [&](const auto& event)
672  {
673  zoom_third_person_camera(-1.0 / static_cast<double>(third_person_camera_zoom_step_count));
674  update_third_person_camera();
675  }
676  )
677  );
678 }
@ 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.
std::unique_ptr< render::model > ant_morphogenesis(const ant_phenome &phenome)
Generates a 3D model of an ant given its phenome.
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::rectangle_light > underground_rectangle_light
Definition: game.hpp:363
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::shared_ptr< scene::camera > underground_camera
Definition: game.hpp:361
std::unique_ptr< screen_transition > fade_transition
Definition: game.hpp:371
std::shared_ptr< ecoregion > active_ecoregion
Definition: game.hpp:426
std::unique_ptr< render::material_pass > underground_material_pass
Definition: game.hpp:325
input::action move_left_action
Definition: game.hpp:218
std::mt19937 rng
Definition: game.hpp:389
std::unique_ptr< resource_manager > resource_manager
Definition: game.hpp:152
std::shared_ptr< app::window > window
Definition: game.hpp:166
std::queue< std::function< void()> > function_queue
Definition: game.hpp:303
float fixed_update_rate
Definition: game.hpp:420
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< scene::collection > underground_scene
Definition: game.hpp:360
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
Boundary representation (B-rep) of a mesh.
Definition: brep-mesh.hpp:34
Cube texture.
Definition: texture.hpp:243
::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_activated_event > & get_activated_channel() noexcept
Returns the channel through which action activated events are published.
Definition: action.hpp:91
nest_view_state(::game &ctx)
virtual ~nest_view_state()
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
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
Definition: log.hpp:88
log_message< log_message_severity::info, Args... > log_info
Formats and logs an info message.
Definition: log.hpp:116
Publish-subscribe messaging.
Definition: channel.hpp:32
void generate_face_normals(brep_mesh &mesh)
Generates the math::fvec3 face attribute "normal" for a B-rep mesh.
void generate_vertex_normals(brep_mesh &mesh)
Generates the math::fvec3 vertex attribute "normal" for a B-rep mesh.
dvec< 2 > dvec2
n-dimensional vector of double-precision floating-point numbers.
Definition: vector.hpp:437
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
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
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
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
float mean_mesosoma_length
Mean mesosoma length (Weber's length), in centimeters.
std::shared_ptr< render::model > model
3D model of the larva.
Complete set of ant phenes.
Definition: ant-phenome.hpp:52
const ant_body_size_phene * body_size
Definition: ant-phenome.hpp:65
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
static T out_sine(const T &x, const T &y, S a)
Definition: ease.hpp:123
Half of a line proceeding from an initial point.
Definition: ray.hpp:38
Event generated when a mouse has been moved.
static quaternion rotate_x(scalar_type angle)
Returns a quaternion representing a rotation about the x-axis.
Definition: quaternion.hpp:110
vector_type scale
Scale vector.
Definition: transform.hpp:56
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
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
std::uint8_t layer_mask
std::shared_ptr< scene::object_base > object
math::transform< float > world
math::transform< float > local