@ -0,0 +1,68 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_AI_STEERING_AGENT_HPP | |||||
#define ANTKEEPER_AI_STEERING_AGENT_HPP | |||||
#include "utility/fundamental-types.hpp" | |||||
#include "math/quaternion-type.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
/** | |||||
* Autonomous agent governed by steering behaviors. | |||||
*/ | |||||
struct agent | |||||
{ | |||||
/// Mass of the agent. | |||||
float mass; | |||||
/// Cartesian position vector. | |||||
float3 position; | |||||
/// Velocity vector. | |||||
float3 velocity; | |||||
/// Acceleration vector. | |||||
float3 acceleration; | |||||
/// Maximum force. | |||||
float max_force; | |||||
/// Maximum speed. | |||||
float max_speed; | |||||
/// Maximum speed squared. | |||||
float max_speed_squared; | |||||
/// Orientation quaternion. | |||||
math::quaternion<float> orientation; | |||||
/// Orthonormal basis forward direction vector. | |||||
float3 forward; | |||||
/// Orthonormal basis up direction vector. | |||||
float3 up; | |||||
}; | |||||
} // namespace steering | |||||
} // namespace ai | |||||
#endif // ANTKEEPER_AI_STEERING_AGENT_HPP |
@ -0,0 +1,44 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#include "ai/steering/behavior/flee.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
float3 flee(const agent& agent, const float3& target) | |||||
{ | |||||
float3 force = {0, 0, 0}; | |||||
const float3 difference = target - agent.position; | |||||
const float distance_squared = math::dot(difference, difference); | |||||
if (distance_squared) | |||||
{ | |||||
const float inverse_distance = 1.0f / std::sqrt(distance_squared); | |||||
force = difference * inverse_distance * agent.max_force; | |||||
force = agent.velocity - force; | |||||
} | |||||
return force; | |||||
} | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai |
@ -0,0 +1,43 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_AI_STEERING_BEHAVIOR_FLEE_HPP | |||||
#define ANTKEEPER_AI_STEERING_BEHAVIOR_FLEE_HPP | |||||
#include "ai/steering/agent.hpp" | |||||
#include "utility/fundamental-types.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
/** | |||||
* Attempts to steer an agent so that it moves away from a target. | |||||
* | |||||
* @param agent Autonomous agent to steer. | |||||
* @param target Target position. | |||||
* @return Flee force. | |||||
*/ | |||||
float3 flee(const agent& agent, const float3& target); | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai | |||||
#endif // ANTKEEPER_AI_STEERING_BEHAVIOR_FLEE_HPP |
@ -0,0 +1,44 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#include "ai/steering/behavior/seek.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
float3 seek(const agent& agent, const float3& target) | |||||
{ | |||||
float3 force = {0, 0, 0}; | |||||
const float3 difference = target - agent.position; | |||||
const float distance_squared = math::dot(difference, difference); | |||||
if (distance_squared) | |||||
{ | |||||
const float inverse_distance = 1.0f / std::sqrt(distance_squared); | |||||
force = difference * inverse_distance * agent.max_force; | |||||
force -= agent.velocity; | |||||
} | |||||
return force; | |||||
} | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai |
@ -0,0 +1,43 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_AI_STEERING_BEHAVIOR_SEEK_HPP | |||||
#define ANTKEEPER_AI_STEERING_BEHAVIOR_SEEK_HPP | |||||
#include "ai/steering/agent.hpp" | |||||
#include "utility/fundamental-types.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
/** | |||||
* Attempts to steer an agent so that it moves toward a target. | |||||
* | |||||
* @param agent Autonomous agent to steer. | |||||
* @param target Target position. | |||||
* @return Seek force. | |||||
*/ | |||||
float3 seek(const agent& agent, const float3& target); | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai | |||||
#endif // ANTKEEPER_AI_STEERING_BEHAVIOR_SEEK_HPP |
@ -0,0 +1,78 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#include "ai/steering/behavior/wander.hpp" | |||||
#include "ai/steering/behavior/seek.hpp" | |||||
#include "math/random.hpp" | |||||
#include "math/quaternion-functions.hpp" | |||||
#include "math/quaternion-operators.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
float3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle) | |||||
{ | |||||
// Shift wander angle | |||||
angle += math::random(-noise, noise); | |||||
// Calculate center of wander circle | |||||
const float3 center = agent.position + agent.forward * distance; | |||||
// Decompose orientation into swing and twist rotations | |||||
math::quaternion<float> swing, twist; | |||||
math::swing_twist(agent.orientation, agent.up, swing, twist); | |||||
// Calculate offset to point on wander circle | |||||
const float3 offset = math::conjugate(twist) * (math::angle_axis(angle, agent.up) * agent.forward * radius); | |||||
// Seek toward point on wander circle | |||||
return seek(agent, center + offset); | |||||
} | |||||
/* | |||||
float3 wander_3d(const agent& agent, float distance, float radius, float delta, float& theta, float& phi) | |||||
{ | |||||
// Shift wander angles | |||||
theta += random(-delta, delta); | |||||
phi += random(-delta, delta); | |||||
// Calculate center of wander sphere | |||||
float3 center = agent.position; | |||||
const float speed_squared = math::dot(agent.velocity, agent.velocity); | |||||
if (speed_squared) | |||||
center += (agent.velocity / std::sqrt(speed_squared)) * distance; | |||||
// Convert spherical coordinates to Cartesian point on wander sphere | |||||
const float r_cos_theta = radius * std::cos(theta); | |||||
const float3 offset = | |||||
{ | |||||
r_cos_theta * std::cos(phi), | |||||
r_cos_theta * std::sin(phi), | |||||
radius * std::sin(theta) | |||||
}; | |||||
// Seek toward point on wander sphere | |||||
return seek(agent, center + offset); | |||||
} | |||||
*/ | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai |
@ -0,0 +1,62 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_AI_STEERING_BEHAVIOR_WANDER_HPP | |||||
#define ANTKEEPER_AI_STEERING_BEHAVIOR_WANDER_HPP | |||||
#include "ai/steering/agent.hpp" | |||||
#include "utility/fundamental-types.hpp" | |||||
namespace ai { | |||||
namespace steering { | |||||
namespace behavior { | |||||
/** | |||||
* Steers an agent in a continuously shifting random direction on the yaw plane. | |||||
* | |||||
* @param agent Autonomous agent to steer. | |||||
* @param distance Distance to the center of the wander circle. | |||||
* @param noise Maximum wander angle shift, in radians. | |||||
* @param radius Radius of the wander circle. | |||||
* @param[in,out] angle Angular coordinate on the wander circle, in radians. | |||||
* | |||||
* @return Wander force. | |||||
*/ | |||||
float3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle); | |||||
/** | |||||
* Steers an agent in a continuously shifting random direction. | |||||
* | |||||
* @param agent Autonomous agent to steer. | |||||
* @param distance Distance to the wander sphere. | |||||
* @param radius Radius of the wander sphere. | |||||
* @param delta Maximum angle offset. | |||||
* @param theta Polar wander angle, in radians. | |||||
* @param phi Azimuthal wander angle, in radians. | |||||
* @param[in,out] Wander angle, in radians. | |||||
* | |||||
* @return Wander force. | |||||
*/ | |||||
//float3 wander_3d(const agent& agent, float distance, float radius, float delta, float& theta, float& phi); | |||||
} // namespace behavior | |||||
} // namespace steering | |||||
} // namespace ai | |||||
#endif // ANTKEEPER_AI_STEERING_BEHAVIOR_WANDER_HPP |
@ -0,0 +1,34 @@ | |||||
/* | |||||
* Copyright (C) 2021 Christopher J. Howard | |||||
* | |||||
* This file is part of Antkeeper source code. | |||||
* | |||||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* Antkeeper source code is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef ANTKEEPER_AI_STEERING_HPP | |||||
#define ANTKEEPER_AI_STEERING_HPP | |||||
namespace ai { | |||||
/** | |||||
* Autonomous agent steering. | |||||
* | |||||
* @see Reynolds, Craig. (2002). Steering Behaviors For Autonomous Characters. | |||||
*/ | |||||
namespace steering {} | |||||
} // namespace ai | |||||
#endif // ANTKEEPER_AI_STEERING_HPP |