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

784 lines
26 KiB

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