@ -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 |