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

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