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

247 lines
8.2 KiB

  1. /*
  2. * Copyright (C) 2017 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 "play-state.hpp"
  20. #include "../application.hpp"
  21. #include "../camera-controller.hpp"
  22. #include "../game/colony.hpp"
  23. #include "../game/ant.hpp"
  24. #include "../ui/toolbar.hpp"
  25. #include <cmath>
  26. PlayState::PlayState(Application* application):
  27. ApplicationState(application)
  28. {}
  29. PlayState::~PlayState()
  30. {}
  31. void PlayState::enter()
  32. {
  33. // Hide level selector
  34. application->levelSelectorContainer->setVisible(false);
  35. application->levelSelectorContainer->setActive(false);
  36. // Setup HUD
  37. application->pauseButtonImage->setVisible(false);
  38. application->pauseButtonImage->setActive(false);
  39. application->playButtonImage->setVisible(false);
  40. application->playButtonImage->setActive(false);
  41. application->rectangularPaletteImage->setVisible(true);
  42. application->rectangularPaletteImage->setActive(true);
  43. application->toolbar->getContainer()->setVisible(true);
  44. application->toolbar->getContainer()->setActive(true);
  45. // Setup tools
  46. application->forcepsClosed = false;
  47. // Add background
  48. //application->backgroundLayer->addObject(&application->bgCamera);
  49. //application->backgroundLayer->addObject(&application->bgBatch);
  50. // Create terrain model instances
  51. application->terrain.getSurfaceModel()->getGroup(0)->material = application->materialLoader->load("data/materials/debug-terrain-surface.mtl");
  52. terrainSurface.setModel(application->terrain.getSurfaceModel());
  53. terrainSurface.setTranslation(Vector3(0, 0, 0));
  54. terrainSubsurface.setModel(application->terrain.getSubsurfaceModel());
  55. terrainSubsurface.setTranslation(Vector3(0, 0, 0));
  56. // Add terrain to scene
  57. application->defaultLayer->addObject(&terrainSurface);
  58. application->defaultLayer->addObject(&terrainSubsurface);
  59. // Add forceps to scene
  60. application->defaultLayer->addObject(&application->forcepsModelInstance);
  61. // Spawn ants
  62. Navmesh* navmesh = application->terrain.getSurfaceNavmesh();
  63. for (int i = 0; i < 50; ++i)
  64. {
  65. Navmesh::Triangle* triangle = (*navmesh->getTriangles())[0];
  66. Ant* ant = application->colony->spawn(navmesh, triangle, normalize_barycentric(Vector3(0.5f)));
  67. Vector3 forward = glm::normalize(triangle->edge->vertex->position - triangle->edge->next->vertex->position);
  68. Vector3 up = triangle->normal;
  69. ant->setOrientation(forward, up);
  70. application->defaultLayer->addObject(ant->getModelInstance());
  71. ant->setState(Ant::State::WANDER);
  72. }
  73. // Setup camera controller
  74. application->surfaceCam->setCamera(&application->camera);
  75. application->surfaceCam->setFocalPoint(Vector3(0.0f));
  76. application->surfaceCam->setFocalDistance(250.0f);
  77. application->surfaceCam->setElevation(glm::radians(35.0f));
  78. application->surfaceCam->setAzimuth(glm::radians(-45.0f));
  79. application->surfaceCam->setTargetFocalPoint(application->surfaceCam->getFocalPoint());
  80. application->surfaceCam->setTargetFocalDistance(application->surfaceCam->getFocalDistance());
  81. application->surfaceCam->setTargetElevation(application->surfaceCam->getElevation());
  82. application->surfaceCam->setTargetAzimuth(application->surfaceCam->getAzimuth());
  83. application->surfaceCam->update(0.0f);
  84. application->simulationPaused = false;
  85. application->mouse->addMouseButtonObserver(this);
  86. }
  87. void PlayState::execute()
  88. {
  89. /*
  90. else
  91. {
  92. Plane plane;
  93. plane.set(Vector3(0, 1, 0), Vector3(0.0f));
  94. auto result = pickingRay.intersects(plane);
  95. pick = pickingRay.extrapolate(std::get<1>(result));
  96. }
  97. */
  98. static float rotationTime = 0.0f;
  99. float iconRotation = std::sin(rotationTime * 3.0f) * glm::radians(10.0f);
  100. rotationTime += application->dt;
  101. //application->blaImage->setRotation(iconRotation);
  102. // Move camera
  103. Vector2 movementVector(0.0f);
  104. if (application->cameraMoveLeft.isTriggered())
  105. movementVector.x -= application->cameraMoveLeft.getCurrentValue();
  106. if (application->cameraMoveRight.isTriggered())
  107. movementVector.x += application->cameraMoveRight.getCurrentValue();
  108. if (application->cameraMoveForward.isTriggered())
  109. movementVector.y -= application->cameraMoveForward.getCurrentValue();
  110. if (application->cameraMoveBack.isTriggered())
  111. movementVector.y += application->cameraMoveBack.getCurrentValue();
  112. if (movementVector.x != 0.0f || movementVector.y != 0.0f)
  113. {
  114. movementVector *= 0.005f * application->surfaceCam->getFocalDistance() * application->dt / (1.0f / 60.0f);
  115. application->surfaceCam->move(movementVector);
  116. Vector3 focal = application->surfaceCam->getFocalPoint();
  117. }
  118. // Zoom camera
  119. float zoomFactor = application->surfaceCam->getFocalDistance() / 10.0f * application->dt / (1.0f / 60.0f);
  120. if (application->cameraZoomIn.isTriggered())
  121. application->surfaceCam->zoom(zoomFactor * application->cameraZoomIn.getCurrentValue());
  122. if (application->cameraZoomOut.isTriggered())
  123. application->surfaceCam->zoom(-zoomFactor * application->cameraZoomOut.getCurrentValue());
  124. // Rotate camera
  125. if (application->cameraRotateCW.isTriggered() && !application->cameraRotateCW.wasTriggered())
  126. {
  127. application->surfaceCam->rotate(glm::radians(-45.0f));
  128. }
  129. if (application->cameraRotateCCW.isTriggered() && !application->cameraRotateCCW.wasTriggered())
  130. {
  131. application->surfaceCam->rotate(glm::radians(45.0f));
  132. }
  133. // Update camera
  134. application->surfaceCam->update(application->dt);
  135. // Picking
  136. glm::ivec2 mousePosition = application->mouse->getCurrentPosition();
  137. mousePosition.y = application->height - mousePosition.y;
  138. Vector4 viewport(0.0f, 0.0f, application->width, application->height);
  139. Vector3 mouseNear = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 0.0f), viewport);
  140. Vector3 mouseFar = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 1.0f), viewport);
  141. Ray pickingRay;
  142. pickingRay.origin = mouseNear;
  143. pickingRay.direction = glm::normalize(mouseFar - mouseNear);
  144. Vector3 pick;
  145. std::list<Navmesh::Triangle*> triangles;
  146. application->terrain.getSurfaceOctree()->query(pickingRay, &triangles);
  147. auto result = intersects(pickingRay, triangles);
  148. if (std::get<0>(result))
  149. {
  150. pick = pickingRay.extrapolate(std::get<1>(result));
  151. std::size_t triangleIndex = std::get<3>(result);
  152. const Navmesh::Triangle* triangle = (*application->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex];
  153. float forcepsDistance = (application->forcepsClosed) ? 0.0f : 0.5f;
  154. //Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal);
  155. Quaternion rotation = glm::angleAxis(application->surfaceCam->getAzimuth(), Vector3(0, 1, 0)) *
  156. glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1));
  157. Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0);
  158. // Set tool position
  159. application->forcepsModelInstance.setTranslation(translation);
  160. application->forcepsModelInstance.setRotation(rotation);
  161. }
  162. // Update colony
  163. if (!application->simulationPaused)
  164. {
  165. application->colony->update(application->dt);
  166. }
  167. // Pause simulation
  168. if (application->togglePause.isTriggered() && !application->togglePause.wasTriggered())
  169. {
  170. if (application->simulationPaused)
  171. {
  172. application->unpauseSimulation();
  173. }
  174. else
  175. {
  176. application->pauseSimulation();
  177. }
  178. }
  179. }
  180. void PlayState::exit()
  181. {
  182. // Remove background
  183. //application->backgroundLayer->removeObject(&application->bgCamera);
  184. //application->backgroundLayer->removeObject(&application->bgBatch);
  185. application->mouse->removeMouseButtonObserver(this);
  186. }
  187. void PlayState::mouseButtonPressed(int button, int x, int y)
  188. {
  189. if (button == 1)
  190. {
  191. application->forcepsClosed = true;
  192. }
  193. }
  194. void PlayState::mouseButtonReleased(int button, int x, int y)
  195. {
  196. if (button == 1)
  197. {
  198. application->forcepsClosed = false;
  199. }
  200. }