💿🐜 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.

780 lines
28 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/ant/ant-cladogenesis.hpp"
  20. #include "game/ant/ant-genome.hpp"
  21. #include "game/ant/ant-morphogenesis.hpp"
  22. #include "game/ant/ant-phenome.hpp"
  23. #include "game/commands/commands.hpp"
  24. #include "game/components/constraint-stack-component.hpp"
  25. #include "game/components/scene-component.hpp"
  26. #include "game/components/picking-component.hpp"
  27. #include "game/components/rigid-body-component.hpp"
  28. #include "game/components/rigid-body-constraint-component.hpp"
  29. #include "game/components/steering-component.hpp"
  30. #include "game/components/terrain-component.hpp"
  31. #include "game/components/legged-locomotion-component.hpp"
  32. #include "game/components/winged-locomotion-component.hpp"
  33. #include "game/components/ik-component.hpp"
  34. #include "game/components/transform-component.hpp"
  35. #include "game/constraints/child-of-constraint.hpp"
  36. #include "game/constraints/copy-rotation-constraint.hpp"
  37. #include "game/constraints/copy-scale-constraint.hpp"
  38. #include "game/constraints/copy-transform-constraint.hpp"
  39. #include "game/constraints/copy-translation-constraint.hpp"
  40. #include "game/constraints/ease-to-constraint.hpp"
  41. #include "game/constraints/pivot-constraint.hpp"
  42. #include "game/constraints/spring-rotation-constraint.hpp"
  43. #include "game/constraints/spring-to-constraint.hpp"
  44. #include "game/constraints/spring-translation-constraint.hpp"
  45. #include "game/constraints/three-dof-constraint.hpp"
  46. #include "game/constraints/track-to-constraint.hpp"
  47. #include "game/controls.hpp"
  48. #include "game/spawn.hpp"
  49. #include "game/states/nest-selection-state.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/resources/resource-manager.hpp>
  70. #include <engine/utility/state-machine.hpp>
  71. #include <engine/scene/static-mesh.hpp>
  72. #include <engine/scene/skeletal-mesh.hpp>
  73. #include <engine/animation/ik/constraints/swing-twist-ik-constraint.hpp>
  74. #include <engine/animation/ik/constraints/euler-ik-constraint.hpp>
  75. nest_selection_state::nest_selection_state(::game& ctx):
  76. game_state(ctx)
  77. {
  78. debug::log_trace("Entering nest selection state...");
  79. // Create world if not yet created
  80. if (ctx.entities.find("earth") == ctx.entities.end())
  81. {
  82. // Create cosmos
  83. ::world::cosmogenesis(ctx);
  84. // Create observer
  85. ::world::create_observer(ctx);
  86. }
  87. ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
  88. ::world::enter_ecoregion(ctx, *ctx.active_ecoregion);
  89. debug::log_trace("Generating genome...");
  90. std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
  91. debug::log_trace("Generated genome");
  92. debug::log_trace("Building worker phenome...");
  93. ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen);
  94. debug::log_trace("Built worker phenome...");
  95. debug::log_trace("Generating worker model...");
  96. worker_model = ant_morphogenesis(worker_phenome);
  97. debug::log_trace("Generated worker model");
  98. // Create floor plane
  99. auto floor_archetype = ctx.resource_manager->load<entity::archetype>("desert-scrub-plane.ent");
  100. auto floor_eid = floor_archetype->create(*ctx.entity_registry);
  101. ctx.entity_registry->patch<transform_component>
  102. (
  103. floor_eid,
  104. [](auto& component)
  105. {
  106. component.local.rotation = math::angle_axis(math::radians(3.0f), math::fvec3{1.0f, 0.0f, 0.0f});
  107. }
  108. );
  109. auto floor_body = std::make_unique<physics::rigid_body>();
  110. auto floor_collider = std::make_shared<physics::plane_collider>(math::fvec3{0.0f, 1.0f, 0.0f});
  111. floor_collider->set_layer_mask(0b11);
  112. floor_collider->set_material(std::make_shared<physics::collider_material>(1.0f, 0.5f, 1.0f));
  113. floor_body->set_mass(0.0f);
  114. floor_body->set_inertia(0.0f);
  115. floor_body->set_collider(std::move(floor_collider));
  116. ctx.entity_registry->emplace<rigid_body_component>(floor_eid, std::move(floor_body));
  117. // Create worker entity(s)
  118. auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
  119. worker_ant_eid = ctx.entity_registry->create();
  120. transform_component worker_transform_component;
  121. worker_transform_component.local = math::transform<float>::identity();
  122. worker_transform_component.local.translation = {0, 0.5f, -4};
  123. worker_transform_component.world = worker_transform_component.local;
  124. ctx.entity_registry->emplace<transform_component>(worker_ant_eid, worker_transform_component);
  125. ctx.entity_registry->emplace<scene_component>(worker_ant_eid, std::move(worker_skeletal_mesh), std::uint8_t{1});
  126. 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});
  127. //auto worker_collider = std::make_shared<physics::sphere_collider>(1.0f);
  128. worker_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  129. auto worker_body = std::make_unique<physics::rigid_body>();
  130. worker_body->set_position(worker_transform_component.local.translation);
  131. worker_body->set_previous_position(worker_transform_component.local.translation);
  132. worker_body->set_mass(0.1f);
  133. worker_body->set_inertia(0.05f);
  134. worker_body->set_angular_damping(0.5f);
  135. worker_body->set_collider(std::move(worker_collider));
  136. //ctx.entity_registry->emplace<rigid_body_component>(worker_ant_eid, std::move(worker_body));
  137. auto cocoon_eid = ctx.entity_registry->create();
  138. ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::make_shared<scene::static_mesh>(worker_phenome.pupa->cocoon_model), std::uint8_t{1});
  139. larva_eid = ctx.entity_registry->create();
  140. auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
  141. //auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(ctx.resource_manager->load<render::model>("snake.mdl"));
  142. const auto& larva_skeleton = larva_skeletal_mesh->get_model()->get_skeleton();
  143. auto larva_ik_rig = std::make_shared<ik_rig>(*larva_skeletal_mesh);
  144. auto no_twist_constraint = std::make_shared<swing_twist_ik_constraint>();
  145. no_twist_constraint->set_twist_limit(0.0f, 0.0f);
  146. //auto euler_constraint = std::make_shared<euler_ik_constraint>();
  147. //euler_constraint->set_limits({0.0f, -math::radians(90.0f), 0.0f}, {math::radians(90.0f), math::radians(90.0f), 0.0f});
  148. for (std::size_t i = 0; i < larva_skeleton.get_bone_count(); ++i)
  149. {
  150. larva_ik_rig->set_constraint(static_cast<bone_index_type>(i), no_twist_constraint);
  151. }
  152. const auto larva_ik_root_bone_index = *larva_skeleton.get_bone_index("abdomen3");
  153. const auto larva_ik_effector_bone_index = *larva_skeleton.get_bone_index("head");
  154. const auto& larva_head_absolute_transform = larva_skeletal_mesh->get_pose().get_absolute_transform(larva_ik_effector_bone_index);
  155. const auto& larva_head_relative_transform = larva_skeletal_mesh->get_pose().get_relative_transform(larva_ik_effector_bone_index);
  156. larva_ik_solver = std::make_shared<ccd_ik_solver>(*larva_ik_rig, larva_ik_root_bone_index, larva_ik_effector_bone_index);
  157. larva_ik_solver->set_effector_position(larva_head_relative_transform * math::fvec3{0.0f, 0.0f, -0.0f});
  158. larva_ik_solver->set_goal_center(larva_head_absolute_transform.translation + math::fvec3{0.2f, 0.2f, 0.5f});
  159. larva_ik_rig->add_solver(larva_ik_solver);
  160. //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}));
  161. //larva_skeletal_mesh->get_pose().update();
  162. ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{1});
  163. ctx.entity_registry->emplace<ik_component>(larva_eid, std::move(larva_ik_rig));
  164. // Set world time
  165. ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
  166. // Init time scale
  167. double time_scale = 60.0;
  168. // Set time scale
  169. ::world::set_time_scale(ctx, time_scale);
  170. // Setup and enable sky and ground passes
  171. ctx.sky_pass->set_enabled(true);
  172. // Set camera exposure
  173. const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
  174. ctx.surface_camera->set_exposure_value(ev100_sunny16);
  175. const auto& viewport_size = ctx.window->get_viewport_size();
  176. const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
  177. // Init first person camera rig parameters
  178. first_person_camera_rig_translation_spring_angular_frequency = physics::s_to_rads(0.125f);
  179. first_person_camera_rig_rotation_spring_angular_frequency = physics::s_to_rads(0.125f);
  180. first_person_camera_rig_fov_spring_angular_frequency = physics::s_to_rads(0.125f);
  181. first_person_camera_rig_min_elevation = 0.25f;
  182. first_person_camera_rig_max_elevation = 150.0f;
  183. first_person_camera_near_fov = math::vertical_fov(math::radians(100.0f), aspect_ratio);
  184. first_person_camera_far_fov = math::vertical_fov(math::radians(60.0f), aspect_ratio);
  185. first_person_camera_near_speed = 5.0f;
  186. first_person_camera_far_speed = 140.0f;
  187. first_person_camera_rig_pedestal_speed = 2.0f;
  188. first_person_camera_rig_pedestal = 0.0f;
  189. // Create first person camera rig
  190. create_first_person_camera_rig();
  191. // Satisfy first person camera rig constraints
  192. satisfy_first_person_camera_rig_constraints();
  193. // Setup controls
  194. setup_controls();
  195. auto color_checker_archetype = ctx.resource_manager->load<entity::archetype>("color-checker.ent");
  196. color_checker_archetype->create(*ctx.entity_registry);
  197. // auto ruler_archetype = ctx.resource_manager->load<entity::archetype>("ruler-10cm.ent");
  198. // ruler_archetype->create(*ctx.entity_registry);
  199. auto yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-l.ent");
  200. auto yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  201. ::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 0, 70});
  202. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-m.ent");
  203. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  204. ::command::warp_to(*ctx.entity_registry, yucca_eid, {400, 0, 200});
  205. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-s.ent");
  206. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  207. ::command::warp_to(*ctx.entity_registry, yucca_eid, {-300, 0, -300});
  208. auto cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-l.ent");
  209. auto cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  210. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {-100, 0, -200});
  211. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-m.ent");
  212. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  213. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {100, 0, -70});
  214. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-s.ent");
  215. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  216. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {50, 0, 80});
  217. // auto cactus_seed_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-seed.ent");
  218. // auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry);
  219. // ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {0, 1, -5});
  220. // Create spring
  221. /*
  222. auto spring_eid = ctx.entity_registry->create();
  223. auto spring = std::make_unique<physics::spring_constraint>();
  224. spring->attach_a();
  225. spring->attach_b();
  226. spring->set_resting_length(10.0f);
  227. spring->set_stiffness(2.0f);
  228. spring->set_damping(1.0f);
  229. ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
  230. */
  231. sky_probe = std::make_shared<scene::light_probe>();
  232. const std::uint32_t sky_probe_face_size = 128;
  233. const auto sky_probe_mip_levels = static_cast<std::uint32_t>(std::bit_width(sky_probe_face_size));
  234. sky_probe->set_luminance_texture
  235. (
  236. std::make_shared<gl::texture_cube>
  237. (
  238. std::make_shared<gl::image_view_cube>
  239. (
  240. std::make_shared<gl::image_cube>
  241. (
  242. gl::format::r16g16b16_sfloat,
  243. sky_probe_face_size,
  244. sky_probe_mip_levels
  245. ),
  246. gl::format::undefined,
  247. 0,
  248. sky_probe_mip_levels
  249. ),
  250. std::make_shared<gl::sampler>
  251. (
  252. gl::sampler_filter::linear,
  253. gl::sampler_filter::linear,
  254. gl::sampler_mipmap_mode::linear,
  255. gl::sampler_address_mode::clamp_to_edge,
  256. gl::sampler_address_mode::clamp_to_edge
  257. )
  258. )
  259. );
  260. ctx.sky_pass->set_sky_probe(sky_probe);
  261. ctx.surface_scene->add_object(*sky_probe);
  262. // Create sphere
  263. auto sphere_eid = ctx.entity_registry->create();
  264. auto sphere_static_mesh = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("diffuse-spheres.mdl"));
  265. ctx.entity_registry->emplace<scene_component>(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{1});
  266. ctx.entity_registry->patch<scene_component>
  267. (
  268. sphere_eid,
  269. [&](auto& component)
  270. {
  271. component.object->set_translation({0.0f, 10.0f, 0.0f});
  272. }
  273. );
  274. // Queue enable game controls
  275. ctx.function_queue.push
  276. (
  277. [&ctx]()
  278. {
  279. ::enable_game_controls(ctx);
  280. }
  281. );
  282. // Queue fade in
  283. ctx.fade_transition_color->set({0, 0, 0});
  284. ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
  285. // Refresh frame scheduler
  286. ctx.frame_scheduler.refresh();
  287. debug::log_trace("Entered nest selection state");
  288. }
  289. nest_selection_state::~nest_selection_state()
  290. {
  291. debug::log_trace("Exiting nest selection state...");
  292. // Disable game controls
  293. ::disable_game_controls(ctx);
  294. destroy_first_person_camera_rig();
  295. debug::log_trace("Exited nest selection state");
  296. }
  297. void nest_selection_state::create_first_person_camera_rig()
  298. {
  299. // Construct first person camera rig transform component
  300. transform_component first_person_camera_rig_transform;
  301. first_person_camera_rig_transform.local = math::transform<float>::identity();
  302. first_person_camera_rig_transform.local.translation = {0, 10, 0};
  303. first_person_camera_rig_transform.world = first_person_camera_rig_transform.local;
  304. // Construct first person camera rig locomotion component
  305. winged_locomotion_component first_person_camera_rig_locomotion;
  306. // Construct first person camera rig physics component
  307. auto first_person_camera_rig_body = std::make_unique<physics::rigid_body>();
  308. first_person_camera_rig_body->set_position({0, 10, 0});
  309. first_person_camera_rig_body->set_mass(1.0f);
  310. first_person_camera_rig_body->set_linear_damping(10.0f);
  311. first_person_camera_rig_body->set_angular_damping(0.5f);
  312. auto first_person_camera_rig_collider = std::make_shared<physics::sphere_collider>(1.0f);
  313. auto camera_collider_material = std::make_shared<physics::collider_material>(0.0f, 0.0f, 0.0f);
  314. camera_collider_material->set_restitution_combine_mode(physics::restitution_combine_mode::minimum);
  315. camera_collider_material->set_friction_combine_mode(physics::friction_combine_mode::minimum);
  316. first_person_camera_rig_collider->set_layer_mask(0b10);
  317. first_person_camera_rig_collider->set_material(std::move(camera_collider_material));
  318. first_person_camera_rig_body->set_collider(std::move(first_person_camera_rig_collider));
  319. // Construct first person camera rig scene component
  320. scene_component first_person_camera_rig_camera;
  321. first_person_camera_rig_camera.object = ctx.surface_camera;
  322. // Construct first person camera rig entity
  323. first_person_camera_rig_eid = ctx.entity_registry->create();
  324. ctx.entity_registry->emplace<scene_component>(first_person_camera_rig_eid, first_person_camera_rig_camera);
  325. ctx.entity_registry->emplace<transform_component>(first_person_camera_rig_eid, first_person_camera_rig_transform);
  326. ctx.entity_registry->emplace<rigid_body_component>(first_person_camera_rig_eid, std::move(first_person_camera_rig_body));
  327. ctx.entity_registry->emplace<winged_locomotion_component>(first_person_camera_rig_eid, first_person_camera_rig_locomotion);
  328. }
  329. void nest_selection_state::destroy_first_person_camera_rig()
  330. {
  331. ctx.entity_registry->destroy(first_person_camera_rig_eid);
  332. }
  333. void nest_selection_state::set_first_person_camera_rig_pedestal(float pedestal)
  334. {
  335. }
  336. void nest_selection_state::move_first_person_camera_rig(const math::fvec2& direction, float factor)
  337. {
  338. }
  339. void nest_selection_state::satisfy_first_person_camera_rig_constraints()
  340. {
  341. }
  342. void nest_selection_state::setup_controls()
  343. {
  344. constexpr float movement_speed = 200.0f;
  345. auto move_first_person_camera_rig = [&](const math::fvec2& direction, float speed)
  346. {
  347. const transform_component& first_person_camera_rig_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
  348. const math::fquat yaw_rotation = math::angle_axis(static_cast<float>(first_person_camera_yaw), math::fvec3{0.0f, 1.0f, 0.0f});
  349. const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]};
  350. const math::fvec3 force = rotated_direction * speed;
  351. moving = true;
  352. movement_direction = direction;
  353. this->movement_speed = speed;
  354. ctx.entity_registry->patch<winged_locomotion_component>
  355. (
  356. first_person_camera_rig_eid,
  357. [&](auto& component)
  358. {
  359. component.force = force;
  360. }
  361. );
  362. };
  363. auto stop_first_person_camera_rig = [&]()
  364. {
  365. moving = false;
  366. ctx.entity_registry->patch<winged_locomotion_component>
  367. (
  368. first_person_camera_rig_eid,
  369. [&](auto& component)
  370. {
  371. component.force = {0.0f, 0.0f, 0.0f};
  372. }
  373. );
  374. };
  375. // Mouse look
  376. mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
  377. (
  378. [&, move_first_person_camera_rig](const auto& event)
  379. {
  380. if (adjust_time)
  381. {
  382. const double sensitivity = 1.0 / static_cast<double>(ctx.window->get_viewport_size().x());
  383. const double t = ctx.astronomy_system->get_time();
  384. ::world::set_time(ctx, t + static_cast<double>(event.difference.x()) * sensitivity);
  385. /*
  386. sky_probe->update_illuminance_matrices();
  387. const auto matrices = sky_probe->get_illuminance_matrices();
  388. for (std::size_t i = 0; i < 3; ++i)
  389. {
  390. const auto m = matrices[i];
  391. 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]);
  392. }
  393. */
  394. }
  395. if (adjust_exposure)
  396. {
  397. const float sensitivity = 8.0f / static_cast<float>(ctx.window->get_viewport_size().y());
  398. ctx.surface_camera->set_exposure_value(ctx.surface_camera->get_exposure_value() + static_cast<float>(event.difference.y()) * sensitivity);
  399. }
  400. if (!mouse_look)
  401. {
  402. return;
  403. }
  404. first_person_camera_yaw -= ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
  405. first_person_camera_pitch += ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
  406. first_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, first_person_camera_pitch));
  407. const math::dquat yaw_rotation = math::angle_axis(first_person_camera_yaw, {0.0f, 1.0, 0.0});
  408. const math::dquat pitch_rotation = math::angle_axis(first_person_camera_pitch, {-1.0, 0.0, 0.0});
  409. const math::fquat first_person_camera_orientation = math::fquat(math::normalize(yaw_rotation * pitch_rotation));
  410. ctx.entity_registry->patch<scene_component>
  411. (
  412. first_person_camera_rig_eid,
  413. [&](auto& component)
  414. {
  415. component.object->set_rotation(first_person_camera_orientation);
  416. }
  417. );
  418. ctx.entity_registry->patch<rigid_body_component>
  419. (
  420. first_person_camera_rig_eid,
  421. [&](auto& component)
  422. {
  423. component.body->set_previous_orientation(first_person_camera_orientation);
  424. component.body->set_orientation(first_person_camera_orientation);
  425. }
  426. );
  427. ctx.entity_registry->patch<transform_component>
  428. (
  429. first_person_camera_rig_eid,
  430. [&](auto& component)
  431. {
  432. component.local.rotation = first_person_camera_orientation;
  433. component.world.rotation = first_person_camera_orientation;
  434. }
  435. );
  436. if (moving)
  437. {
  438. move_first_person_camera_rig(movement_direction, this->movement_speed);
  439. }
  440. }
  441. );
  442. // Move forward
  443. action_subscriptions.emplace_back
  444. (
  445. ctx.move_forward_action.get_active_channel().subscribe
  446. (
  447. [&, move_first_person_camera_rig](const auto& event)
  448. {
  449. move_first_person_camera_rig({0.0f, -1.0f}, movement_speed * event.input_value);
  450. }
  451. )
  452. );
  453. action_subscriptions.emplace_back
  454. (
  455. ctx.move_forward_action.get_deactivated_channel().subscribe
  456. (
  457. [&, stop_first_person_camera_rig](const auto& event)
  458. {
  459. stop_first_person_camera_rig();
  460. }
  461. )
  462. );
  463. // Move back
  464. action_subscriptions.emplace_back
  465. (
  466. ctx.move_back_action.get_active_channel().subscribe
  467. (
  468. [&, move_first_person_camera_rig](const auto& event)
  469. {
  470. move_first_person_camera_rig({0, 1}, movement_speed * event.input_value);
  471. }
  472. )
  473. );
  474. action_subscriptions.emplace_back
  475. (
  476. ctx.move_back_action.get_deactivated_channel().subscribe
  477. (
  478. [&, stop_first_person_camera_rig](const auto& event)
  479. {
  480. stop_first_person_camera_rig();
  481. }
  482. )
  483. );
  484. // Move left
  485. action_subscriptions.emplace_back
  486. (
  487. ctx.move_left_action.get_active_channel().subscribe
  488. (
  489. [&, move_first_person_camera_rig](const auto& event)
  490. {
  491. move_first_person_camera_rig({-1, 0}, movement_speed * event.input_value);
  492. }
  493. )
  494. );
  495. action_subscriptions.emplace_back
  496. (
  497. ctx.move_left_action.get_deactivated_channel().subscribe
  498. (
  499. [&, stop_first_person_camera_rig](const auto& event)
  500. {
  501. stop_first_person_camera_rig();
  502. }
  503. )
  504. );
  505. // Move right
  506. action_subscriptions.emplace_back
  507. (
  508. ctx.move_right_action.get_active_channel().subscribe
  509. (
  510. [&, move_first_person_camera_rig](const auto& event)
  511. {
  512. move_first_person_camera_rig({1, 0}, movement_speed * event.input_value);
  513. }
  514. )
  515. );
  516. action_subscriptions.emplace_back
  517. (
  518. ctx.move_right_action.get_deactivated_channel().subscribe
  519. (
  520. [&, stop_first_person_camera_rig](const auto& event)
  521. {
  522. stop_first_person_camera_rig();
  523. }
  524. )
  525. );
  526. // Move up
  527. action_subscriptions.emplace_back
  528. (
  529. ctx.move_up_action.get_activated_channel().subscribe
  530. (
  531. [&](const auto& event)
  532. {
  533. ctx.entity_registry->patch<rigid_body_component>
  534. (
  535. first_person_camera_rig_eid,
  536. [&](auto& component)
  537. {
  538. component.body->apply_central_impulse({0, 5.0f, 0});
  539. }
  540. );
  541. }
  542. )
  543. );
  544. // Move down
  545. action_subscriptions.emplace_back
  546. (
  547. ctx.move_down_action.get_activated_channel().subscribe
  548. (
  549. [&](const auto& event)
  550. {
  551. ctx.entity_registry->patch<rigid_body_component>
  552. (
  553. first_person_camera_rig_eid,
  554. [&](auto& component)
  555. {
  556. component.body->apply_central_impulse({0, -5.0f, 0});
  557. }
  558. );
  559. }
  560. )
  561. );
  562. /*
  563. // Focus
  564. action_subscriptions.emplace_back
  565. (
  566. ctx.focus_action.get_activated_channel().subscribe
  567. (
  568. [&](const auto& event)
  569. {
  570. auto projectile_eid = ctx.entity_registry->create();
  571. const auto& camera_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
  572. scene_component projectile_scene;
  573. transform_component projectile_transform;
  574. projectile_transform.local = camera_transform.world;
  575. projectile_transform.world = projectile_transform.local;
  576. auto projectile_body = std::make_unique<physics::rigid_body>();
  577. projectile_body->set_position(camera_transform.world.translation);
  578. projectile_body->set_previous_position(camera_transform.world.translation);
  579. projectile_body->set_mass(0.1f);
  580. projectile_body->set_inertia(0.05f);
  581. projectile_body->set_angular_damping(0.5f);
  582. if (ctx.mouse_look_action.is_active())
  583. {
  584. auto projectile_collider = std::make_shared<physics::sphere_collider>(1.0f);
  585. //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});
  586. projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  587. projectile_body->set_collider(std::move(projectile_collider));
  588. projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("sphere.mdl"));
  589. //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("cube.mdl"));
  590. }
  591. else
  592. {
  593. 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});
  594. projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  595. projectile_body->set_collider(std::move(projectile_collider));
  596. //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("capsule.mdl"));
  597. auto projectile_mesh = std::make_shared<scene::skeletal_mesh>(worker_model);
  598. projectile_mesh->get_pose() = *worker_model->get_skeleton().get_pose("pupa");
  599. projectile_scene.object = projectile_mesh;
  600. }
  601. projectile_body->apply_central_impulse(camera_transform.world.rotation * math::fvec3{0.0f, 0.0f, -10.0f});
  602. // auto spring_eid = ctx.entity_registry->create();
  603. // auto spring = std::make_unique<physics::spring_constraint>();
  604. // spring->attach_a(*ctx.entity_registry->get<rigid_body_component>(first_person_camera_rig_eid).body, {0.0f, 0.0f, 0.0f});
  605. // spring->attach_b(*projectile_body, {0.0f, 0.0f, 0.0f});
  606. // spring->set_resting_length(10.0f);
  607. // spring->set_stiffness(2.0f);
  608. // spring->set_damping(1.0f);
  609. // ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
  610. ctx.entity_registry->emplace<transform_component>(projectile_eid, projectile_transform);
  611. ctx.entity_registry->emplace<scene_component>(projectile_eid, std::move(projectile_scene));
  612. ctx.entity_registry->emplace<rigid_body_component>(projectile_eid, std::move(projectile_body));
  613. // body.linear_momentum = math::fvec3::zero();
  614. // body.angular_momentum = math::fvec3::zero();
  615. // body.linear_velocity = math::fvec3::zero();
  616. // body.angular_velocity = math::fvec3::zero();
  617. //body.apply_central_impulse({0.0f, 100.5f, 0.0f});
  618. // ctx.entity_registry->patch<constraint_stack_node_component>
  619. // (
  620. // first_person_camera_rig_track_to_eid,
  621. // [&](auto& component)
  622. // {
  623. // component.active = true;
  624. // }
  625. // );
  626. }
  627. )
  628. );
  629. action_subscriptions.emplace_back
  630. (
  631. ctx.focus_action.get_deactivated_channel().subscribe
  632. (
  633. [&](const auto& event)
  634. {
  635. }
  636. )
  637. );
  638. */
  639. }
  640. void nest_selection_state::enable_controls()
  641. {
  642. }
  643. void nest_selection_state::disable_controls()
  644. {
  645. }