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

757 lines
26 KiB

1 year ago
1 year ago
  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/state/nest-selection.hpp"
  20. #include "game/state/pause-menu.hpp"
  21. #include "entity/archetype.hpp"
  22. #include "game/system/camera.hpp"
  23. #include "game/system/astronomy.hpp"
  24. #include "game/system/atmosphere.hpp"
  25. #include "game/system/collision.hpp"
  26. #include "game/component/locomotion.hpp"
  27. #include "game/component/transform.hpp"
  28. #include "game/component/terrain.hpp"
  29. #include "game/component/camera.hpp"
  30. #include "game/component/model.hpp"
  31. #include "game/component/constraint/constraint.hpp"
  32. #include "game/component/constraint-stack.hpp"
  33. #include "game/component/steering.hpp"
  34. #include "game/component/picking.hpp"
  35. #include "game/component/spring.hpp"
  36. #include "game/controls.hpp"
  37. #include "entity/commands.hpp"
  38. #include "animation/screen-transition.hpp"
  39. #include "animation/ease.hpp"
  40. #include "resources/resource-manager.hpp"
  41. #include "game/world.hpp"
  42. #include "application.hpp"
  43. #include "render/passes/clear-pass.hpp"
  44. #include "render/passes/ground-pass.hpp"
  45. #include "state-machine.hpp"
  46. #include "config.hpp"
  47. #include "math/interpolation.hpp"
  48. #include "physics/light/exposure.hpp"
  49. #include "application.hpp"
  50. #include "input/mouse.hpp"
  51. #include "math/projection.hpp"
  52. #include "game/ant/morphogenesis.hpp"
  53. #include "game/ant/phenome.hpp"
  54. #include "game/ant/genome.hpp"
  55. #include "game/ant/cladogenesis.hpp"
  56. #include "game/spawn.hpp"
  57. using namespace game::ant;
  58. namespace game {
  59. namespace state {
  60. nest_selection::nest_selection(game::context& ctx):
  61. game::state::base(ctx)
  62. {
  63. debug::log::trace("Entering nest selection state...");
  64. debug::log::trace("Generating genome...");
  65. std::random_device rng;
  66. ant::genome* genome = ant::cladogenesis(ctx.active_ecoregion->gene_pools[0], rng);
  67. debug::log::trace("Generated genome");
  68. debug::log::trace("Building worker phenome...");
  69. ant::phenome worker_phenome = ant::phenome(*genome, ant::caste::worker);
  70. debug::log::trace("Built worker phenome...");
  71. debug::log::trace("Generating worker model...");
  72. render::model* worker_model = ant::morphogenesis(worker_phenome);
  73. debug::log::trace("Generated worker model");
  74. // Create worker entity(s)
  75. entity::id worker_eid = ctx.entity_registry->create();
  76. component::transform worker_transform_component;
  77. worker_transform_component.local = math::transform<float>::identity;
  78. worker_transform_component.local.translation = {0, 0, -20};
  79. worker_transform_component.world = worker_transform_component.local;
  80. worker_transform_component.warp = true;
  81. ctx.entity_registry->emplace<component::transform>(worker_eid, worker_transform_component);
  82. component::model worker_model_component;
  83. worker_model_component.render_model = worker_model;
  84. worker_model_component.instance_count = 0;
  85. worker_model_component.layers = ~0;
  86. ctx.entity_registry->emplace<component::model>(worker_eid, worker_model_component);
  87. // Disable UI color clear
  88. ctx.ui_clear_pass->set_cleared_buffers(false, true, false);
  89. // Create world if not yet created
  90. if (ctx.entities.find("earth") == ctx.entities.end())
  91. {
  92. // Create cosmos
  93. game::world::cosmogenesis(ctx);
  94. // Create observer
  95. game::world::create_observer(ctx);
  96. }
  97. // Init time scale
  98. double time_scale = 60.0;
  99. // Set time scale
  100. game::world::set_time_scale(ctx, time_scale);
  101. // Setup and enable sky and ground passes
  102. ctx.sky_pass->set_enabled(true);
  103. ctx.ground_pass->set_enabled(true);
  104. // Switch to surface camera
  105. ctx.underground_camera->set_active(false);
  106. ctx.surface_camera->set_active(true);
  107. // Set camera exposure
  108. const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
  109. ctx.surface_camera->set_exposure(ev100_sunny16);
  110. const auto& viewport_size = ctx.app->get_viewport_size();
  111. const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
  112. // Init first person camera rig parameters
  113. first_person_camera_rig_translation_spring_angular_frequency = period_to_rads(0.125f);
  114. first_person_camera_rig_rotation_spring_angular_frequency = period_to_rads(0.125f);
  115. first_person_camera_rig_fov_spring_angular_frequency = period_to_rads(0.125f);
  116. first_person_camera_rig_min_elevation = 0.25f;
  117. first_person_camera_rig_max_elevation = 150.0f;
  118. first_person_camera_near_fov = math::vertical_fov(math::radians(100.0f), aspect_ratio);
  119. first_person_camera_far_fov = math::vertical_fov(math::radians(60.0f), aspect_ratio);
  120. first_person_camera_near_speed = 5.0f;
  121. first_person_camera_far_speed = 140.0f;
  122. first_person_camera_rig_pedestal_speed = 2.0f;
  123. first_person_camera_rig_pedestal = 0.0f;
  124. // Create first person camera rig
  125. create_first_person_camera_rig();
  126. // Satisfy first person camera rig constraints
  127. satisfy_first_person_camera_rig_constraints();
  128. // auto color_checker_archetype = ctx.resource_manager->load<entity::archetype>("color-checker.ent");
  129. // color_checker_archetype->create(*ctx.entity_registry);
  130. // auto ruler_archetype = ctx.resource_manager->load<entity::archetype>("ruler-10cm.ent");
  131. // ruler_archetype->create(*ctx.entity_registry);
  132. auto yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-l.ent");
  133. auto yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  134. entity::command::warp_to(*ctx.entity_registry, yucca_eid, {0, 4, 30});
  135. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-m.ent");
  136. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  137. entity::command::warp_to(*ctx.entity_registry, yucca_eid, {400, 0, 200});
  138. yucca_archetype = ctx.resource_manager->load<entity::archetype>("yucca-plant-s.ent");
  139. yucca_eid = yucca_archetype->create(*ctx.entity_registry);
  140. entity::command::warp_to(*ctx.entity_registry, yucca_eid, {-300, 3, -300});
  141. auto cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-l.ent");
  142. auto cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  143. entity::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {-100, 0, -200});
  144. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-m.ent");
  145. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  146. entity::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {100, -2, -70});
  147. cactus_plant_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-plant-s.ent");
  148. cactus_plant_eid = cactus_plant_archetype->create(*ctx.entity_registry);
  149. entity::command::warp_to(*ctx.entity_registry, cactus_plant_eid, {50, 2, 80});
  150. auto cactus_seed_archetype = ctx.resource_manager->load<entity::archetype>("barrel-cactus-seed.ent");
  151. auto cactus_seed_eid = cactus_seed_archetype->create(*ctx.entity_registry);
  152. entity::command::warp_to(*ctx.entity_registry, cactus_seed_eid, {10, 5, 10});
  153. // Queue control setup
  154. ctx.function_queue.push(std::bind(&nest_selection::enable_controls, this));
  155. debug::log::trace("Entered nest selection state");
  156. }
  157. nest_selection::~nest_selection()
  158. {
  159. debug::log::trace("Exiting nest selection state...");
  160. destroy_first_person_camera_rig();
  161. debug::log::trace("Exited nest selection state");
  162. }
  163. void nest_selection::create_first_person_camera_rig()
  164. {
  165. // Construct first person camera rig spring rotation constraint
  166. component::constraint::spring_rotation first_person_camera_rig_spring_rotation;
  167. first_person_camera_rig_spring_rotation.spring =
  168. {
  169. {0.0f, 0.0f, 0.0f},
  170. {0.0f, 0.0f, 0.0f},
  171. {0.0f, 0.0f, 0.0f},
  172. 1.0f,
  173. first_person_camera_rig_rotation_spring_angular_frequency
  174. };
  175. component::constraint_stack_node first_person_camera_rig_spring_rotation_node;
  176. first_person_camera_rig_spring_rotation_node.active = true;
  177. first_person_camera_rig_spring_rotation_node.weight = 1.0f;
  178. first_person_camera_rig_spring_rotation_node.next = entt::null;
  179. first_person_camera_rig_spring_rotation_eid = ctx.entity_registry->create();
  180. ctx.entity_registry->emplace<component::constraint::spring_rotation>(first_person_camera_rig_spring_rotation_eid, first_person_camera_rig_spring_rotation);
  181. ctx.entity_registry->emplace<component::constraint_stack_node>(first_person_camera_rig_spring_rotation_eid, first_person_camera_rig_spring_rotation_node);
  182. // Construct first person camera rig spring translation constraint
  183. component::constraint::spring_translation first_person_camera_rig_spring_translation;
  184. first_person_camera_rig_spring_translation.spring =
  185. {
  186. {0.0f, 0.0f, 0.0f},
  187. {0.0f, 0.0f, 0.0f},
  188. {0.0f, 0.0f, 0.0f},
  189. 1.0f,
  190. first_person_camera_rig_translation_spring_angular_frequency
  191. };
  192. component::constraint_stack_node first_person_camera_rig_spring_translation_node;
  193. first_person_camera_rig_spring_translation_node.active = true;
  194. first_person_camera_rig_spring_translation_node.weight = 1.0f;
  195. first_person_camera_rig_spring_translation_node.next = first_person_camera_rig_spring_rotation_eid;
  196. first_person_camera_rig_spring_translation_eid = ctx.entity_registry->create();
  197. ctx.entity_registry->emplace<component::constraint::spring_translation>(first_person_camera_rig_spring_translation_eid, first_person_camera_rig_spring_translation);
  198. ctx.entity_registry->emplace<component::constraint_stack_node>(first_person_camera_rig_spring_translation_eid, first_person_camera_rig_spring_translation_node);
  199. // Construct first person camera rig constraint stack
  200. component::constraint_stack first_person_camera_rig_constraint_stack;
  201. first_person_camera_rig_constraint_stack.priority = 2;
  202. first_person_camera_rig_constraint_stack.head = first_person_camera_rig_spring_translation_eid;
  203. // Construct first person camera rig transform component
  204. component::transform first_person_camera_rig_transform;
  205. first_person_camera_rig_transform.local = math::transform<float>::identity;
  206. first_person_camera_rig_transform.world = first_person_camera_rig_transform.local;
  207. first_person_camera_rig_transform.warp = true;
  208. // Construct first person camera rig camera component
  209. component::camera first_person_camera_rig_camera;
  210. first_person_camera_rig_camera.object = ctx.surface_camera;
  211. // Construct first person camera rig entity
  212. first_person_camera_rig_eid = ctx.entity_registry->create();
  213. ctx.entity_registry->emplace<component::camera>(first_person_camera_rig_eid, first_person_camera_rig_camera);
  214. ctx.entity_registry->emplace<component::transform>(first_person_camera_rig_eid, first_person_camera_rig_transform);
  215. ctx.entity_registry->emplace<component::constraint_stack>(first_person_camera_rig_eid, first_person_camera_rig_constraint_stack);
  216. // Construct first person camera rig fov spring
  217. component::spring1 first_person_camera_rig_fov_spring;
  218. first_person_camera_rig_fov_spring.spring =
  219. {
  220. 0.0f,
  221. 0.0f,
  222. 0.0f,
  223. 1.0f,
  224. first_person_camera_rig_fov_spring_angular_frequency
  225. };
  226. first_person_camera_rig_fov_spring.callback = [&](float fov)
  227. {
  228. ctx.surface_camera->set_perspective(fov, ctx.surface_camera->get_aspect_ratio(), ctx.surface_camera->get_clip_near(), ctx.surface_camera->get_clip_far());
  229. };
  230. // Construct first person camera rig fov spring entity
  231. first_person_camera_rig_fov_spring_eid = ctx.entity_registry->create();
  232. ctx.entity_registry->emplace<component::spring1>(first_person_camera_rig_fov_spring_eid, first_person_camera_rig_fov_spring);
  233. set_first_person_camera_rig_pedestal(first_person_camera_rig_pedestal);
  234. }
  235. void nest_selection::destroy_first_person_camera_rig()
  236. {
  237. ctx.entity_registry->destroy(first_person_camera_rig_eid);
  238. ctx.entity_registry->destroy(first_person_camera_rig_spring_translation_eid);
  239. ctx.entity_registry->destroy(first_person_camera_rig_spring_rotation_eid);
  240. ctx.entity_registry->destroy(first_person_camera_rig_fov_spring_eid);
  241. }
  242. void nest_selection::set_first_person_camera_rig_pedestal(float pedestal)
  243. {
  244. first_person_camera_rig_pedestal = pedestal;
  245. const float elevation = math::log_lerp(first_person_camera_rig_min_elevation, first_person_camera_rig_max_elevation, first_person_camera_rig_pedestal);
  246. const float fov = math::log_lerp(first_person_camera_near_fov, first_person_camera_far_fov, first_person_camera_rig_pedestal);
  247. ctx.entity_registry->patch<component::constraint::spring_translation>
  248. (
  249. first_person_camera_rig_spring_translation_eid,
  250. [&](auto& component)
  251. {
  252. component.spring.x1[1] = elevation;
  253. }
  254. );
  255. ctx.entity_registry->patch<component::spring1>
  256. (
  257. first_person_camera_rig_fov_spring_eid,
  258. [&](auto& component)
  259. {
  260. component.spring.x1 = fov;
  261. }
  262. );
  263. }
  264. void nest_selection::move_first_person_camera_rig(const float2& direction, float factor)
  265. {
  266. const float speed = math::log_lerp(first_person_camera_near_speed, first_person_camera_far_speed, first_person_camera_rig_pedestal) * factor;
  267. const component::constraint::spring_rotation& first_person_camera_rig_spring_rotation = ctx.entity_registry->get<component::constraint::spring_rotation>(first_person_camera_rig_spring_rotation_eid);
  268. const math::quaternion<float> yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], float3{0.0f, 1.0f, 0.0f});
  269. const float3 rotated_direction = math::normalize(yaw_rotation * float3{direction[0], 0.0f, direction[1]});
  270. const float3 velocity = rotated_direction * speed;
  271. ctx.entity_registry->patch<component::constraint::spring_translation>
  272. (
  273. first_person_camera_rig_spring_translation_eid,
  274. [&](auto& component)
  275. {
  276. component.spring.x1 += velocity * static_cast<float>(ctx.loop.get_update_period());
  277. }
  278. );
  279. }
  280. void nest_selection::satisfy_first_person_camera_rig_constraints()
  281. {
  282. // Satisfy first person camera rig spring translation constraint
  283. ctx.entity_registry->patch<component::constraint::spring_translation>
  284. (
  285. first_person_camera_rig_spring_translation_eid,
  286. [&](auto& component)
  287. {
  288. component.spring.x0 = component.spring.x1;
  289. component.spring.v *= 0.0f;
  290. }
  291. );
  292. // Satisfy first person camera rig spring rotation constraint
  293. ctx.entity_registry->patch<component::constraint::spring_rotation>
  294. (
  295. first_person_camera_rig_spring_rotation_eid,
  296. [&](auto& component)
  297. {
  298. component.spring.x0 = component.spring.x1;
  299. component.spring.v *= 0.0f;
  300. }
  301. );
  302. // Satisfy first person camera rig fov spring
  303. ctx.entity_registry->patch<component::spring1>
  304. (
  305. first_person_camera_rig_fov_spring_eid,
  306. [&](auto& component)
  307. {
  308. component.spring.x0 = component.spring.x1;
  309. component.spring.v *= 0.0f;
  310. }
  311. );
  312. }
  313. void nest_selection::enable_controls()
  314. {
  315. /*
  316. // Reset mouse look
  317. mouse_look = false;
  318. double time_scale = 0.0;
  319. double ff_time_scale = 60.0 * 200.0;
  320. // Init control settings
  321. float mouse_tilt_sensitivity = 1.0f;
  322. float mouse_pan_sensitivity = 1.0f;
  323. bool mouse_invert_tilt = false;
  324. bool mouse_invert_pan = false;
  325. bool mouse_look_toggle = false;
  326. float gamepad_tilt_sensitivity = 1.0f;
  327. float gamepad_pan_sensitivity = 1.0f;
  328. bool gamepad_invert_tilt = false;
  329. bool gamepad_invert_pan = false;
  330. // Read control settings
  331. if (ctx.config->contains("mouse_tilt_sensitivity"))
  332. mouse_tilt_sensitivity = math::radians((*ctx.config)["mouse_tilt_sensitivity"].get<float>());
  333. if (ctx.config->contains("mouse_pan_sensitivity"))
  334. mouse_pan_sensitivity = math::radians((*ctx.config)["mouse_pan_sensitivity"].get<float>());
  335. if (ctx.config->contains("mouse_invert_tilt"))
  336. mouse_invert_tilt = (*ctx.config)["mouse_invert_tilt"].get<bool>();
  337. if (ctx.config->contains("mouse_invert_pan"))
  338. mouse_invert_pan = (*ctx.config)["mouse_invert_pan"].get<bool>();
  339. if (ctx.config->contains("mouse_look_toggle"))
  340. mouse_look_toggle = (*ctx.config)["mouse_look_toggle"].get<bool>();
  341. if (ctx.config->contains("gamepad_tilt_sensitivity"))
  342. gamepad_tilt_sensitivity = math::radians((*ctx.config)["gamepad_tilt_sensitivity"].get<float>());
  343. if (ctx.config->contains("gamepad_pan_sensitivity"))
  344. gamepad_pan_sensitivity = math::radians((*ctx.config)["gamepad_pan_sensitivity"].get<float>());
  345. if (ctx.config->contains("gamepad_invert_tilt"))
  346. gamepad_invert_tilt = (*ctx.config)["gamepad_invert_tilt"].get<bool>();
  347. if (ctx.config->contains("gamepad_invert_pan"))
  348. gamepad_invert_pan = (*ctx.config)["gamepad_invert_pan"].get<bool>();
  349. // Determine tilt and pan factors according to sensitivity and inversion
  350. const float mouse_tilt_factor = mouse_tilt_sensitivity * (mouse_invert_tilt ? -1.0f : 1.0f);
  351. const float mouse_pan_factor = mouse_pan_sensitivity * (mouse_invert_pan ? -1.0f : 1.0f);
  352. const float gamepad_tilt_factor = gamepad_tilt_sensitivity * (gamepad_invert_tilt ? -1.0f : 1.0f);
  353. const float gamepad_pan_factor = gamepad_pan_sensitivity * (gamepad_invert_pan ? -1.0f : 1.0f);
  354. // Mouse look control
  355. ctx.controls["mouse_look"]->set_activated_callback
  356. (
  357. [&, mouse_look_toggle]()
  358. {
  359. if (mouse_look_toggle)
  360. mouse_look = !mouse_look;
  361. else
  362. mouse_look = true;
  363. ctx.app->set_relative_mouse_mode(mouse_look);
  364. }
  365. );
  366. ctx.controls["mouse_look"]->set_deactivated_callback
  367. (
  368. [&, mouse_look_toggle]()
  369. {
  370. if (!mouse_look_toggle && mouse_look)
  371. {
  372. mouse_look = false;
  373. ctx.app->set_relative_mouse_mode(false);
  374. }
  375. }
  376. );
  377. // Look right control
  378. ctx.controls["look_right_mouse"]->set_active_callback
  379. (
  380. [&, mouse_pan_factor](float value)
  381. {
  382. if (!mouse_look)
  383. return;
  384. ctx.entity_registry->patch<component::constraint::spring_rotation>
  385. (
  386. first_person_camera_rig_spring_rotation_eid,
  387. [&, mouse_pan_factor](auto& component)
  388. {
  389. component.spring.x1[0] -= mouse_pan_factor * value;
  390. }
  391. );
  392. }
  393. );
  394. ctx.controls["look_right_gamepad"]->set_active_callback
  395. (
  396. [&, gamepad_pan_factor](float value)
  397. {
  398. ctx.entity_registry->patch<component::constraint::spring_rotation>
  399. (
  400. first_person_camera_rig_spring_rotation_eid,
  401. [&, gamepad_pan_factor](auto& component)
  402. {
  403. component.spring.x1[0] -= gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period());
  404. }
  405. );
  406. }
  407. );
  408. // Look left control
  409. ctx.controls["look_left_mouse"]->set_active_callback
  410. (
  411. [&, mouse_pan_factor](float value)
  412. {
  413. if (!mouse_look)
  414. return;
  415. ctx.entity_registry->patch<component::constraint::spring_rotation>
  416. (
  417. first_person_camera_rig_spring_rotation_eid,
  418. [&, mouse_pan_factor](auto& component)
  419. {
  420. component.spring.x1[0] += mouse_pan_factor * value;
  421. }
  422. );
  423. }
  424. );
  425. ctx.controls["look_left_gamepad"]->set_active_callback
  426. (
  427. [&, gamepad_pan_factor](float value)
  428. {
  429. ctx.entity_registry->patch<component::constraint::spring_rotation>
  430. (
  431. first_person_camera_rig_spring_rotation_eid,
  432. [&, gamepad_pan_factor](auto& component)
  433. {
  434. component.spring.x1[0] += gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period());
  435. }
  436. );
  437. }
  438. );
  439. // Look up control
  440. ctx.controls["look_up_mouse"]->set_active_callback
  441. (
  442. [&, mouse_tilt_factor](float value)
  443. {
  444. if (!mouse_look)
  445. return;
  446. ctx.entity_registry->patch<component::constraint::spring_rotation>
  447. (
  448. first_person_camera_rig_spring_rotation_eid,
  449. [&, mouse_tilt_factor](auto& component)
  450. {
  451. component.spring.x1[1] -= mouse_tilt_factor * value;
  452. component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]);
  453. }
  454. );
  455. }
  456. );
  457. ctx.controls["look_up_gamepad"]->set_active_callback
  458. (
  459. [&, gamepad_tilt_factor](float value)
  460. {
  461. ctx.entity_registry->patch<component::constraint::spring_rotation>
  462. (
  463. first_person_camera_rig_spring_rotation_eid,
  464. [&, gamepad_tilt_factor](auto& component)
  465. {
  466. component.spring.x1[1] -= gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period());
  467. component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]);
  468. }
  469. );
  470. }
  471. );
  472. // Look down control
  473. ctx.controls["look_down_mouse"]->set_active_callback
  474. (
  475. [&, mouse_tilt_factor](float value)
  476. {
  477. if (!mouse_look)
  478. return;
  479. ctx.entity_registry->patch<component::constraint::spring_rotation>
  480. (
  481. first_person_camera_rig_spring_rotation_eid,
  482. [&, mouse_tilt_factor](auto& component)
  483. {
  484. component.spring.x1[1] += mouse_tilt_factor * value;
  485. component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]);
  486. }
  487. );
  488. }
  489. );
  490. ctx.controls["look_down_gamepad"]->set_active_callback
  491. (
  492. [&, gamepad_tilt_factor](float value)
  493. {
  494. ctx.entity_registry->patch<component::constraint::spring_rotation>
  495. (
  496. first_person_camera_rig_spring_rotation_eid,
  497. [&, gamepad_tilt_factor](auto& component)
  498. {
  499. component.spring.x1[1] += gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period());
  500. component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]);
  501. }
  502. );
  503. }
  504. );
  505. // Pedestal up control
  506. ctx.controls["move_up"]->set_active_callback
  507. (
  508. [&](float value)
  509. {
  510. set_first_person_camera_rig_pedestal(std::min(1.0f, first_person_camera_rig_pedestal + first_person_camera_rig_pedestal_speed * static_cast<float>(ctx.loop.get_update_period())));
  511. }
  512. );
  513. // Pedestal down control
  514. ctx.controls["move_down"]->set_active_callback
  515. (
  516. [&](float value)
  517. {
  518. set_first_person_camera_rig_pedestal(std::max(0.0f, first_person_camera_rig_pedestal - first_person_camera_rig_pedestal_speed * static_cast<float>(ctx.loop.get_update_period())));
  519. }
  520. );
  521. // Mouse select control
  522. ctx.controls["select_mouse"]->set_activated_callback
  523. (
  524. [&]()
  525. {
  526. }
  527. );
  528. // Move forward control
  529. ctx.controls["move_forward"]->set_active_callback
  530. (
  531. [&](float value)
  532. {
  533. move_first_person_camera_rig({0, -1}, value);
  534. }
  535. );
  536. // Move back control
  537. ctx.controls["move_back"]->set_active_callback
  538. (
  539. [&](float value)
  540. {
  541. move_first_person_camera_rig({0, 1}, value);
  542. }
  543. );
  544. // Move right control
  545. ctx.controls["move_right"]->set_active_callback
  546. (
  547. [&](float value)
  548. {
  549. move_first_person_camera_rig({1, 0}, value);
  550. }
  551. );
  552. // Move left control
  553. ctx.controls["move_left"]->set_active_callback
  554. (
  555. [&](float value)
  556. {
  557. move_first_person_camera_rig({-1, 0}, value);
  558. }
  559. );
  560. // Action control
  561. ctx.controls["action"]->set_activated_callback
  562. (
  563. [&]()
  564. {
  565. }
  566. );
  567. // Fast-forward
  568. ctx.controls["fast_forward"]->set_activated_callback
  569. (
  570. [&ctx = this->ctx, ff_time_scale]()
  571. {
  572. game::world::set_time_scale(ctx, ff_time_scale);
  573. }
  574. );
  575. ctx.controls["fast_forward"]->set_deactivated_callback
  576. (
  577. [&ctx = this->ctx, time_scale]()
  578. {
  579. game::world::set_time_scale(ctx, time_scale);
  580. }
  581. );
  582. ctx.controls["rewind"]->set_activated_callback
  583. (
  584. [&ctx = this->ctx, ff_time_scale]()
  585. {
  586. game::world::set_time_scale(ctx, -ff_time_scale);
  587. }
  588. );
  589. ctx.controls["rewind"]->set_deactivated_callback
  590. (
  591. [&ctx = this->ctx, time_scale]()
  592. {
  593. game::world::set_time_scale(ctx, time_scale);
  594. }
  595. );
  596. // Setup pause control
  597. ctx.controls["pause"]->set_activated_callback
  598. (
  599. [this, &ctx = this->ctx]()
  600. {
  601. // Disable controls
  602. this->disable_controls();
  603. // Set resume callback
  604. ctx.resume_callback = [this, &ctx]()
  605. {
  606. this->enable_controls();
  607. ctx.resume_callback = nullptr;
  608. };
  609. // Push pause menu state
  610. ctx.state_machine.emplace(new game::state::pause_menu(ctx));
  611. }
  612. );
  613. ctx.controls["increase_exposure"]->set_active_callback
  614. (
  615. [&ctx = this->ctx](float)
  616. {
  617. //ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() - 1.0f);
  618. ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 2.0f * static_cast<float>(ctx.loop.get_update_period()));
  619. debug::log::info("EV100: " + std::to_string(ctx.surface_camera->get_exposure()));
  620. }
  621. );
  622. ctx.controls["decrease_exposure"]->set_active_callback
  623. (
  624. [&ctx = this->ctx](float)
  625. {
  626. //ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() + 1.0f);
  627. ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 2.0f * static_cast<float>(ctx.loop.get_update_period()));
  628. debug::log::info("EV100: " + std::to_string(ctx.surface_camera->get_exposure()));
  629. }
  630. );
  631. */
  632. }
  633. void nest_selection::disable_controls()
  634. {
  635. /*
  636. if (mouse_look)
  637. {
  638. mouse_look = false;
  639. ctx.app->set_relative_mouse_mode(false);
  640. }
  641. ctx.controls["mouse_look"]->set_activated_callback(nullptr);
  642. ctx.controls["mouse_look"]->set_deactivated_callback(nullptr);
  643. ctx.controls["look_right_mouse"]->set_active_callback(nullptr);
  644. ctx.controls["look_right_gamepad"]->set_active_callback(nullptr);
  645. ctx.controls["look_left_mouse"]->set_active_callback(nullptr);
  646. ctx.controls["look_left_gamepad"]->set_active_callback(nullptr);
  647. ctx.controls["look_up_mouse"]->set_active_callback(nullptr);
  648. ctx.controls["look_up_gamepad"]->set_active_callback(nullptr);
  649. ctx.controls["look_down_mouse"]->set_active_callback(nullptr);
  650. ctx.controls["look_down_gamepad"]->set_active_callback(nullptr);
  651. ctx.controls["move_up"]->set_active_callback(nullptr);
  652. ctx.controls["move_down"]->set_active_callback(nullptr);
  653. ctx.controls["select_mouse"]->set_activated_callback(nullptr);
  654. ctx.controls["move_forward"]->set_active_callback(nullptr);
  655. ctx.controls["move_back"]->set_active_callback(nullptr);
  656. ctx.controls["move_right"]->set_active_callback(nullptr);
  657. ctx.controls["move_left"]->set_active_callback(nullptr);
  658. ctx.controls["action"]->set_activated_callback(nullptr);
  659. ctx.controls["fast_forward"]->set_activated_callback(nullptr);
  660. ctx.controls["fast_forward"]->set_deactivated_callback(nullptr);
  661. ctx.controls["rewind"]->set_activated_callback(nullptr);
  662. ctx.controls["rewind"]->set_deactivated_callback(nullptr);
  663. ctx.controls["pause"]->set_activated_callback(nullptr);
  664. ctx.controls["increase_exposure"]->set_active_callback(nullptr);
  665. ctx.controls["decrease_exposure"]->set_active_callback(nullptr);
  666. */
  667. }
  668. } // namespace state
  669. } // namespace game