1 #ifndef STEERIOUSLY_HPP
2 #define STEERIOUSLY_HPP
40 #include <steeriously/Agent.hpp>
41 #include <steeriously/BehaviorHelpers.hpp>
42 #include <steeriously/GeometryHelpers.hpp>
43 #include <steeriously/Path.hpp>
44 #include <steeriously/Transformations.hpp>
45 #include <steeriously/Utilities.hpp>
46 #include <steeriously/Vector2.hpp>
47 #include <steeriously/VectorMath.hpp>
48 #include <steeriously/Wall.hpp>
81 template<
class T,
class N>
94 float extrapolateTime =
VectorMath::length(to) / (agent->getMaxSpeed() + other->getSpeed());
109 template<
class T,
class N,
class P>
110 steer::Vector2 calculateTarget(
const T& agent,
const N& otherA,
const P& otherB)
113 steer::Vector2 mid = (otherA->getPosition() + otherB->getPosition()) / 2.f;
122 steer::Vector2 posA = otherA->getPosition() + otherA->getVelocity() * extrapolateTime;
123 steer::Vector2 posB = otherB->getPosition() + otherB->getVelocity() * extrapolateTime;
126 mid = (posA + posB) / 2.f;
141 if (agent !=
nullptr)
144 return (velocity - agent->getVelocity());
163 return (velocity - agent->getVelocity());
173 template<
class T,
class conT>
179 if (agent !=
nullptr)
181 for (
auto& i : neighbors)
185 if (i !=
nullptr && i != agent && i->taggedInGroup())
189 avg += i->getHeading();
200 avg -= agent->getHeading();
214 template <
class T,
class conT>
222 if (agent !=
nullptr)
224 for (
auto& i : neighbors)
228 if (i !=
nullptr && i != agent && i->taggedInGroup())
230 toTarget = agent->getPosition() - i->getPosition();
237 force += normal / length;
252 template <
class T,
class conT>
260 if (agent !=
nullptr)
262 for (
auto& i : neighbors)
266 if (i !=
nullptr && i != agent && i->taggedInGroup())
269 centerOfMass += i->getPosition();
278 centerOfMass /= (float)count;
284 force = Seek(agent, centerOfMass);
306 steer::Vector2 target = agent->getTarget() - agent->getPosition();
315 float speed = distance / ((float)deceleration * agent->getDecelerationTweaker());
318 speed = std::min(speed, agent->getMaxSpeed());
323 return (velocity - agent->getVelocity());
337 template<
class T,
class N>
347 agent->setTarget(evader->getPosition());
348 return Seek<T>(agent);
353 float extrapolationTime =
VectorMath::length(to) / (agent->getMaxSpeed() + evader->getSpeed());
356 agent->setTarget(evader->getPosition() + evader->getVelocity() * extrapolationTime);
357 return Seek<T>(agent);
368 template<
class T,
class N>
372 agent->setTarget(leader->getPosition());
382 float speed = distance / ((float)parameters.deceleration * agent->getDecelerationTweaker());
385 speed = std::min(speed, agent->getMaxSpeed());
390 return (velocity - agent->getVelocity());
409 return (velocity - agent->getVelocity());
419 template<
class T,
class N>
422 agent->setTarget(calculateTarget<T,N>(agent, other));
428 return (velocity - agent->getVelocity());
443 float away = radius + distanceBuffer;
451 return (to * away) + goalPosition;
463 template<
class T,
class N,
class conT>
466 float closest = steer::MaxFloat;
469 for (
auto& ob : obstacles)
477 if (distance < closest)
488 if (closest == steer::MaxFloat)
490 return Evade<T, N>(agent, other);
494 agent->setTarget(best);
495 return Arrive<T>(agent, parameters.deceleration);
507 template<
class T,
class N,
class P>
511 agent->setTarget(calculateTarget<T,N,P>(agent, otherA, otherB));
519 float speed = distance / ((float)parameters.deceleration * agent->getDecelerationTweaker());
522 speed = std::min(speed, agent->getMaxSpeed());
526 return (velocity - agent->getVelocity());
541 if (agent !=
nullptr)
545 float JitterThisTimeSlice = agent->m_wanderJitter * agent->getElapsedTime();
555 agent->m_wanderTarget *= agent->m_wanderRadius;
563 return Target - agent->getPosition();
575 template <
class T,
class conT>
579 agent->setBoxLength(parameters.MinDetectionBoxLength + (agent->getSpeed() / agent->getMaxSpeed()) * parameters.MinDetectionBoxLength);
582 steer::TagObstaclesWithinViewRange< T, conT >(agent, obstacles, agent->m_boxLength);
588 float distance = steer::MaxDouble;
593 for (
auto& i : obstacles)
595 if (i !=
nullptr && i->taggedInGroup())
604 float radius = i->getRadius() + agent->getBoundingRadius();
606 if (fabs(local.y) < radius)
610 float subtrahend = sqrt(radius*radius - local.y*local.y);
612 float difference = local.x - subtrahend;
616 if (difference <= 0.0)
618 difference = local.x + subtrahend;
622 if (difference < distance)
624 distance = difference;
637 if (closest !=
nullptr)
641 float scale = 1.0 + (agent->boxLength() - position.x) / agent->boxLength();
644 force.y = (closest->getRadius() - position.y) * scale;
646 const float brake = 0.2;
649 force.x = (closest->getRadius() - position.x) * brake;
664 steer::Vector2 WallAvoidance(
const T& agent,
const std::vector<steer::Wall*>& walls)
667 agent->createFeelers();
669 float distance = 0.0;
670 float closestDistance = steer::MaxFloat;
679 for (
unsigned int flr = 0; flr<agent->getFeelers().size(); ++flr)
682 for (
unsigned int w = 0; w<walls.size(); ++w)
684 if (
steer::LineIntersection2D(agent->getPosition(), agent->getFeelers()[flr], walls[w]->From(), walls[w]->To(), distance, tempPoint))
687 if (distance < closestDistance)
689 closestDistance = distance;
738 return Seek< T >(agent);
744 return Arrive< T >(agent, agent->m_deceleration);
751 #endif //STEERIOUSLY_HPP