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

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