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

983 lines
35 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/spring-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/nest-selection-state.hpp"
  51. #include "game/states/pause-menu-state.hpp"
  52. #include "game/systems/astronomy-system.hpp"
  53. #include "game/systems/atmosphere-system.hpp"
  54. #include "game/systems/camera-system.hpp"
  55. #include "game/systems/collision-system.hpp"
  56. #include "game/world.hpp"
  57. #include <engine/animation/ease.hpp>
  58. #include <engine/animation/screen-transition.hpp>
  59. #include <engine/config.hpp>
  60. #include <engine/entity/archetype.hpp>
  61. #include <engine/input/mouse.hpp>
  62. #include <engine/math/interpolation.hpp>
  63. #include <engine/math/projection.hpp>
  64. #include <engine/physics/light/exposure.hpp>
  65. #include <engine/physics/kinematics/constraints/spring-constraint.hpp>
  66. #include <engine/physics/kinematics/colliders/sphere-collider.hpp>
  67. #include <engine/physics/kinematics/colliders/plane-collider.hpp>
  68. #include <engine/physics/kinematics/colliders/box-collider.hpp>
  69. #include <engine/physics/kinematics/colliders/capsule-collider.hpp>
  70. #include <engine/render/passes/clear-pass.hpp>
  71. #include <engine/render/passes/ground-pass.hpp>
  72. #include <engine/resources/resource-manager.hpp>
  73. #include <engine/utility/state-machine.hpp>
  74. #include <engine/scene/static-mesh.hpp>
  75. #include <engine/scene/skeletal-mesh.hpp>
  76. #include <engine/animation/ik/constraints/swing-twist-ik-constraint.hpp>
  77. #include <engine/animation/ik/constraints/euler-ik-constraint.hpp>
  78. nest_selection_state::nest_selection_state(::game& ctx):
  79. game_state(ctx)
  80. {
  81. debug::log::trace("Entering nest selection state...");
  82. // Create world if not yet created
  83. if (ctx.entities.find("earth") == ctx.entities.end())
  84. {
  85. // Create cosmos
  86. ::world::cosmogenesis(ctx);
  87. // Create observer
  88. ::world::create_observer(ctx);
  89. }
  90. ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
  91. ::world::enter_ecoregion(ctx, *ctx.active_ecoregion);
  92. debug::log::trace("Generating genome...");
  93. std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
  94. debug::log::trace("Generated genome");
  95. debug::log::trace("Building worker phenome...");
  96. ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen);
  97. debug::log::trace("Built worker phenome...");
  98. debug::log::trace("Generating worker model...");
  99. worker_model = ant_morphogenesis(worker_phenome);
  100. debug::log::trace("Generated worker model");
  101. // Create floor plane
  102. auto floor_archetype = ctx.resource_manager->load<entity::archetype>("desert-scrub-plane.ent");
  103. auto floor_eid = floor_archetype->create(*ctx.entity_registry);
  104. ctx.entity_registry->patch<transform_component>
  105. (
  106. floor_eid,
  107. [](auto& component)
  108. {
  109. component.local.rotation = math::angle_axis(math::radians(3.0f), math::fvec3{1.0f, 0.0f, 0.0f});
  110. }
  111. );
  112. auto floor_body = std::make_unique<physics::rigid_body>();
  113. auto floor_collider = std::make_shared<physics::plane_collider>(math::fvec3{0.0f, 1.0f, 0.0f});
  114. floor_collider->set_layer_mask(0b11);
  115. floor_collider->set_material(std::make_shared<physics::collider_material>(1.0f, 0.5f, 1.0f));
  116. floor_body->set_mass(0.0f);
  117. floor_body->set_inertia(0.0f);
  118. floor_body->set_collider(std::move(floor_collider));
  119. ctx.entity_registry->emplace<rigid_body_component>(floor_eid, std::move(floor_body));
  120. // Create worker entity(s)
  121. auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
  122. worker_ant_eid = ctx.entity_registry->create();
  123. transform_component worker_transform_component;
  124. worker_transform_component.local = math::transform<float>::identity();
  125. worker_transform_component.local.translation = {0, 0.5f, -4};
  126. worker_transform_component.world = worker_transform_component.local;
  127. ctx.entity_registry->emplace<transform_component>(worker_ant_eid, worker_transform_component);
  128. ctx.entity_registry->emplace<scene_component>(worker_ant_eid, std::move(worker_skeletal_mesh), std::uint8_t{1});
  129. 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});
  130. //auto worker_collider = std::make_shared<physics::sphere_collider>(1.0f);
  131. worker_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  132. auto worker_body = std::make_unique<physics::rigid_body>();
  133. worker_body->set_position(worker_transform_component.local.translation);
  134. worker_body->set_previous_position(worker_transform_component.local.translation);
  135. worker_body->set_mass(0.1f);
  136. worker_body->set_inertia(0.05f);
  137. worker_body->set_angular_damping(0.5f);
  138. worker_body->set_collider(std::move(worker_collider));
  139. //ctx.entity_registry->emplace<rigid_body_component>(worker_ant_eid, std::move(worker_body));
  140. auto cocoon_eid = ctx.entity_registry->create();
  141. ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::make_shared<scene::static_mesh>(worker_phenome.cocoon->model), std::uint8_t{1});
  142. larva_eid = ctx.entity_registry->create();
  143. auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
  144. //auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(ctx.resource_manager->load<render::model>("snake.mdl"));
  145. const auto& larva_skeleton = larva_skeletal_mesh->get_model()->get_skeleton();
  146. auto larva_ik_rig = std::make_shared<ik_rig>(*larva_skeletal_mesh);
  147. auto no_twist_constraint = std::make_shared<swing_twist_ik_constraint>();
  148. no_twist_constraint->set_twist_limit(0.0f, 0.0f);
  149. //auto euler_constraint = std::make_shared<euler_ik_constraint>();
  150. //euler_constraint->set_limits({0.0f, -math::radians(90.0f), 0.0f}, {math::radians(90.0f), math::radians(90.0f), 0.0f});
  151. for (std::size_t i = 0; i < larva_skeleton.get_bone_count(); ++i)
  152. {
  153. larva_ik_rig->set_constraint(static_cast<bone_index_type>(i), no_twist_constraint);
  154. }
  155. const auto larva_ik_root_bone_index = *larva_skeleton.get_bone_index("abdomen3");
  156. const auto larva_ik_effector_bone_index = *larva_skeleton.get_bone_index("head");
  157. const auto& larva_head_absolute_transform = larva_skeletal_mesh->get_pose().get_absolute_transform(larva_ik_effector_bone_index);
  158. const auto& larva_head_relative_transform = larva_skeletal_mesh->get_pose().get_relative_transform(larva_ik_effector_bone_index);
  159. larva_ik_solver = std::make_shared<ccd_ik_solver>(*larva_ik_rig, larva_ik_root_bone_index, larva_ik_effector_bone_index);
  160. larva_ik_solver->set_effector_position(larva_head_relative_transform * math::fvec3{0.0f, 0.0f, -0.0f});
  161. larva_ik_solver->set_goal_center(larva_head_absolute_transform.translation + math::fvec3{0.2f, 0.2f, 0.5f});
  162. larva_ik_rig->add_solver(larva_ik_solver);
  163. //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}));
  164. //larva_skeletal_mesh->get_pose().update();
  165. ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{1});
  166. ctx.entity_registry->emplace<ik_component>(larva_eid, std::move(larva_ik_rig));
  167. // Disable UI color clear
  168. ctx.ui_clear_pass->set_cleared_buffers(false, true, false);
  169. // Set world time
  170. ::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
  171. // Init time scale
  172. double time_scale = 60.0;
  173. // Set time scale
  174. ::world::set_time_scale(ctx, time_scale);
  175. // Setup and enable sky and ground passes
  176. ctx.sky_pass->set_enabled(true);
  177. ctx.ground_pass->set_enabled(true);
  178. // Set camera exposure
  179. const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
  180. ctx.surface_camera->set_exposure_value(ev100_sunny16);
  181. const auto& viewport_size = ctx.window->get_viewport_size();
  182. const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
  183. // Init first person camera rig parameters
  184. first_person_camera_rig_translation_spring_angular_frequency = period_to_rads(0.125f);
  185. first_person_camera_rig_rotation_spring_angular_frequency = period_to_rads(0.125f);
  186. first_person_camera_rig_fov_spring_angular_frequency = period_to_rads(0.125f);
  187. first_person_camera_rig_min_elevation = 0.25f;
  188. first_person_camera_rig_max_elevation = 150.0f;
  189. first_person_camera_near_fov = math::vertical_fov(math::radians(100.0f), aspect_ratio);
  190. first_person_camera_far_fov = math::vertical_fov(math::radians(60.0f), aspect_ratio);
  191. first_person_camera_near_speed = 5.0f;
  192. first_person_camera_far_speed = 140.0f;
  193. first_person_camera_rig_pedestal_speed = 2.0f;
  194. first_person_camera_rig_pedestal = 0.0f;
  195. // Create first person camera rig
  196. create_first_person_camera_rig();
  197. // Satisfy first person camera rig constraints
  198. satisfy_first_person_camera_rig_constraints();
  199. // Setup controls
  200. setup_controls();
  201. auto color_checker_archetype = ctx.resource_manager->load<entity::archetype>("color-checker.ent");
  202. color_checker_archetype->create(*ctx.entity_registry);
  203. // auto ruler_archetype = ctx.resource_manager->load<entity::archetype>("ruler-10cm.ent");
  204. // ruler_archetype->create(*ctx.entity_registry);
  205. auto yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-l.ent");
  206. auto yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  207. ::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 0, 70});
  208. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-m.ent");
  209. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  210. ::command::warp_to(*ctx.entity_registry, yucca_eid, {400, 0, 200});
  211. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-s.ent");
  212. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  213. ::command::warp_to(*ctx.entity_registry, yucca_eid, {-300, 0, -300});
  214. auto cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-l.ent");
  215. auto cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  216. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {-100, 0, -200});
  217. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-m.ent");
  218. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  219. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {100, 0, -70});
  220. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-s.ent");
  221. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  222. ::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {50, 0, 80});
  223. // auto cactus_seed_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-seed.ent");
  224. // auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry);
  225. // ::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {0, 1, -5});
  226. // Create spring
  227. /*
  228. auto spring_eid = ctx.entity_registry->create();
  229. auto spring = std::make_unique<physics::spring_constraint>();
  230. spring->attach_a();
  231. spring->attach_b();
  232. spring->set_resting_length(10.0f);
  233. spring->set_stiffness(2.0f);
  234. spring->set_damping(1.0f);
  235. ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
  236. */
  237. sky_probe = std::make_shared<scene::light_probe>();
  238. sky_probe->set_luminance_texture(std::make_shared<gl::texture_cube>(384, 512, gl::pixel_type::float_16, gl::pixel_format::rgb));
  239. ctx.sky_pass->set_sky_probe(sky_probe);
  240. ctx.surface_scene->add_object(*sky_probe);
  241. // Create sphere
  242. auto sphere_eid = ctx.entity_registry->create();
  243. auto sphere_static_mesh = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("diffuse-spheres.mdl"));
  244. ctx.entity_registry->emplace<scene_component>(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{1});
  245. ctx.entity_registry->patch<scene_component>
  246. (
  247. sphere_eid,
  248. [&](auto& component)
  249. {
  250. component.object->set_translation({0.0f, 10.0f, 0.0f});
  251. }
  252. );
  253. // Queue enable game controls
  254. ctx.function_queue.push
  255. (
  256. [&ctx]()
  257. {
  258. ::enable_game_controls(ctx);
  259. }
  260. );
  261. // Queue fade in
  262. ctx.fade_transition_color->set({0, 0, 0});
  263. ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
  264. // Refresh frame scheduler
  265. ctx.frame_scheduler.refresh();
  266. debug::log::trace("Entered nest selection state");
  267. }
  268. nest_selection_state::~nest_selection_state()
  269. {
  270. debug::log::trace("Exiting nest selection state...");
  271. // Disable game controls
  272. ::disable_game_controls(ctx);
  273. destroy_first_person_camera_rig();
  274. debug::log::trace("Exited nest selection state");
  275. }
  276. void nest_selection_state::create_first_person_camera_rig()
  277. {
  278. // Construct first person camera rig transform component
  279. transform_component first_person_camera_rig_transform;
  280. first_person_camera_rig_transform.local = math::transform<float>::identity();
  281. first_person_camera_rig_transform.local.translation = {0, 10, 0};
  282. first_person_camera_rig_transform.world = first_person_camera_rig_transform.local;
  283. // Construct first person camera rig locomotion component
  284. winged_locomotion_component first_person_camera_rig_locomotion;
  285. // Construct first person camera rig physics component
  286. auto first_person_camera_rig_body = std::make_unique<physics::rigid_body>();
  287. first_person_camera_rig_body->set_position({0, 10, 0});
  288. first_person_camera_rig_body->set_mass(1.0f);
  289. first_person_camera_rig_body->set_linear_damping(10.0f);
  290. first_person_camera_rig_body->set_angular_damping(0.5f);
  291. auto first_person_camera_rig_collider = std::make_shared<physics::sphere_collider>(1.0f);
  292. auto camera_collider_material = std::make_shared<physics::collider_material>(0.0f, 0.0f, 0.0f);
  293. camera_collider_material->set_restitution_combine_mode(physics::restitution_combine_mode::minimum);
  294. camera_collider_material->set_friction_combine_mode(physics::friction_combine_mode::minimum);
  295. first_person_camera_rig_collider->set_layer_mask(0b10);
  296. first_person_camera_rig_collider->set_material(std::move(camera_collider_material));
  297. first_person_camera_rig_body->set_collider(std::move(first_person_camera_rig_collider));
  298. // Construct first person camera rig scene component
  299. scene_component first_person_camera_rig_camera;
  300. first_person_camera_rig_camera.object = ctx.surface_camera;
  301. // Construct first person camera rig entity
  302. first_person_camera_rig_eid = ctx.entity_registry->create();
  303. ctx.entity_registry->emplace<scene_component>(first_person_camera_rig_eid, first_person_camera_rig_camera);
  304. ctx.entity_registry->emplace<transform_component>(first_person_camera_rig_eid, first_person_camera_rig_transform);
  305. ctx.entity_registry->emplace<rigid_body_component>(first_person_camera_rig_eid, std::move(first_person_camera_rig_body));
  306. ctx.entity_registry->emplace<winged_locomotion_component>(first_person_camera_rig_eid, first_person_camera_rig_locomotion);
  307. }
  308. void nest_selection_state::destroy_first_person_camera_rig()
  309. {
  310. ctx.entity_registry->destroy(first_person_camera_rig_eid);
  311. }
  312. void nest_selection_state::set_first_person_camera_rig_pedestal(float pedestal)
  313. {
  314. // first_person_camera_rig_pedestal = pedestal;
  315. // const float elevation = math::log_lerp(first_person_camera_rig_min_elevation, first_person_camera_rig_max_elevation, first_person_camera_rig_pedestal);
  316. // const float fov = math::log_lerp(first_person_camera_near_fov, first_person_camera_far_fov, first_person_camera_rig_pedestal);
  317. // ctx.entity_registry->patch<spring_translation_constraint>
  318. // (
  319. // first_person_camera_rig_spring_translation_eid,
  320. // [&](auto& component)
  321. // {
  322. // component.spring.x1[1] = elevation;
  323. // }
  324. // );
  325. // ctx.entity_registry->patch<spring1_component>
  326. // (
  327. // first_person_camera_rig_fov_spring_eid,
  328. // [&](auto& component)
  329. // {
  330. // component.spring.x1 = fov;
  331. // }
  332. // );
  333. }
  334. void nest_selection_state::move_first_person_camera_rig(const math::fvec2& direction, float factor)
  335. {
  336. // const float speed = math::log_lerp(first_person_camera_near_speed, first_person_camera_far_speed, first_person_camera_rig_pedestal) * factor;
  337. // const spring_rotation_constraint& first_person_camera_rig_spring_rotation = ctx.entity_registry->get<spring_rotation_constraint>(first_person_camera_rig_spring_rotation_eid);
  338. // const math::fquat yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], math::fvec3{0.0f, 1.0f, 0.0f});
  339. // const math::fvec3 rotated_direction = math::normalize(yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]});
  340. // const math::fvec3 velocity = rotated_direction * speed;
  341. // ctx.entity_registry->patch<spring_translation_constraint>
  342. // (
  343. // first_person_camera_rig_spring_translation_eid,
  344. // [&](auto& component)
  345. // {
  346. // component.spring.x1 += velocity * static_cast<float>(1.0 / ctx.fixed_update_rate);
  347. // }
  348. // );
  349. }
  350. void nest_selection_state::satisfy_first_person_camera_rig_constraints()
  351. {
  352. // Satisfy first person camera rig spring translation constraint
  353. // ctx.entity_registry->patch<spring_translation_constraint>
  354. // (
  355. // first_person_camera_rig_spring_translation_eid,
  356. // [&](auto& component)
  357. // {
  358. // component.spring.x0 = component.spring.x1;
  359. // component.spring.v *= 0.0f;
  360. // }
  361. // );
  362. // Satisfy first person camera rig spring rotation constraint
  363. // ctx.entity_registry->patch<spring_rotation_constraint>
  364. // (
  365. // first_person_camera_rig_spring_rotation_eid,
  366. // [&](auto& component)
  367. // {
  368. // component.spring.x0 = component.spring.x1;
  369. // component.spring.v *= 0.0f;
  370. // }
  371. // );
  372. // Satisfy first person camera rig fov spring
  373. // ctx.entity_registry->patch<spring1_component>
  374. // (
  375. // first_person_camera_rig_fov_spring_eid,
  376. // [&](auto& component)
  377. // {
  378. // component.spring.x0 = component.spring.x1;
  379. // component.spring.v *= 0.0f;
  380. // }
  381. // );
  382. }
  383. void nest_selection_state::setup_controls()
  384. {
  385. constexpr float movement_speed = 200.0f;
  386. auto move_first_person_camera_rig = [&](const math::fvec2& direction, float speed)
  387. {
  388. const transform_component& first_person_camera_rig_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
  389. //const spring_rotation_constraint& first_person_camera_rig_spring_rotation = ctx.entity_registry->get<spring_rotation_constraint>(first_person_camera_rig_spring_rotation_eid);
  390. //const math::fquat yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], math::fvec3{0.0f, 1.0f, 0.0f});
  391. //const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]};
  392. const math::fquat yaw_rotation = math::angle_axis(static_cast<float>(first_person_camera_yaw), math::fvec3{0.0f, 1.0f, 0.0f});
  393. const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]};
  394. const math::fvec3 force = rotated_direction * speed;
  395. moving = true;
  396. movement_direction = direction;
  397. this->movement_speed = speed;
  398. ctx.entity_registry->patch<winged_locomotion_component>
  399. (
  400. first_person_camera_rig_eid,
  401. [&](auto& component)
  402. {
  403. component.force = force;
  404. }
  405. );
  406. };
  407. auto stop_first_person_camera_rig = [&]()
  408. {
  409. moving = false;
  410. ctx.entity_registry->patch<winged_locomotion_component>
  411. (
  412. first_person_camera_rig_eid,
  413. [&](auto& component)
  414. {
  415. component.force = {0.0f, 0.0f, 0.0f};
  416. }
  417. );
  418. };
  419. // Mouse look
  420. mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
  421. (
  422. [&, move_first_person_camera_rig](const auto& event)
  423. {
  424. if (adjust_time)
  425. {
  426. const double sensitivity = 1.0 / static_cast<double>(ctx.window->get_viewport_size().x());
  427. const double t = ctx.astronomy_system->get_time();
  428. ::world::set_time(ctx, t + static_cast<double>(event.difference.x()) * sensitivity);
  429. /*
  430. sky_probe->update_illuminance_matrices();
  431. const auto matrices = sky_probe->get_illuminance_matrices();
  432. for (std::size_t i = 0; i < 3; ++i)
  433. {
  434. const auto m = matrices[i];
  435. 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]);
  436. }
  437. */
  438. }
  439. if (adjust_exposure)
  440. {
  441. const float sensitivity = 8.0f / static_cast<float>(ctx.window->get_viewport_size().y());
  442. ctx.surface_camera->set_exposure_value(ctx.surface_camera->get_exposure_value() + static_cast<float>(event.difference.y()) * sensitivity);
  443. }
  444. if (!mouse_look)
  445. {
  446. return;
  447. }
  448. first_person_camera_yaw -= ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
  449. first_person_camera_pitch += ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
  450. first_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, first_person_camera_pitch));
  451. const math::dquat yaw_rotation = math::angle_axis(first_person_camera_yaw, {0.0f, 1.0, 0.0});
  452. const math::dquat pitch_rotation = math::angle_axis(first_person_camera_pitch, {-1.0, 0.0, 0.0});
  453. const math::fquat first_person_camera_orientation = math::fquat(math::normalize(yaw_rotation * pitch_rotation));
  454. ctx.entity_registry->patch<scene_component>
  455. (
  456. first_person_camera_rig_eid,
  457. [&](auto& component)
  458. {
  459. component.object->set_rotation(first_person_camera_orientation);
  460. }
  461. );
  462. ctx.entity_registry->patch<rigid_body_component>
  463. (
  464. first_person_camera_rig_eid,
  465. [&](auto& component)
  466. {
  467. component.body->set_previous_orientation(first_person_camera_orientation);
  468. component.body->set_orientation(first_person_camera_orientation);
  469. }
  470. );
  471. ctx.entity_registry->patch<transform_component>
  472. (
  473. first_person_camera_rig_eid,
  474. [&](auto& component)
  475. {
  476. component.local.rotation = first_person_camera_orientation;
  477. component.world.rotation = first_person_camera_orientation;
  478. }
  479. );
  480. if (moving)
  481. {
  482. move_first_person_camera_rig(movement_direction, this->movement_speed);
  483. }
  484. }
  485. );
  486. // Move forward
  487. action_subscriptions.emplace_back
  488. (
  489. ctx.move_forward_action.get_active_channel().subscribe
  490. (
  491. [&, move_first_person_camera_rig](const auto& event)
  492. {
  493. move_first_person_camera_rig({0.0f, -1.0f}, movement_speed * event.input_value);
  494. }
  495. )
  496. );
  497. action_subscriptions.emplace_back
  498. (
  499. ctx.move_forward_action.get_deactivated_channel().subscribe
  500. (
  501. [&, stop_first_person_camera_rig](const auto& event)
  502. {
  503. stop_first_person_camera_rig();
  504. }
  505. )
  506. );
  507. // Move back
  508. action_subscriptions.emplace_back
  509. (
  510. ctx.move_back_action.get_active_channel().subscribe
  511. (
  512. [&, move_first_person_camera_rig](const auto& event)
  513. {
  514. move_first_person_camera_rig({0, 1}, movement_speed * event.input_value);
  515. }
  516. )
  517. );
  518. action_subscriptions.emplace_back
  519. (
  520. ctx.move_back_action.get_deactivated_channel().subscribe
  521. (
  522. [&, stop_first_person_camera_rig](const auto& event)
  523. {
  524. stop_first_person_camera_rig();
  525. }
  526. )
  527. );
  528. // Move left
  529. action_subscriptions.emplace_back
  530. (
  531. ctx.move_left_action.get_active_channel().subscribe
  532. (
  533. [&, move_first_person_camera_rig](const auto& event)
  534. {
  535. move_first_person_camera_rig({-1, 0}, movement_speed * event.input_value);
  536. }
  537. )
  538. );
  539. action_subscriptions.emplace_back
  540. (
  541. ctx.move_left_action.get_deactivated_channel().subscribe
  542. (
  543. [&, stop_first_person_camera_rig](const auto& event)
  544. {
  545. stop_first_person_camera_rig();
  546. }
  547. )
  548. );
  549. // Move right
  550. action_subscriptions.emplace_back
  551. (
  552. ctx.move_right_action.get_active_channel().subscribe
  553. (
  554. [&, move_first_person_camera_rig](const auto& event)
  555. {
  556. move_first_person_camera_rig({1, 0}, movement_speed * event.input_value);
  557. }
  558. )
  559. );
  560. action_subscriptions.emplace_back
  561. (
  562. ctx.move_right_action.get_deactivated_channel().subscribe
  563. (
  564. [&, stop_first_person_camera_rig](const auto& event)
  565. {
  566. stop_first_person_camera_rig();
  567. }
  568. )
  569. );
  570. // Move up
  571. action_subscriptions.emplace_back
  572. (
  573. ctx.move_up_action.get_activated_channel().subscribe
  574. (
  575. [&](const auto& event)
  576. {
  577. ctx.entity_registry->patch<rigid_body_component>
  578. (
  579. first_person_camera_rig_eid,
  580. [&](auto& component)
  581. {
  582. component.body->apply_central_impulse({0, 5.0f, 0});
  583. }
  584. );
  585. }
  586. )
  587. );
  588. // Move down
  589. action_subscriptions.emplace_back
  590. (
  591. ctx.move_down_action.get_activated_channel().subscribe
  592. (
  593. [&](const auto& event)
  594. {
  595. ctx.entity_registry->patch<rigid_body_component>
  596. (
  597. first_person_camera_rig_eid,
  598. [&](auto& component)
  599. {
  600. component.body->apply_central_impulse({0, -5.0f, 0});
  601. }
  602. );
  603. }
  604. )
  605. );
  606. /*
  607. // Focus
  608. action_subscriptions.emplace_back
  609. (
  610. ctx.focus_action.get_activated_channel().subscribe
  611. (
  612. [&](const auto& event)
  613. {
  614. auto projectile_eid = ctx.entity_registry->create();
  615. const auto& camera_transform = ctx.entity_registry->get<transform_component>(first_person_camera_rig_eid);
  616. scene_component projectile_scene;
  617. transform_component projectile_transform;
  618. projectile_transform.local = camera_transform.world;
  619. projectile_transform.world = projectile_transform.local;
  620. auto projectile_body = std::make_unique<physics::rigid_body>();
  621. projectile_body->set_position(camera_transform.world.translation);
  622. projectile_body->set_previous_position(camera_transform.world.translation);
  623. projectile_body->set_mass(0.1f);
  624. projectile_body->set_inertia(0.05f);
  625. projectile_body->set_angular_damping(0.5f);
  626. if (ctx.mouse_look_action.is_active())
  627. {
  628. auto projectile_collider = std::make_shared<physics::sphere_collider>(1.0f);
  629. //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});
  630. projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  631. projectile_body->set_collider(std::move(projectile_collider));
  632. projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("sphere.mdl"));
  633. //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("cube.mdl"));
  634. }
  635. else
  636. {
  637. 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});
  638. projectile_collider->set_material(std::make_shared<physics::collider_material>(0.4f, 0.1f, 0.2f));
  639. projectile_body->set_collider(std::move(projectile_collider));
  640. //projectile_scene.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("capsule.mdl"));
  641. auto projectile_mesh = std::make_shared<scene::skeletal_mesh>(worker_model);
  642. projectile_mesh->get_pose() = *worker_model->get_skeleton().get_pose("pupa");
  643. projectile_scene.object = projectile_mesh;
  644. }
  645. projectile_body->apply_central_impulse(camera_transform.world.rotation * math::fvec3{0.0f, 0.0f, -10.0f});
  646. // auto spring_eid = ctx.entity_registry->create();
  647. // auto spring = std::make_unique<physics::spring_constraint>();
  648. // spring->attach_a(*ctx.entity_registry->get<rigid_body_component>(first_person_camera_rig_eid).body, {0.0f, 0.0f, 0.0f});
  649. // spring->attach_b(*projectile_body, {0.0f, 0.0f, 0.0f});
  650. // spring->set_resting_length(10.0f);
  651. // spring->set_stiffness(2.0f);
  652. // spring->set_damping(1.0f);
  653. // ctx.entity_registry->emplace<rigid_body_constraint_component>(spring_eid, std::move(spring));
  654. ctx.entity_registry->emplace<transform_component>(projectile_eid, projectile_transform);
  655. ctx.entity_registry->emplace<scene_component>(projectile_eid, std::move(projectile_scene));
  656. ctx.entity_registry->emplace<rigid_body_component>(projectile_eid, std::move(projectile_body));
  657. // body.linear_momentum = math::fvec3::zero();
  658. // body.angular_momentum = math::fvec3::zero();
  659. // body.linear_velocity = math::fvec3::zero();
  660. // body.angular_velocity = math::fvec3::zero();
  661. //body.apply_central_impulse({0.0f, 100.5f, 0.0f});
  662. // ctx.entity_registry->patch<constraint_stack_node_component>
  663. // (
  664. // first_person_camera_rig_track_to_eid,
  665. // [&](auto& component)
  666. // {
  667. // component.active = true;
  668. // }
  669. // );
  670. }
  671. )
  672. );
  673. action_subscriptions.emplace_back
  674. (
  675. ctx.focus_action.get_deactivated_channel().subscribe
  676. (
  677. [&](const auto& event)
  678. {
  679. }
  680. )
  681. );
  682. */
  683. }
  684. void nest_selection_state::enable_controls()
  685. {
  686. /*
  687. // Reset mouse look
  688. mouse_look = false;
  689. double time_scale = 0.0;
  690. double ff_time_scale = 60.0 * 200.0;
  691. // Init control settings
  692. float mouse_tilt_sensitivity = 1.0f;
  693. float mouse_pan_sensitivity = 1.0f;
  694. bool mouse_invert_tilt = false;
  695. bool mouse_invert_pan = false;
  696. bool mouse_look_toggle = false;
  697. float gamepad_tilt_sensitivity = 1.0f;
  698. float gamepad_pan_sensitivity = 1.0f;
  699. bool gamepad_invert_tilt = false;
  700. bool gamepad_invert_pan = false;
  701. // Read control settings
  702. if (ctx.config->contains("mouse_tilt_sensitivity"))
  703. mouse_tilt_sensitivity = math::radians((*ctx.config)["mouse_tilt_sensitivity"].get<float>());
  704. if (ctx.config->contains("mouse_pan_sensitivity"))
  705. mouse_pan_sensitivity = math::radians((*ctx.config)["mouse_pan_sensitivity"].get<float>());
  706. if (ctx.config->contains("mouse_invert_tilt"))
  707. mouse_invert_tilt = (*ctx.config)["mouse_invert_tilt"].get<bool>();
  708. if (ctx.config->contains("mouse_invert_pan"))
  709. mouse_invert_pan = (*ctx.config)["mouse_invert_pan"].get<bool>();
  710. if (ctx.config->contains("mouse_look_toggle"))
  711. mouse_look_toggle = (*ctx.config)["mouse_look_toggle"].get<bool>();
  712. if (ctx.config->contains("gamepad_tilt_sensitivity"))
  713. gamepad_tilt_sensitivity = math::radians((*ctx.config)["gamepad_tilt_sensitivity"].get<float>());
  714. if (ctx.config->contains("gamepad_pan_sensitivity"))
  715. gamepad_pan_sensitivity = math::radians((*ctx.config)["gamepad_pan_sensitivity"].get<float>());
  716. if (ctx.config->contains("gamepad_invert_tilt"))
  717. gamepad_invert_tilt = (*ctx.config)["gamepad_invert_tilt"].get<bool>();
  718. if (ctx.config->contains("gamepad_invert_pan"))
  719. gamepad_invert_pan = (*ctx.config)["gamepad_invert_pan"].get<bool>();
  720. // Determine tilt and pan factors according to sensitivity and inversion
  721. const float mouse_tilt_factor = mouse_tilt_sensitivity * (mouse_invert_tilt ? -1.0f : 1.0f);
  722. const float mouse_pan_factor = mouse_pan_sensitivity * (mouse_invert_pan ? -1.0f : 1.0f);
  723. const float gamepad_tilt_factor = gamepad_tilt_sensitivity * (gamepad_invert_tilt ? -1.0f : 1.0f);
  724. const float gamepad_pan_factor = gamepad_pan_sensitivity * (gamepad_invert_pan ? -1.0f : 1.0f);
  725. ctx.controls["look_right_gamepad"]->set_active_callback
  726. (
  727. [&, gamepad_pan_factor](float value)
  728. {
  729. ctx.entity_registry->patch<spring_rotation_constraint>
  730. (
  731. first_person_camera_rig_spring_rotation_eid,
  732. [&, gamepad_pan_factor](auto& component)
  733. {
  734. component.spring.x1[0] -= gamepad_pan_factor * value * static_cast<float>(1.0 / ctx.fixed_update_rate);
  735. }
  736. );
  737. }
  738. );
  739. ctx.controls["look_left_gamepad"]->set_active_callback
  740. (
  741. [&, gamepad_pan_factor](float value)
  742. {
  743. ctx.entity_registry->patch<spring_rotation_constraint>
  744. (
  745. first_person_camera_rig_spring_rotation_eid,
  746. [&, gamepad_pan_factor](auto& component)
  747. {
  748. component.spring.x1[0] += gamepad_pan_factor * value * static_cast<float>(1.0 / ctx.fixed_update_rate);
  749. }
  750. );
  751. }
  752. );
  753. ctx.controls["look_up_gamepad"]->set_active_callback
  754. (
  755. [&, gamepad_tilt_factor](float value)
  756. {
  757. ctx.entity_registry->patch<spring_rotation_constraint>
  758. (
  759. first_person_camera_rig_spring_rotation_eid,
  760. [&, gamepad_tilt_factor](auto& component)
  761. {
  762. component.spring.x1[1] -= gamepad_tilt_factor * value * static_cast<float>(1.0 / ctx.fixed_update_rate);
  763. component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]);
  764. }
  765. );
  766. }
  767. );
  768. ctx.controls["look_down_gamepad"]->set_active_callback
  769. (
  770. [&, gamepad_tilt_factor](float value)
  771. {
  772. ctx.entity_registry->patch<spring_rotation_constraint>
  773. (
  774. first_person_camera_rig_spring_rotation_eid,
  775. [&, gamepad_tilt_factor](auto& component)
  776. {
  777. component.spring.x1[1] += gamepad_tilt_factor * value * static_cast<float>(1.0 / ctx.fixed_update_rate);
  778. component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]);
  779. }
  780. );
  781. }
  782. );
  783. // Pedestal up control
  784. ctx.controls["move_up"]->set_active_callback
  785. (
  786. [&](float value)
  787. {
  788. set_first_person_camera_rig_pedestal(std::min(1.0f, first_person_camera_rig_pedestal + first_person_camera_rig_pedestal_speed * static_cast<float>(1.0 / ctx.fixed_update_rate)));
  789. }
  790. );
  791. // Pedestal down control
  792. ctx.controls["move_down"]->set_active_callback
  793. (
  794. [&](float value)
  795. {
  796. set_first_person_camera_rig_pedestal(std::max(0.0f, first_person_camera_rig_pedestal - first_person_camera_rig_pedestal_speed * static_cast<float>(1.0 / ctx.fixed_update_rate)));
  797. }
  798. );
  799. // Fast-forward
  800. ctx.controls["fast_forward"]->set_activated_callback
  801. (
  802. [&ctx = this->ctx, ff_time_scale]()
  803. {
  804. ::world::set_time_scale(ctx, ff_time_scale);
  805. }
  806. );
  807. ctx.controls["fast_forward"]->set_deactivated_callback
  808. (
  809. [&ctx = this->ctx, time_scale]()
  810. {
  811. ::world::set_time_scale(ctx, time_scale);
  812. }
  813. );
  814. ctx.controls["rewind"]->set_activated_callback
  815. (
  816. [&ctx = this->ctx, ff_time_scale]()
  817. {
  818. ::world::set_time_scale(ctx, -ff_time_scale);
  819. }
  820. );
  821. ctx.controls["rewind"]->set_deactivated_callback
  822. (
  823. [&ctx = this->ctx, time_scale]()
  824. {
  825. ::world::set_time_scale(ctx, time_scale);
  826. }
  827. );
  828. */
  829. }
  830. void nest_selection_state::disable_controls()
  831. {
  832. }