pandemonium_engine/modules/steering_ai/behaviors/gsaimatchorientation.cpp

155 lines
5.1 KiB
C++

#include "gsaimatchorientation.h"
GSAIAgentLocation GSAIMatchOrientation::get_*target() {
return *target;
}
void GSAIMatchOrientation::set_*target(const GSAIAgentLocation &val) {
*target = val;
}
float GSAIMatchOrientation::get_alignment_tolerance() const {
return alignment_tolerance;
}
void GSAIMatchOrientation::set_alignment_tolerance(const float val) {
alignment_tolerance = val;
}
float GSAIMatchOrientation::get_deceleration_radius() const {
return deceleration_radius;
}
void GSAIMatchOrientation::set_deceleration_radius(const float val) {
deceleration_radius = val;
}
float GSAIMatchOrientation::get_time_to_reach() const {
return time_to_reach;
}
void GSAIMatchOrientation::set_time_to_reach(const float val) {
time_to_reach = val;
}
bool GSAIMatchOrientation::get_use_z() const {
return use_z;
}
void GSAIMatchOrientation::set_use_z(const bool val) {
use_z = val;
}
// Calculates an angular acceleration to match an agent's orientation to that of;
// its target. Attempts to make the agent arrive with zero remaining angular;
// velocity.;
// @category - Individual behaviors;
// The target orientation for the behavior to try and match rotations to.;
GSAIAgentLocation *target;
// The amount of distance in radians for the behavior to consider itself close;
// enough to be matching the target agent's rotation.;
float alignment_tolerance = 0.0;
// The amount of distance in radians from the goal to start slowing down.;
float deceleration_radius = 0.0;
// The amount of time to reach the target velocity;
float time_to_reach = 0.1;
// Whether to use the X and Z components instead of X and Y components when;
// determining angles. X and Z should be used in 3D.;
bool use_z = false;
void GSAIMatchOrientation::match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation) {
call("_match_orientation", acceleration, desired_orientation);
}
void GSAIMatchOrientation::_match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation) {
float rotation = wrapf(desired_orientation - agent.orientation, -PI, PI);
float rotation_size = abs(rotation);
if (rotation_size <= alignment_tolerance) {
acceleration.set_zero();
}
else {
float desired_rotation = agent.angular_speed_max;
if (rotation_size <= deceleration_radius) {
desired_rotation *= rotation_size / deceleration_radius;
}
desired_rotation *= rotation / rotation_size;
acceleration.angular = ((desired_rotation - agent.angular_velocity) / time_to_reach);
float limited_acceleration = abs(acceleration.angular);
if (limited_acceleration > agent.angular_acceleration_max) {
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration);
}
}
acceleration.linear = Vector3.ZERO;
}
void GSAIMatchOrientation::_calculate_steering(const GSAITargetAcceleration &acceleration) {
match_orientation(acceleration, target.orientation);
}
}
GSAIMatchOrientation::GSAIMatchOrientation() {
*target;
alignment_tolerance = 0.0;
deceleration_radius = 0.0;
time_to_reach = 0.1;
use_z = false;
}
GSAIMatchOrientation::~GSAIMatchOrientation() {
}
static void GSAIMatchOrientation::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIMatchOrientation::get_*target);
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIMatchOrientation::set_*target);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
ClassDB::bind_method(D_METHOD("get_alignment_tolerance"), &GSAIMatchOrientation::get_alignment_tolerance);
ClassDB::bind_method(D_METHOD("set_alignment_tolerance", "value"), &GSAIMatchOrientation::set_alignment_tolerance);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "alignment_tolerance"), "set_alignment_tolerance", "get_alignment_tolerance");
ClassDB::bind_method(D_METHOD("get_deceleration_radius"), &GSAIMatchOrientation::get_deceleration_radius);
ClassDB::bind_method(D_METHOD("set_deceleration_radius", "value"), &GSAIMatchOrientation::set_deceleration_radius);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "deceleration_radius"), "set_deceleration_radius", "get_deceleration_radius");
ClassDB::bind_method(D_METHOD("get_time_to_reach"), &GSAIMatchOrientation::get_time_to_reach);
ClassDB::bind_method(D_METHOD("set_time_to_reach", "value"), &GSAIMatchOrientation::set_time_to_reach);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_to_reach"), "set_time_to_reach", "get_time_to_reach");
ClassDB::bind_method(D_METHOD("get_use_z"), &GSAIMatchOrientation::get_use_z);
ClassDB::bind_method(D_METHOD("set_use_z", "value"), &GSAIMatchOrientation::set_use_z);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_z"), "set_use_z", "get_use_z");
ClassDB::bind_method(D_METHOD("match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::match_orientation);
ClassDB::bind_method(D_METHOD("_match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::_match_orientation);
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIMatchOrientation::_calculate_steering);
}