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

107 lines
3.3 KiB

  1. /*
  2. * Copyright (C) 2017-2019 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 "locomotion-system.hpp"
  20. #include "../../triangle-mesh-operations.hpp"
  21. LocomotionSystem::LocomotionSystem(ComponentManager* componentManager):
  22. System(componentManager),
  23. leggedLocomotionGroup(componentManager)
  24. {
  25. leggedLocomotionGroup.addGroupObserver(this);
  26. }
  27. LocomotionSystem::~LocomotionSystem()
  28. {}
  29. void LocomotionSystem::update(float t, float dt)
  30. {
  31. auto members = leggedLocomotionGroup.getMembers();
  32. // Perform legged locomotion
  33. for (const LeggedLocomotionGroup::Member* member: *members)
  34. {
  35. LeggedLocomotionComponent* leggedLocomotion = std::get<0>(member->components);
  36. SteeringComponent* steering = std::get<1>(member->components);
  37. TransformComponent* transform = std::get<2>(member->components);
  38. // Skip entities which are not on a surface
  39. if (!leggedLocomotion->surface)
  40. {
  41. continue;
  42. }
  43. // Determine target position
  44. Vector3 force = steering->force * dt;
  45. float speed = steering->speed * dt;
  46. if (speed == 0.0f)
  47. {
  48. continue;
  49. }
  50. // Calculate direction vector
  51. Vector3 direction = force * (1.0f / speed);
  52. std::vector<WrapOperationSegment> segments;
  53. float wrapDistance = wrap(leggedLocomotion->surface, transform->transform.translation, direction, speed, &segments);
  54. WrapOperationSegment segment = segments.back();
  55. Vector3 cartesianStart = cartesian(segment.startPosition,
  56. segment.triangle->edge->vertex->position,
  57. segment.triangle->edge->next->vertex->position,
  58. segment.triangle->edge->previous->vertex->position);
  59. Vector3 cartesianEnd = cartesian(segment.endPosition,
  60. segment.triangle->edge->vertex->position,
  61. segment.triangle->edge->next->vertex->position,
  62. segment.triangle->edge->previous->vertex->position);
  63. // Calculate wrap direction of final segment
  64. Vector3 segmentDirection(0.0f);
  65. if (cartesianStart != cartesianEnd)
  66. {
  67. segmentDirection = glm::normalize(cartesianEnd - cartesianStart);
  68. }
  69. // Determine angle between the triangles
  70. float angle = std::acos(glm::dot(leggedLocomotion->surface->normal, segment.triangle->normal));
  71. if (std::abs(angle) > glm::radians(35.0f))
  72. {
  73. // Transition
  74. }
  75. leggedLocomotion->surface = segment.triangle;
  76. leggedLocomotion->barycentricPosition = segment.endPosition;
  77. transform->transform.translation = cartesianEnd;
  78. if (cartesianStart != cartesianEnd)
  79. {
  80. transform->transform.rotation = lookRotation(segmentDirection, segment.triangle->normal);
  81. }
  82. }
  83. }
  84. void LocomotionSystem::memberRegistered(const LeggedLocomotionGroup::Member* member)
  85. {}
  86. void LocomotionSystem::memberUnregistered(const LeggedLocomotionGroup::Member* member)
  87. {}