💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

678 lines
23 KiB

  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. #include "game/states/nest-view-state.hpp"
  20. #include "game/ant/ant-cladogenesis.hpp"
  21. #include "game/ant/ant-genome.hpp"
  22. #include "game/ant/ant-morphogenesis.hpp"
  23. #include "game/ant/ant-phenome.hpp"
  24. #include "game/commands/commands.hpp"
  25. #include "game/components/constraint-stack-component.hpp"
  26. #include "game/components/scene-component.hpp"
  27. #include "game/components/picking-component.hpp"
  28. #include "game/components/rigid-body-component.hpp"
  29. #include "game/components/rigid-body-constraint-component.hpp"
  30. #include "game/components/steering-component.hpp"
  31. #include "game/components/terrain-component.hpp"
  32. #include "game/components/legged-locomotion-component.hpp"
  33. #include "game/components/winged-locomotion-component.hpp"
  34. #include "game/components/ik-component.hpp"
  35. #include "game/components/transform-component.hpp"
  36. #include "game/constraints/child-of-constraint.hpp"
  37. #include "game/constraints/copy-rotation-constraint.hpp"
  38. #include "game/constraints/copy-scale-constraint.hpp"
  39. #include "game/constraints/copy-transform-constraint.hpp"
  40. #include "game/constraints/copy-translation-constraint.hpp"
  41. #include "game/constraints/ease-to-constraint.hpp"
  42. #include "game/constraints/pivot-constraint.hpp"
  43. #include "game/constraints/spring-rotation-constraint.hpp"
  44. #include "game/constraints/spring-to-constraint.hpp"
  45. #include "game/constraints/spring-translation-constraint.hpp"
  46. #include "game/constraints/three-dof-constraint.hpp"
  47. #include "game/constraints/track-to-constraint.hpp"
  48. #include "game/controls.hpp"
  49. #include "game/spawn.hpp"
  50. #include "game/states/pause-menu-state.hpp"
  51. #include "game/systems/astronomy-system.hpp"
  52. #include "game/systems/atmosphere-system.hpp"
  53. #include "game/systems/camera-system.hpp"
  54. #include "game/systems/collision-system.hpp"
  55. #include "game/world.hpp"
  56. #include <engine/animation/ease.hpp>
  57. #include <engine/animation/screen-transition.hpp>
  58. #include <engine/config.hpp>
  59. #include <engine/entity/archetype.hpp>
  60. #include <engine/input/mouse.hpp>
  61. #include <engine/math/interpolation.hpp>
  62. #include <engine/math/projection.hpp>
  63. #include <engine/physics/light/exposure.hpp>
  64. #include <engine/physics/kinematics/constraints/spring-constraint.hpp>
  65. #include <engine/physics/kinematics/colliders/sphere-collider.hpp>
  66. #include <engine/physics/kinematics/colliders/plane-collider.hpp>
  67. #include <engine/physics/kinematics/colliders/box-collider.hpp>
  68. #include <engine/physics/kinematics/colliders/capsule-collider.hpp>
  69. #include <engine/render/passes/material-pass.hpp>
  70. #include <engine/resources/resource-manager.hpp>
  71. #include <engine/utility/state-machine.hpp>
  72. #include <engine/scene/static-mesh.hpp>
  73. #include <engine/scene/skeletal-mesh.hpp>
  74. #include <engine/scene/rectangle-light.hpp>
  75. #include <engine/scene/point-light.hpp>
  76. #include <engine/geom/intersection.hpp>
  77. #include <engine/animation/ease.hpp>
  78. #include <engine/color/color.hpp>
  79. #include <engine/geom/brep/brep-operations.hpp>
  80. #include <engine/geom/coordinates.hpp>
  81. #include <engine/ai/navmesh.hpp>
  82. nest_view_state::nest_view_state(::game& ctx):
  83. game_state(ctx)
  84. {
  85. debug::log_trace("Entering nest view state...");
  86. // Create world if not yet created
  87. if (ctx.entities.find("earth") == ctx.entities.end())
  88. {
  89. // Create cosmos
  90. ::world::cosmogenesis(ctx);
  91. // Create observer
  92. ::world::create_observer(ctx);
  93. }
  94. ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
  95. ::world::enter_ecoregion(ctx, *ctx.active_ecoregion);
  96. debug::log_trace("Generating genome...");
  97. std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
  98. debug::log_trace("Generated genome");
  99. debug::log_trace("Building worker phenome...");
  100. worker_phenome = ant_phenome(*genome, ant_caste_type::worker);
  101. debug::log_trace("Built worker phenome...");
  102. debug::log_trace("Generating worker model...");
  103. std::shared_ptr<render::model> worker_model = ant_morphogenesis(worker_phenome);
  104. debug::log_trace("Generated worker model");
  105. // Create directional light
  106. // ctx.underground_directional_light = std::make_unique<scene::directional_light>();
  107. // ctx.underground_directional_light->set_color({1.0f, 1.0f, 1.0f});
  108. // ctx.underground_directional_light->set_illuminance(2.0f);
  109. // ctx.underground_directional_light->set_direction(math::normalize(math::fvec3{0, -1, 0}));
  110. // ctx.underground_directional_light->set_shadow_caster(true);
  111. // ctx.underground_directional_light->set_shadow_framebuffer(ctx.shadow_map_framebuffer);
  112. // ctx.underground_directional_light->set_shadow_bias(0.005f);
  113. // ctx.underground_directional_light->set_shadow_cascade_count(4);
  114. // ctx.underground_directional_light->set_shadow_cascade_coverage(0.15f);
  115. // ctx.underground_directional_light->set_shadow_cascade_distribution(0.8f);
  116. // ctx.underground_scene->add_object(*ctx.underground_directional_light);
  117. light_probe = std::make_shared<scene::light_probe>();
  118. light_probe->set_luminance_texture(ctx.resource_manager->load<gl::texture_cube>("grey-furnace.tex"));
  119. ctx.underground_scene->add_object(*light_probe);
  120. const math::fvec3 light_color{1.0f, 1.0f, 1.0f};
  121. // Create rectangle light
  122. ctx.underground_rectangle_light = std::make_unique<scene::rectangle_light>();
  123. ctx.underground_rectangle_light->set_color(light_color);
  124. ctx.underground_rectangle_light->set_luminous_flux(1500.0f);
  125. ctx.underground_rectangle_light->set_translation({0.0f, 10.0f, 0.0f});
  126. ctx.underground_rectangle_light->set_rotation(math::fquat::rotate_x(math::radians(90.0f)));
  127. ctx.underground_rectangle_light->set_scale(7.0f);
  128. ctx.underground_scene->add_object(*ctx.underground_rectangle_light);
  129. // Create light rectangle
  130. auto light_rectangle_model = ctx.resource_manager->load<render::model>("light-rectangle.mdl");
  131. auto light_rectangle_material = std::make_shared<render::material>(*light_rectangle_model->get_groups().front().material);
  132. light_rectangle_emissive = std::static_pointer_cast<render::matvar_fvec3>(light_rectangle_material->get_variable("emissive"));
  133. light_rectangle_emissive->set(ctx.underground_rectangle_light->get_colored_luminance());
  134. auto light_rectangle_static_mesh = std::make_shared<scene::static_mesh>(light_rectangle_model);
  135. light_rectangle_static_mesh->set_material(0, light_rectangle_material);
  136. auto light_rectangle_eid = ctx.entity_registry->create();
  137. ctx.entity_registry->emplace<scene_component>(light_rectangle_eid, std::move(light_rectangle_static_mesh), std::uint8_t{2});
  138. ctx.entity_registry->patch<scene_component>
  139. (
  140. light_rectangle_eid,
  141. [&](auto& component)
  142. {
  143. component.object->set_transform(ctx.underground_rectangle_light->get_transform());
  144. }
  145. );
  146. // Create treadmill
  147. auto treadmill_eid = ctx.entity_registry->create();
  148. scene_component treadmill_scene_component;
  149. treadmill_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("treadmill-5cm.mdl"));
  150. treadmill_scene_component.layer_mask = 2;
  151. ctx.entity_registry->emplace<scene_component>(treadmill_eid, std::move(treadmill_scene_component));
  152. // Create worker
  153. auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
  154. worker_eid = ctx.entity_registry->create();
  155. transform_component worker_transform_component;
  156. worker_transform_component.local = math::transform<float>::identity();
  157. worker_transform_component.local.translation = {0, 0.1f, 0};
  158. worker_transform_component.local.scale = math::fvec3::one() * worker_phenome.body_size->mean_mesosoma_length;
  159. worker_transform_component.world = worker_transform_component.local;
  160. ctx.entity_registry->emplace<transform_component>(worker_eid, worker_transform_component);
  161. ctx.entity_registry->emplace<scene_component>(worker_eid, std::move(worker_skeletal_mesh), std::uint8_t{2});
  162. // Create cocoon
  163. auto cocoon_eid = ctx.entity_registry->create();
  164. auto cocoon_static_mesh = std::make_shared<scene::static_mesh>(worker_phenome.pupa->cocoon_model);
  165. cocoon_static_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length);
  166. ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::move(cocoon_static_mesh), std::uint8_t{2});
  167. ctx.entity_registry->patch<scene_component>
  168. (
  169. cocoon_eid,
  170. [&](auto& component)
  171. {
  172. component.object->set_translation({-4.0f, 0.0f, 4.0f});
  173. }
  174. );
  175. // Create color checker
  176. auto color_checker_eid = ctx.entity_registry->create();
  177. scene_component color_checker_scene_component;
  178. color_checker_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("color-checker.mdl"));
  179. color_checker_scene_component.object->set_translation({0, 0, 4});
  180. color_checker_scene_component.layer_mask = 2;
  181. ctx.entity_registry->emplace<scene_component>(color_checker_eid, std::move(color_checker_scene_component));
  182. // Create larva
  183. larva_eid = ctx.entity_registry->create();
  184. auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
  185. larva_skeletal_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length);
  186. ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{2});
  187. ctx.entity_registry->patch<scene_component>
  188. (
  189. larva_eid,
  190. [&](auto& component)
  191. {
  192. component.object->set_translation({4.0f, 0.0f, 4.0f});
  193. }
  194. );
  195. // Create sphere
  196. // auto sphere_eid = ctx.entity_registry->create();
  197. // auto sphere_static_mesh = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("sphere.mdl"));
  198. // ctx.entity_registry->emplace<scene_component>(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{2});
  199. // ctx.entity_registry->patch<scene_component>
  200. // (
  201. // sphere_eid,
  202. // [&](auto& component)
  203. // {
  204. // component.object->set_translation({0.0f, 0.0f, 0.0f});
  205. // }
  206. // );
  207. // Set world time
  208. ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
  209. // Init time scale
  210. double time_scale = 60.0;
  211. // Set time scale
  212. ::world::set_time_scale(ctx, time_scale);
  213. // Setup camera
  214. ctx.underground_camera->set_exposure_value(0.0f);
  215. const auto& viewport_size = ctx.window->get_viewport_size();
  216. const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
  217. // Create third person camera rig
  218. create_third_person_camera_rig();
  219. // Setup controls
  220. setup_controls();
  221. // Queue enable game controls
  222. ctx.function_queue.push
  223. (
  224. [&ctx]()
  225. {
  226. ::enable_game_controls(ctx);
  227. }
  228. );
  229. // Queue fade in
  230. ctx.fade_transition_color->set({0, 0, 0});
  231. ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
  232. // Refresh frame scheduler
  233. ctx.frame_scheduler.refresh();
  234. // Load navmesh
  235. navmesh = ctx.resource_manager->load<geom::brep_mesh>("treadmill-5cm.msh");
  236. // Generate navmesh attributes
  237. geom::generate_face_normals(*navmesh);
  238. geom::generate_vertex_normals(*navmesh);
  239. // Build navmesh BVH
  240. debug::log_info("building bvh");
  241. navmesh_bvh = std::make_unique<geom::bvh>(*navmesh);
  242. debug::log_info("building bvh done");
  243. debug::log_trace("Entered nest view state");
  244. }
  245. nest_view_state::~nest_view_state()
  246. {
  247. debug::log_trace("Exiting nest view state...");
  248. // Disable game controls
  249. ::disable_game_controls(ctx);
  250. destroy_third_person_camera_rig();
  251. debug::log_trace("Exited nest view state");
  252. }
  253. void nest_view_state::create_third_person_camera_rig()
  254. {
  255. // Construct third person camera rig scene component
  256. scene_component third_person_camera_rig_camera;
  257. third_person_camera_rig_camera.object = ctx.underground_camera;
  258. third_person_camera_rig_camera.layer_mask = 2;
  259. // Construct third person camera rig entity
  260. third_person_camera_rig_eid = ctx.entity_registry->create();
  261. ctx.entity_registry->emplace<scene_component>(third_person_camera_rig_eid, third_person_camera_rig_camera);
  262. set_third_person_camera_zoom(third_person_camera_zoom);
  263. set_third_person_camera_rotation(third_person_camera_yaw, third_person_camera_pitch);
  264. update_third_person_camera();
  265. }
  266. void nest_view_state::destroy_third_person_camera_rig()
  267. {
  268. ctx.entity_registry->destroy(third_person_camera_rig_eid);
  269. }
  270. void nest_view_state::set_third_person_camera_zoom(double zoom)
  271. {
  272. // Clamp zoom
  273. third_person_camera_zoom = std::min<double>(std::max<double>(zoom, 0.0), 1.0);
  274. // Update FoV
  275. third_person_camera_hfov = ease<double, double>::out_sine(third_person_camera_far_hfov, third_person_camera_near_hfov, third_person_camera_zoom);
  276. third_person_camera_vfov = math::vertical_fov(third_person_camera_hfov, static_cast<double>(ctx.underground_camera->get_aspect_ratio()));
  277. // Update focal plane size
  278. 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);
  279. third_person_camera_focal_plane_width = third_person_camera_focal_plane_height * ctx.underground_camera->get_aspect_ratio();
  280. // Update focal distance
  281. third_person_camera_focal_distance = third_person_camera_focal_plane_height * 0.5 / std::tan(third_person_camera_vfov * 0.5);
  282. // update_third_person_camera();
  283. }
  284. void nest_view_state::set_third_person_camera_rotation(double yaw, double pitch)
  285. {
  286. third_person_camera_yaw = yaw;
  287. third_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, pitch));
  288. third_person_camera_yaw_rotation = math::angle_axis(third_person_camera_yaw, {0.0, 1.0, 0.0});
  289. third_person_camera_pitch_rotation = math::angle_axis(third_person_camera_pitch, {-1.0, 0.0, 0.0});
  290. third_person_camera_orientation = math::normalize(third_person_camera_yaw_rotation * third_person_camera_pitch_rotation);
  291. }
  292. void nest_view_state::zoom_third_person_camera(double zoom)
  293. {
  294. set_third_person_camera_zoom(third_person_camera_zoom + zoom);
  295. }
  296. void nest_view_state::translate_third_person_camera(const math::dvec3& direction, double magnitude)
  297. {
  298. // Scale translation magnitude by factor of focal plane height
  299. magnitude *= third_person_camera_focal_plane_height * third_person_camera_speed;
  300. // Rotate translation direction according to camera yaw
  301. const math::dvec3 rotated_direction = third_person_camera_yaw_rotation * direction;
  302. third_person_camera_focal_point += rotated_direction * magnitude;
  303. // update_third_person_camera();
  304. }
  305. void nest_view_state::rotate_third_person_camera(const input::mouse_moved_event& event)
  306. {
  307. const double yaw = third_person_camera_yaw - ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
  308. const double pitch = third_person_camera_pitch + ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
  309. set_third_person_camera_rotation(yaw, pitch);
  310. }
  311. void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event)
  312. {
  313. ctx.underground_material_pass->set_mouse_position(math::fvec2(event.position));
  314. if (!mouse_look && !mouse_grip && !mouse_zoom)
  315. {
  316. return;
  317. }
  318. if (mouse_grip)
  319. {
  320. const math::dvec2 viewport_size = math::dvec2(ctx.window->get_viewport_size());
  321. math::dvec3 translation
  322. {
  323. third_person_camera_focal_plane_width * (static_cast<double>(-event.difference.x()) / (viewport_size.x() - 1.0)),
  324. 0.0,
  325. third_person_camera_focal_plane_height * (static_cast<double>(-event.difference.y()) / (viewport_size.y() - 1.0)),
  326. };
  327. if (third_person_camera_pitch < 0.0)
  328. {
  329. translation.z() *= -1.0;
  330. }
  331. third_person_camera_focal_point += third_person_camera_yaw_rotation * translation;
  332. }
  333. if (mouse_look)
  334. {
  335. rotate_third_person_camera(event);
  336. }
  337. if (mouse_zoom)
  338. {
  339. const double zoom_speed = -1.0 / static_cast<double>(ctx.window->get_viewport_size().y());
  340. zoom_third_person_camera(static_cast<double>(event.difference.y()) * zoom_speed);
  341. }
  342. update_third_person_camera();
  343. }
  344. void nest_view_state::update_third_person_camera()
  345. {
  346. }
  347. geom::ray<float, 3> nest_view_state::get_mouse_ray(const math::vec2<std::int32_t>& mouse_position) const
  348. {
  349. // Get window viewport size
  350. const auto& viewport_size = ctx.window->get_viewport_size();
  351. // Transform mouse coordinates from window space to NDC space
  352. const math::fvec2 mouse_ndc =
  353. {
  354. static_cast<float>(mouse_position.x()) / static_cast<float>(viewport_size.x() - 1) * 2.0f - 1.0f,
  355. (1.0f - static_cast<float>(mouse_position.y()) / static_cast<float>(viewport_size.y() - 1)) * 2.0f - 1.0f
  356. };
  357. const auto& scene_component = ctx.entity_registry->get<::scene_component>(third_person_camera_rig_eid);
  358. const auto& camera = static_cast<const scene::camera&>(*scene_component.object);
  359. return camera.pick(mouse_ndc);
  360. }
  361. void nest_view_state::setup_controls()
  362. {
  363. /*
  364. // Enable/toggle mouse look
  365. action_subscriptions.emplace_back
  366. (
  367. ctx.mouse_look_action.get_activated_channel().subscribe
  368. (
  369. [&](const auto& event)
  370. {
  371. mouse_look = ctx.toggle_mouse_look ? !mouse_look : true;
  372. //ctx.input_manager->set_cursor_visible(!mouse_look);
  373. ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
  374. }
  375. )
  376. );
  377. // Disable mouse look
  378. action_subscriptions.emplace_back
  379. (
  380. ctx.mouse_look_action.get_deactivated_channel().subscribe
  381. (
  382. [&](const auto& event)
  383. {
  384. if (!ctx.toggle_mouse_look && mouse_look)
  385. {
  386. mouse_look = false;
  387. //ctx.input_manager->set_cursor_visible(true);
  388. ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
  389. }
  390. }
  391. )
  392. );
  393. // Enable/toggle mouse grip
  394. action_subscriptions.emplace_back
  395. (
  396. ctx.mouse_grip_action.get_activated_channel().subscribe
  397. (
  398. [&](const auto& event)
  399. {
  400. mouse_grip = ctx.toggle_mouse_grip ? !mouse_grip : true;
  401. if (mouse_grip)
  402. {
  403. const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
  404. // Cast ray to plane
  405. const auto mouse_ray = get_mouse_ray(mouse_position);
  406. const auto intersection = geom::intersection(mouse_ray, mouse_grip_plane);
  407. if (intersection)
  408. {
  409. mouse_grip_point = mouse_ray.origin + mouse_ray.direction * (*intersection);
  410. }
  411. }
  412. ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
  413. // BVH picking test
  414. const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
  415. const auto mouse_ray = get_mouse_ray(mouse_position);
  416. debug::log_info("pick:");
  417. float nearest_hit = std::numeric_limits<float>::infinity();
  418. bool hit = false;
  419. std::uint32_t hit_index;
  420. const auto& vertex_positions = navmesh->vertices().attributes().at<math::fvec3>("position");
  421. std::size_t test_count = 0;
  422. int box_test_passed = 0;
  423. navmesh_bvh->visit
  424. (
  425. mouse_ray,
  426. [&](std::uint32_t index)
  427. {
  428. ++box_test_passed;
  429. geom::brep_face* face = navmesh->faces()[index];
  430. auto loop = face->loops().begin();
  431. const auto& a = vertex_positions[loop->vertex()->index()];
  432. const auto& b = vertex_positions[(++loop)->vertex()->index()];
  433. const auto& c = vertex_positions[(++loop)->vertex()->index()];
  434. if (auto intersection = geom::intersection(mouse_ray, a, b, c))
  435. {
  436. ++test_count;
  437. float t = std::get<0>(*intersection);
  438. if (t < nearest_hit)
  439. {
  440. hit = true;
  441. nearest_hit = t;
  442. hit_index = index;
  443. }
  444. }
  445. }
  446. );
  447. debug::log_info("box tests passed: {}", box_test_passed);
  448. if (hit)
  449. {
  450. const auto& navmesh_face_normals = navmesh->faces().attributes().at<math::fvec3>("normal");
  451. navmesh_agent_face = navmesh->faces()[hit_index];
  452. navmesh_agent_position = mouse_ray.extrapolate(nearest_hit);
  453. navmesh_agent_normal = navmesh_face_normals[hit_index];
  454. const auto& hit_normal = navmesh_face_normals[hit_index];
  455. const float standing_height = worker_phenome.legs->standing_height * worker_phenome.body_size->mean_mesosoma_length;
  456. const math::fvec3 translation = navmesh_agent_position + hit_normal * standing_height;
  457. const math::fquat rotation = math::rotation(math::fvec3{0, 1, 0}, hit_normal);
  458. ctx.entity_registry->patch<scene_component>
  459. (
  460. worker_eid,
  461. [&](auto& component)
  462. {
  463. component.object->set_translation(translation);
  464. component.object->set_rotation(rotation);
  465. }
  466. );
  467. debug::log_info("hit! test count: {}", test_count);
  468. }
  469. else
  470. {
  471. debug::log_info("no hit");
  472. }
  473. }
  474. )
  475. );
  476. // Disable mouse grip
  477. action_subscriptions.emplace_back
  478. (
  479. ctx.mouse_grip_action.get_deactivated_channel().subscribe
  480. (
  481. [&](const auto& event)
  482. {
  483. mouse_grip = false;
  484. ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
  485. }
  486. )
  487. );
  488. */
  489. // Mouse look
  490. mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
  491. (
  492. std::bind_front(&nest_view_state::handle_mouse_motion, this)
  493. );
  494. // Move back
  495. action_subscriptions.emplace_back
  496. (
  497. ctx.move_back_action.get_active_channel().subscribe
  498. (
  499. [&](const auto& event)
  500. {
  501. translate_third_person_camera({0.0, 0.0, 1.0}, event.input_value / ctx.fixed_update_rate);
  502. update_third_person_camera();
  503. }
  504. )
  505. );
  506. // Move left
  507. action_subscriptions.emplace_back
  508. (
  509. ctx.move_left_action.get_active_channel().subscribe
  510. (
  511. [&](const auto& event)
  512. {
  513. // translate_third_person_camera({-1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
  514. // update_third_person_camera();
  515. ctx.entity_registry->patch<::scene_component>
  516. (
  517. worker_eid,
  518. [&](auto& component)
  519. {
  520. auto rotation = math::angle_axis(math::radians(30.0f) * event.input_value / ctx.fixed_update_rate, navmesh_agent_normal);
  521. component.object->set_rotation(math::normalize(rotation * component.object->get_rotation()));
  522. }
  523. );
  524. }
  525. )
  526. );
  527. // Move right
  528. action_subscriptions.emplace_back
  529. (
  530. ctx.move_right_action.get_active_channel().subscribe
  531. (
  532. [&](const auto& event)
  533. {
  534. // translate_third_person_camera({1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
  535. // update_third_person_camera();
  536. ctx.entity_registry->patch<::scene_component>
  537. (
  538. worker_eid,
  539. [&](auto& component)
  540. {
  541. auto rotation = math::angle_axis(math::radians(-30.0f) * event.input_value / ctx.fixed_update_rate, navmesh_agent_normal);
  542. component.object->set_rotation(math::normalize(rotation * component.object->get_rotation()));
  543. }
  544. );
  545. }
  546. )
  547. );
  548. // Zoom in
  549. action_subscriptions.emplace_back
  550. (
  551. ctx.move_up_action.get_activated_channel().subscribe
  552. (
  553. [&](const auto& event)
  554. {
  555. zoom_third_person_camera(1.0 / static_cast<double>(third_person_camera_zoom_step_count));
  556. update_third_person_camera();
  557. }
  558. )
  559. );
  560. // Zoom out
  561. action_subscriptions.emplace_back
  562. (
  563. ctx.move_down_action.get_activated_channel().subscribe
  564. (
  565. [&](const auto& event)
  566. {
  567. zoom_third_person_camera(-1.0 / static_cast<double>(third_person_camera_zoom_step_count));
  568. update_third_person_camera();
  569. }
  570. )
  571. );
  572. }