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

417 lines
14 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/states/brood.hpp"
  20. #include "entity/archetype.hpp"
  21. #include "entity/commands.hpp"
  22. #include "entity/components/observer.hpp"
  23. #include "entity/components/camera.hpp"
  24. #include "entity/components/terrain.hpp"
  25. #include "entity/components/transform.hpp"
  26. #include "entity/components/chamber.hpp"
  27. #include "entity/components/constraints/spring-to.hpp"
  28. #include "entity/components/constraints/three-dof.hpp"
  29. #include "entity/components/constraint-stack.hpp"
  30. #include "animation/screen-transition.hpp"
  31. #include "animation/ease.hpp"
  32. #include "resources/resource-manager.hpp"
  33. #include "renderer/passes/sky-pass.hpp"
  34. #include "application.hpp"
  35. #include <iostream>
  36. namespace game {
  37. namespace state {
  38. namespace brood {
  39. static void setup_nest(game::context* ctx);
  40. static void setup_ants(game::context* ctx);
  41. static void setup_camera(game::context* ctx);
  42. static void setup_controls(game::context* ctx);
  43. void enter(game::context* ctx)
  44. {
  45. setup_nest(ctx);
  46. setup_ants(ctx);
  47. setup_camera(ctx);
  48. setup_controls(ctx);
  49. ctx->underground_ambient_light->set_intensity(1.0f);
  50. // Create larva
  51. {
  52. entity::archetype* larva_archetype = ctx->resource_manager->load<entity::archetype>("ant-larva.ent");
  53. auto larva_eid = larva_archetype->create(*ctx->entity_registry);
  54. entity::command::warp_to(*ctx->entity_registry, larva_eid, {0.0f, 0.0f, 0.0f});
  55. entity::command::assign_render_layers(*ctx->entity_registry, larva_eid, 0b1);
  56. entity::command::rename(*ctx->entity_registry, larva_eid, "larva");
  57. }
  58. // Create cocoon
  59. {
  60. entity::archetype* cocoon_archetype = ctx->resource_manager->load<entity::archetype>("ant-cocoon.ent");
  61. auto cocoon_eid = cocoon_archetype->create(*ctx->entity_registry);
  62. entity::command::warp_to(*ctx->entity_registry, cocoon_eid, {-50, 0.1935f, 0});
  63. entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b1);
  64. entity::command::rename(*ctx->entity_registry, cocoon_eid, "cocoon");
  65. }
  66. // Reset tweening
  67. ctx->underground_scene->update_tweens();
  68. // Start fade in
  69. ctx->fade_transition->transition(1.0f, true, ease<float>::in_quad);
  70. }
  71. void exit(game::context* ctx)
  72. {}
  73. void setup_nest(game::context* ctx)
  74. {
  75. // Find or create nest central shaft entity
  76. entity::id shaft_eid = entity::command::find(*ctx->entity_registry, "shaft");
  77. if (shaft_eid == entt::null)
  78. {
  79. shaft_eid = entity::command::create(*ctx->entity_registry, "shaft");
  80. entity::component::transform transform;
  81. transform.local = math::identity_transform<float>;
  82. transform.world = transform.local;
  83. transform.warp = true;
  84. ctx->entity_registry->assign<entity::component::transform>(shaft_eid, transform);
  85. }
  86. // Find or create nest lobby chamber entity
  87. entity::id lobby_eid = entity::command::find(*ctx->entity_registry, "lobby");
  88. if (lobby_eid == entt::null)
  89. {
  90. lobby_eid = entity::command::create(*ctx->entity_registry, "lobby");
  91. entity::component::chamber chamber;
  92. chamber.shaft_eid = shaft_eid;
  93. chamber.distance = 10.0f;
  94. chamber.previous_chamber_eid = entt::null;
  95. chamber.next_chamber_eid = entt::null;
  96. }
  97. // Find or create nest shaft elevator entity
  98. entity::id elevator_eid = entity::command::find(*ctx->entity_registry, "elevator");
  99. if (elevator_eid == entt::null)
  100. {
  101. elevator_eid = entity::command::create(*ctx->entity_registry, "elevator");
  102. // Create transform component
  103. entity::component::transform transform;
  104. transform.local = math::identity_transform<float>;
  105. transform.world = transform.local;
  106. transform.warp = true;
  107. ctx->entity_registry->assign<entity::component::transform>(elevator_eid, transform);
  108. /*
  109. entity::component::constraint::follow_curve follow_curve;
  110. follow_curve.target_eid = shaft_eid;
  111. follow_curve.offset = 10.0f;
  112. */
  113. }
  114. }
  115. void setup_ants(game::context* ctx)
  116. {
  117. // Find or create queen ant entity
  118. entity::id queen_eid = entity::command::find(*ctx->entity_registry, "queen");
  119. if (queen_eid == entt::null)
  120. {
  121. queen_eid = entity::command::create(*ctx->entity_registry, "queen");
  122. }
  123. }
  124. void setup_camera(game::context* ctx)
  125. {
  126. // Switch to underground camera
  127. ctx->surface_camera->set_active(false);
  128. ctx->underground_camera->set_active(true);
  129. // Get underground camera entity
  130. entity::id camera_eid = entity::command::find(*ctx->entity_registry, "underground_cam");
  131. if (camera_eid == entt::null)
  132. {
  133. // Create camera target entity
  134. entity::id target_eid = entity::command::create(*ctx->entity_registry, "underground_cam_target");
  135. {
  136. // Transform
  137. entity::component::transform target_transform;
  138. target_transform.local = math::identity_transform<float>;
  139. target_transform.world = target_transform.local;
  140. target_transform.warp = true;
  141. ctx->entity_registry->assign<entity::component::transform>(target_eid, target_transform);
  142. }
  143. // Create camera entity
  144. camera_eid = entity::command::create(*ctx->entity_registry, "underground_cam");
  145. // Create camera transform component
  146. entity::component::transform transform;
  147. transform.local = math::identity_transform<float>;
  148. transform.world = transform.local;
  149. transform.warp = true;
  150. ctx->entity_registry->assign<entity::component::transform>(camera_eid, transform);
  151. // Create camera camera component
  152. entity::component::camera camera;
  153. camera.object = ctx->underground_camera;
  154. ctx->entity_registry->assign<entity::component::camera>(camera_eid, camera);
  155. // Create camera 3DOF constraint entity
  156. entity::id three_dof_constraint_eid = entity::command::create(*ctx->entity_registry, "underground_cam_3dof");
  157. {
  158. // Create 3DOF to constraint
  159. entity::component::constraint::three_dof three_dof;
  160. three_dof.yaw = 0.0f;
  161. three_dof.pitch = 0.0f;
  162. three_dof.roll = 0.0f;
  163. ctx->entity_registry->assign<entity::component::constraint::three_dof>(three_dof_constraint_eid, three_dof);
  164. // Create constraint stack node component
  165. entity::component::constraint_stack_node node;
  166. node.active = true;
  167. node.weight = 1.0f;
  168. node.next = entt::null;
  169. ctx->entity_registry->assign<entity::component::constraint_stack_node>(three_dof_constraint_eid, node);
  170. }
  171. // Create camera spring to constraint entity
  172. entity::id spring_constraint_eid = entity::command::create(*ctx->entity_registry);
  173. {
  174. // Create spring to constraint
  175. entity::component::constraint::spring_to spring;
  176. spring.target = target_eid;
  177. spring.translation = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, math::two_pi<float>};
  178. spring.translation.w = hz_to_rads(8.0f);
  179. spring.spring_translation = true;
  180. spring.spring_rotation = false;
  181. ctx->entity_registry->assign<entity::component::constraint::spring_to>(spring_constraint_eid, spring);
  182. // Create constraint stack node component
  183. entity::component::constraint_stack_node node;
  184. node.active = true;
  185. node.weight = 1.0f;
  186. node.next = three_dof_constraint_eid;
  187. ctx->entity_registry->assign<entity::component::constraint_stack_node>(spring_constraint_eid, node);
  188. }
  189. // Create camera constraint stack component
  190. entity::component::constraint_stack constraint_stack;
  191. constraint_stack.head = spring_constraint_eid;
  192. ctx->entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack);
  193. }
  194. ctx->underground_camera->set_exposure(0.0f);
  195. }
  196. void setup_controls(game::context* ctx)
  197. {
  198. // Get underground camera entity
  199. entity::id camera_eid = entity::command::find(*ctx->entity_registry, "underground_cam");
  200. entity::id target_eid = entity::command::find(*ctx->entity_registry, "underground_cam_target");
  201. entity::id three_dof_eid = entity::command::find(*ctx->entity_registry, "underground_cam_3dof");
  202. const float dolly_speed = 20.0f;
  203. const float truck_speed = dolly_speed;
  204. const float pedestal_speed = 30.0f;
  205. const float pan_speed = math::radians(8.0f);
  206. const float tilt_speed = pan_speed;
  207. // Dolly forward
  208. ctx->camera_control_dolly_forward->set_active_callback
  209. (
  210. [ctx, target_eid, three_dof_eid, truck_speed](float value)
  211. {
  212. if (ctx->camera_control_slow_modifier->is_active())
  213. value *= 0.5f;
  214. if (ctx->camera_control_fast_modifier->is_active())
  215. value *= 2.0f;
  216. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  217. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  218. const float3 movement = {0.0f, 0.0f, -truck_speed * value * (1.0f / 60.0f)};
  219. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  220. }
  221. );
  222. // Dolly backward
  223. ctx->camera_control_dolly_backward->set_active_callback
  224. (
  225. [ctx, target_eid, three_dof_eid, truck_speed](float value)
  226. {
  227. if (ctx->camera_control_slow_modifier->is_active())
  228. value *= 0.5f;
  229. if (ctx->camera_control_fast_modifier->is_active())
  230. value *= 2.0f;
  231. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  232. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  233. const float3 movement = {0.0f, 0.0f, truck_speed * value * (1.0f / 60.0f)};
  234. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  235. }
  236. );
  237. // Truck right
  238. ctx->camera_control_truck_right->set_active_callback
  239. (
  240. [ctx, target_eid, three_dof_eid, truck_speed](float value)
  241. {
  242. if (ctx->camera_control_slow_modifier->is_active())
  243. value *= 0.5f;
  244. if (ctx->camera_control_fast_modifier->is_active())
  245. value *= 2.0f;
  246. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  247. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  248. const float3 movement = {truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
  249. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  250. }
  251. );
  252. // Truck left
  253. ctx->camera_control_truck_left->set_active_callback
  254. (
  255. [ctx, target_eid, three_dof_eid, truck_speed](float value)
  256. {
  257. if (ctx->camera_control_slow_modifier->is_active())
  258. value *= 0.5f;
  259. if (ctx->camera_control_fast_modifier->is_active())
  260. value *= 2.0f;
  261. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  262. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  263. const float3 movement = {-truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
  264. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  265. }
  266. );
  267. // Pedestal up
  268. ctx->camera_control_pedestal_up->set_active_callback
  269. (
  270. [ctx, target_eid, pedestal_speed](float value)
  271. {
  272. if (ctx->camera_control_slow_modifier->is_active())
  273. value *= 0.5f;
  274. if (ctx->camera_control_fast_modifier->is_active())
  275. value *= 2.0f;
  276. const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
  277. entity::command::translate(*ctx->entity_registry, target_eid, movement);
  278. }
  279. );
  280. // Pedestal down
  281. ctx->camera_control_pedestal_down->set_active_callback
  282. (
  283. [ctx, target_eid, pedestal_speed](float value)
  284. {
  285. if (ctx->camera_control_slow_modifier->is_active())
  286. value *= 0.5f;
  287. if (ctx->camera_control_fast_modifier->is_active())
  288. value *= 2.0f;
  289. const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
  290. entity::command::translate(*ctx->entity_registry, target_eid, movement);
  291. }
  292. );
  293. // Mouse rotate
  294. ctx->camera_control_mouse_rotate->set_activated_callback
  295. (
  296. [ctx]()
  297. {
  298. ctx->app->set_relative_mouse_mode(true);
  299. }
  300. );
  301. ctx->camera_control_mouse_rotate->set_deactivated_callback
  302. (
  303. [ctx]()
  304. {
  305. ctx->app->set_relative_mouse_mode(false);
  306. }
  307. );
  308. // Pan left
  309. ctx->camera_control_mouse_left->set_active_callback
  310. (
  311. [ctx, three_dof_eid, pan_speed](float value)
  312. {
  313. if (!ctx->camera_control_mouse_rotate->is_active())
  314. return;
  315. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  316. three_dof.yaw += pan_speed * value * (1.0f / 60.0f);
  317. }
  318. );
  319. // Pan right
  320. ctx->camera_control_mouse_right->set_active_callback
  321. (
  322. [ctx, three_dof_eid, pan_speed](float value)
  323. {
  324. if (!ctx->camera_control_mouse_rotate->is_active())
  325. return;
  326. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  327. three_dof.yaw -= pan_speed * value * (1.0f / 60.0f);
  328. }
  329. );
  330. // Tilt up
  331. ctx->camera_control_mouse_up->set_active_callback
  332. (
  333. [ctx, three_dof_eid, tilt_speed](float value)
  334. {
  335. if (!ctx->camera_control_mouse_rotate->is_active())
  336. return;
  337. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  338. three_dof.pitch -= tilt_speed * value * (1.0f / 60.0f);
  339. three_dof.pitch = std::max<float>(math::radians(-90.0f), three_dof.pitch);
  340. }
  341. );
  342. // Tilt down
  343. ctx->camera_control_mouse_down->set_active_callback
  344. (
  345. [ctx, three_dof_eid, tilt_speed](float value)
  346. {
  347. if (!ctx->camera_control_mouse_rotate->is_active())
  348. return;
  349. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  350. three_dof.pitch += tilt_speed * value * (1.0f / 60.0f);
  351. three_dof.pitch = std::min<float>(math::radians(90.0f), three_dof.pitch);
  352. }
  353. );
  354. }
  355. } // namespace brood
  356. } // namespace state
  357. } // namespace game