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

240 lines
8.6 KiB

  1. /*
  2. * Copyright (C) 2020 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 "application-states.hpp"
  20. #include "configuration.hpp"
  21. #include "application.hpp"
  22. #include "scene/model-instance.hpp"
  23. #include "resources/resource-manager.hpp"
  24. #include "renderer/model.hpp"
  25. #include "renderer/material.hpp"
  26. #include "systems/control-system.hpp"
  27. #include "entity/components/model-component.hpp"
  28. #include "entity/components/transform-component.hpp"
  29. #include "entity/components/terrain-component.hpp"
  30. #include "entity/components/samara-component.hpp"
  31. #include "entity/components/cavity-component.hpp"
  32. #include "entity/components/tool-component.hpp"
  33. #include "entity/components/placement-component.hpp"
  34. #include "entity/archetype.hpp"
  35. #include "nest.hpp"
  36. #include "math.hpp"
  37. #include "geometry/mesh-accelerator.hpp"
  38. #include "behavior/ebt.hpp"
  39. #include <iostream>
  40. using namespace vmq::operators;
  41. void enter_play_state(application* app)
  42. {
  43. logger* logger = app->get_logger();
  44. logger->push_task("Entering play state");
  45. resource_manager* resource_manager = app->get_resource_manager();
  46. entt::registry& ecs_registry = app->get_ecs_registry();
  47. // Load entity archetypes
  48. ecs::archetype* ant_hill_archetype = resource_manager->load<ecs::archetype>("ant-hill.ent");
  49. ecs::archetype* maple_tree_archetype = resource_manager->load<ecs::archetype>("maple-tree.ent");
  50. ecs::archetype* darkness_volume_archetype = resource_manager->load<ecs::archetype>("darkness-volume.ent");
  51. ecs::archetype* nest_archetype = resource_manager->load<ecs::archetype>("harvester-nest.ent");
  52. ecs::archetype* samara_archetype = resource_manager->load<ecs::archetype>("samara.ent");
  53. ecs::archetype* forceps_archetype = resource_manager->load<ecs::archetype>("forceps.ent");
  54. ecs::archetype* larva_archetype = resource_manager->load<ecs::archetype>("larva.ent");
  55. ecs::archetype* pebble_archetype = resource_manager->load<ecs::archetype>("pebble.ent");
  56. ecs::placement_component placement;
  57. auto ant_hill_entity = ant_hill_archetype->create(ecs_registry);
  58. placement.ray.origin = {0, 10000, 0};
  59. placement.ray.direction = {0, -1, 0};
  60. ecs_registry.assign<ecs::placement_component>(ant_hill_entity, placement);
  61. float pebble_radius = 300.0f;
  62. int pebble_count = 100;
  63. for (int i = 0; i < pebble_count; ++i)
  64. {
  65. float x = frand(-pebble_radius, pebble_radius);
  66. float z = frand(-pebble_radius, pebble_radius);
  67. auto pebble_entity = pebble_archetype->create(ecs_registry);
  68. auto& transform = ecs_registry.get<ecs::transform_component>(pebble_entity);
  69. transform.transform = vmq::identity_transform<float>;
  70. transform.transform.rotation = vmq::angle_axis(frand(0.0f, vmq::two_pi<float>), {0, 1, 0});
  71. transform.transform.scale = float3{1, 1, 1} * frand(0.75f, 1.25f);
  72. placement.ray.origin = {x, 10000, z};
  73. ecs_registry.assign<ecs::placement_component>(pebble_entity, placement);
  74. }
  75. auto maple_tree_entity = maple_tree_archetype->create(ecs_registry);
  76. placement.ray.origin = {300, 10000, 200};
  77. placement.ray.direction = {0, -1, 0};
  78. ecs_registry.assign<ecs::placement_component>(maple_tree_entity, placement);
  79. //auto darkness_volume_entity = darkness_volume_archetype->create(ecs_registry);
  80. auto nest_entity = nest_archetype->create(ecs_registry);
  81. int terrain_radius = 2;
  82. for (int x = -terrain_radius; x <= terrain_radius; ++x)
  83. {
  84. for (int z = -terrain_radius; z <= terrain_radius; ++z)
  85. {
  86. ecs::terrain_component terrain_component;
  87. terrain_component.subdivisions = TERRAIN_PATCH_RESOLUTION;
  88. terrain_component.x = x;
  89. terrain_component.z = z;
  90. auto terrain_entity = ecs_registry.create();
  91. ecs_registry.assign<ecs::terrain_component>(terrain_entity, terrain_component);
  92. }
  93. }
  94. for (int i = 0; i < 15; ++i)
  95. {
  96. auto samara_entity = samara_archetype->create(ecs_registry);
  97. auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity);
  98. float zone = 200.0f;
  99. transform.transform = vmq::identity_transform<float>;
  100. transform.transform.translation.x = frand(-zone, zone);
  101. transform.transform.translation.y = frand(50.0f, 150.0f);
  102. transform.transform.translation.z = frand(-zone, zone);
  103. ecs::samara_component samara_component;
  104. samara_component.angle = frand(0.0f, vmq::radians(360.0f));
  105. samara_component.direction = vmq::normalize(float3{frand(-1, 1), frand(-1, -5), frand(-1, 1)});
  106. samara_component.chirality = (frand(0, 1) < 0.5f) ? -1.0f : 1.0f;
  107. ecs_registry.assign_or_replace<ecs::samara_component>(samara_entity, samara_component);
  108. }
  109. /*
  110. ecs::archetype* grass_archetype = resource_manager->load<ecs::archetype>("grassland-grass.ent");
  111. auto grass_entity_1 = grass_archetype->create(ecs_registry);
  112. auto grass_entity_2 = grass_archetype->create(ecs_registry);
  113. ecs_registry.get<ecs::transform_component>(grass_entity_2).transform.rotation = vmq::angle_axis(vmq::radians(120.0f), float3{0, 1, 0});
  114. */
  115. // Setup overworld camera
  116. camera* camera = app->get_overworld_camera();
  117. orbit_cam* orbit_cam = app->get_orbit_cam();
  118. orbit_cam->attach(camera);
  119. orbit_cam->set_target_focal_point({0, 0, 0});
  120. orbit_cam->set_target_focal_distance(15.0f);
  121. orbit_cam->set_target_elevation(vmq::radians(25.0f));
  122. orbit_cam->set_target_azimuth(0.0f);
  123. orbit_cam->set_focal_point(orbit_cam->get_target_focal_point());
  124. orbit_cam->set_focal_distance(orbit_cam->get_target_focal_distance());
  125. orbit_cam->set_elevation(orbit_cam->get_target_elevation());
  126. orbit_cam->set_azimuth(orbit_cam->get_target_azimuth());
  127. // Create forceps tool
  128. auto forceps_entity = forceps_archetype->create(ecs_registry);
  129. ecs::tool_component forceps_tool_component;
  130. forceps_tool_component.active = true;
  131. ecs_registry.assign<ecs::tool_component>(forceps_entity, forceps_tool_component);
  132. app->get_scene().update_tweens();
  133. // Allocate a nest
  134. nest* nest = new ::nest();
  135. // Setup initial nest parameters
  136. float tunnel_radius = 1.15f;
  137. nest->set_tunnel_radius(tunnel_radius);
  138. nest::shaft* central_shaft = nest->get_central_shaft();
  139. central_shaft->chirality = -1.0f;
  140. central_shaft->rotation = vmq::radians(0.0f);
  141. central_shaft->depth = {0.0f, 200.0f};
  142. central_shaft->radius = {0.0f, 5.0f};
  143. central_shaft->pitch = {4.0f, 8.0f};
  144. central_shaft->translation = {{{0.0f, 0.0f}, {40.0f, 26.0f}}};
  145. central_shaft->current_depth = 0.0f;
  146. for (std::size_t i = 0; i < 4; ++i)
  147. {
  148. nest::chamber chamber;
  149. chamber.shaft = central_shaft;
  150. chamber.depth = (i + 1) * 50.0f;
  151. chamber.rotation = vmq::radians(0.0f);
  152. chamber.inner_radius = 4.0f;
  153. chamber.outer_radius = 10.0f;
  154. central_shaft->chambers.push_back(chamber);
  155. }
  156. // Dig nest shafts
  157. float shift = 0.1f;
  158. for (int i = 0; i < 400; ++i)
  159. {
  160. ecs::cavity_component cavity;
  161. cavity.position = nest->extend_shaft(*nest->get_central_shaft());
  162. cavity.position += float3{frand(-shift, shift), frand(-shift, shift), frand(-shift, shift)};
  163. cavity.radius = tunnel_radius * frand(1.0f, 1.1f);
  164. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  165. }
  166. // Dig nest chambers
  167. for (int i = 0; i < central_shaft->chambers.size(); ++i)
  168. {
  169. for (int j = 0; j < 150; ++j)
  170. {
  171. ecs::cavity_component cavity;
  172. cavity.position = nest->expand_chamber(central_shaft->chambers[i]);
  173. cavity.position += float3{frand(-shift, shift), frand(-shift, shift), frand(-shift, shift)};
  174. cavity.radius = tunnel_radius * frand(1.0f, 1.1f);
  175. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  176. }
  177. }
  178. // Place larva in chamber
  179. {
  180. auto larva_entity = larva_archetype->create(ecs_registry);
  181. auto& transform = ecs_registry.get<ecs::transform_component>(larva_entity);
  182. transform.transform = vmq::identity_transform<float>;
  183. transform.transform.translation = nest->get_shaft_position(*central_shaft, central_shaft->depth[1]);
  184. //transform.transform.translation.y -= 1.0f;
  185. }
  186. control_system* control_system = app->get_control_system();
  187. control_system->update(0.0f);
  188. control_system->set_nest(nest);
  189. orbit_cam->update(0.0f);
  190. logger->pop_task(EXIT_SUCCESS);
  191. }
  192. void exit_play_state(application* app)
  193. {
  194. logger* logger = app->get_logger();
  195. logger->push_task("Exiting play state");
  196. logger->pop_task(EXIT_SUCCESS);
  197. }