mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-11 13:21:10 +01:00
Behaviors cleanup part1.
This commit is contained in:
parent
caf3f1210b
commit
9bca0fae16
@ -5,8 +5,8 @@ class GSAIFollowPath : public GSAIArrive {
|
||||
GDCLASS(GSAIFollowPath, GSAIArrive);
|
||||
|
||||
public:
|
||||
GSAIPath get_ *path();
|
||||
void set_ *path(const GSAIPath &val);
|
||||
GSAIPath get_path();
|
||||
void set_path(const GSAIPath &val);
|
||||
|
||||
float get_path_offset() const;
|
||||
void set_path_offset(const float val);
|
||||
|
@ -1,30 +1,27 @@
|
||||
|
||||
#include "gsai_look_where_you_go.h"
|
||||
|
||||
// Calculates an angular acceleration to match an agent's orientation to its;
|
||||
// direction of travel.;
|
||||
// @category - Individual behaviors;
|
||||
#include "../gsai_steering_agent.h"
|
||||
#include "../gsai_target_acceleration.h"
|
||||
#include "../gsai_utils.h"
|
||||
|
||||
void GSAILookWhereYouGo::_calculate_steering(const GSAITargetAcceleration &accel) {
|
||||
if (agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold) {
|
||||
accel.set_zero();
|
||||
}
|
||||
void GSAILookWhereYouGo::_calculate_steering(Ref<GSAITargetAcceleration> accel) {
|
||||
ERR_FAIL_COND(!agent.is_valid());
|
||||
|
||||
else {
|
||||
float orientation = ;
|
||||
if (agent->get_linear_velocity().length_squared() < agent->get_zero_linear_speed_threshold()) {
|
||||
accel->set_zero();
|
||||
} else {
|
||||
float orientation;
|
||||
|
||||
if (use_z) {
|
||||
orientation = GSAIUtils.vector3_to_angle(agent.linear_velocity);
|
||||
}
|
||||
|
||||
else {
|
||||
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(agent.linear_velocity));
|
||||
orientation = GSAIUtils::vector3_to_angle(agent->get_linear_velocity());
|
||||
} else {
|
||||
orientation = GSAIUtils::vector2_to_angle(GSAIUtils::to_vector2(agent->get_linear_velocity()));
|
||||
}
|
||||
|
||||
match_orientation(accel, orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSAILookWhereYouGo::GSAILookWhereYouGo() {
|
||||
}
|
||||
@ -32,6 +29,5 @@ GSAILookWhereYouGo::GSAILookWhereYouGo() {
|
||||
GSAILookWhereYouGo::~GSAILookWhereYouGo() {
|
||||
}
|
||||
|
||||
static void GSAILookWhereYouGo::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "accel"), &GSAILookWhereYouGo::_calculate_steering);
|
||||
void GSAILookWhereYouGo::_bind_methods() {
|
||||
}
|
||||
|
@ -1,11 +1,17 @@
|
||||
#ifndef GSAI_LOOK_WHERE_YOU_GO_H
|
||||
#define GSAI_LOOK_WHERE_YOU_GO_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "gsai_match_orientation.h"
|
||||
|
||||
class GSAITargetAcceleration;
|
||||
|
||||
class GSAILookWhereYouGo : public GSAIMatchOrientation {
|
||||
GDCLASS(GSAILookWhereYouGo, GSAIMatchOrientation);
|
||||
|
||||
public:
|
||||
void _calculate_steering(const GSAITargetAcceleration &accel);
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> accel);
|
||||
|
||||
GSAILookWhereYouGo();
|
||||
~GSAILookWhereYouGo();
|
||||
|
@ -1,12 +1,18 @@
|
||||
|
||||
#include "gsai_match_orientation.h"
|
||||
|
||||
GSAIAgentLocation GSAIMatchOrientation::get_ *target() {
|
||||
return *target;
|
||||
#include "core/math/math_funcs.h"
|
||||
|
||||
#include "../gsai_agent_location.h"
|
||||
#include "../gsai_steering_agent.h"
|
||||
#include "../gsai_target_acceleration.h"
|
||||
|
||||
Ref<GSAIAgentLocation> GSAIMatchOrientation::get_target() {
|
||||
return target;
|
||||
}
|
||||
|
||||
void GSAIMatchOrientation::set_ *target(const GSAIAgentLocation &val) {
|
||||
*target = val;
|
||||
void GSAIMatchOrientation::set_target(const Ref<GSAIAgentLocation> &val) {
|
||||
target = val;
|
||||
}
|
||||
|
||||
float GSAIMatchOrientation::get_alignment_tolerance() const {
|
||||
@ -41,61 +47,48 @@ 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) {
|
||||
void GSAIMatchOrientation::match_orientation(const Ref<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);
|
||||
void GSAIMatchOrientation::_match_orientation(Ref<GSAITargetAcceleration> acceleration, float desired_orientation) {
|
||||
ERR_FAIL_COND(!agent.is_valid());
|
||||
|
||||
float rotation = Math::wrapf(static_cast<double>(desired_orientation - agent->get_orientation()), -Math_PI, Math_PI);
|
||||
float rotation_size = abs(rotation);
|
||||
|
||||
if (rotation_size <= alignment_tolerance) {
|
||||
acceleration.set_zero();
|
||||
}
|
||||
|
||||
else {
|
||||
float desired_rotation = agent.angular_speed_max;
|
||||
acceleration->set_zero();
|
||||
} else {
|
||||
float desired_rotation = agent->get_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);
|
||||
float angular = ((desired_rotation - agent->get_angular_velocity()) / time_to_reach);
|
||||
float limited_acceleration = abs(angular);
|
||||
|
||||
if (limited_acceleration > agent.angular_acceleration_max) {
|
||||
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration);
|
||||
float angular_acceleration_max = agent->get_angular_acceleration_max();
|
||||
|
||||
if (limited_acceleration > angular_acceleration_max) {
|
||||
angular *= (angular_acceleration_max / limited_acceleration);
|
||||
}
|
||||
|
||||
acceleration->set_angular(angular);
|
||||
}
|
||||
|
||||
acceleration.linear = Vector3.ZERO;
|
||||
acceleration->set_linear(Vector3());
|
||||
}
|
||||
|
||||
void GSAIMatchOrientation::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||
match_orientation(acceleration, target.orientation);
|
||||
}
|
||||
void GSAIMatchOrientation::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
|
||||
ERR_FAIL_COND(!target.is_valid());
|
||||
|
||||
match_orientation(acceleration, target->get_orientation());
|
||||
}
|
||||
|
||||
GSAIMatchOrientation::GSAIMatchOrientation() {
|
||||
*target;
|
||||
alignment_tolerance = 0.0;
|
||||
deceleration_radius = 0.0;
|
||||
time_to_reach = 0.1;
|
||||
@ -105,10 +98,10 @@ GSAIMatchOrientation::GSAIMatchOrientation() {
|
||||
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");
|
||||
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);
|
||||
@ -126,7 +119,7 @@ static void GSAIMatchOrientation::_bind_methods() {
|
||||
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");
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_match_orientation", PropertyInfo(Variant::OBJECT, "acceleration", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), PropertyInfo(Variant::REAL, "desired_orientation")));
|
||||
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);
|
||||
}
|
||||
|
@ -1,12 +1,19 @@
|
||||
#ifndef GSAI_MATCH_ORIENTATION_H
|
||||
#define GSAI_MATCH_ORIENTATION_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "../gsai_steering_behavior.h"
|
||||
|
||||
class GSAIAgentLocation;
|
||||
class GSAITargetAcceleration;
|
||||
|
||||
class GSAIMatchOrientation : public GSAISteeringBehavior {
|
||||
GDCLASS(GSAIMatchOrientation, GSAISteeringBehavior);
|
||||
|
||||
public:
|
||||
GSAIAgentLocation get_ *target();
|
||||
void set_ *target(const GSAIAgentLocation &val);
|
||||
Ref<GSAIAgentLocation> get_target();
|
||||
void set_target(const Ref<GSAIAgentLocation> &val);
|
||||
|
||||
float get_alignment_tolerance() const;
|
||||
void set_alignment_tolerance(const float val);
|
||||
@ -20,9 +27,10 @@ public:
|
||||
bool get_use_z() const;
|
||||
void set_use_z(const bool val);
|
||||
|
||||
void match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
||||
void _match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||
void match_orientation(const Ref<GSAITargetAcceleration> &acceleration, const float desired_orientation);
|
||||
void _match_orientation(Ref<GSAITargetAcceleration> acceleration, float desired_orientation);
|
||||
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
|
||||
|
||||
GSAIMatchOrientation();
|
||||
~GSAIMatchOrientation();
|
||||
@ -35,17 +43,17 @@ protected:
|
||||
// velocity.
|
||||
// @category - Individual behaviors
|
||||
// The target orientation for the behavior to try and match rotations to.
|
||||
GSAIAgentLocation *target;
|
||||
Ref<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;
|
||||
float alignment_tolerance;
|
||||
// The amount of distance in radians from the goal to start slowing down.
|
||||
float deceleration_radius = 0.0;
|
||||
float deceleration_radius;
|
||||
// The amount of time to reach the target velocity
|
||||
float time_to_reach = 0.1;
|
||||
float time_to_reach;
|
||||
// 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;
|
||||
bool use_z;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
|
||||
#include "gsai_priority.h"
|
||||
|
||||
#include "../gsai_target_acceleration.h"
|
||||
|
||||
float GSAIPriority::get_zero_threshold() const {
|
||||
return zero_threshold;
|
||||
}
|
||||
@ -9,112 +11,66 @@ void GSAIPriority::set_zero_threshold(const float val) {
|
||||
zero_threshold = val;
|
||||
}
|
||||
|
||||
int GSAIPriority::get__last_selected_index() const {
|
||||
return _last_selected_index;
|
||||
void GSAIPriority::add_behavior(const Ref<GSAISteeringBehavior> &behavior) {
|
||||
_behaviors.push_back(behavior);
|
||||
}
|
||||
|
||||
void GSAIPriority::set__last_selected_index(const int val) {
|
||||
_last_selected_index = val;
|
||||
}
|
||||
Ref<GSAISteeringBehavior> GSAIPriority::get_behavior(const int index) {
|
||||
ERR_FAIL_INDEX_V(index, _behaviors.size(), Ref<GSAISteeringBehavior>());
|
||||
|
||||
Array GSAIPriority::get__behaviors() {
|
||||
return _behaviors;
|
||||
}
|
||||
|
||||
void GSAIPriority::set__behaviors(const Array &val) {
|
||||
_behaviors = val;
|
||||
}
|
||||
|
||||
// Container for multiple behaviors that returns the result of the first child;
|
||||
// behavior with non-zero acceleration.;
|
||||
// @category - Combination behaviors;
|
||||
// If a behavior's acceleration is lower than this threshold, the container;
|
||||
// considers it has an acceleration of zero.;
|
||||
float zero_threshold = 0.0;
|
||||
// The index of the last behavior the container prioritized.;
|
||||
int _last_selected_index = 0;
|
||||
Array _behaviors = Array();
|
||||
// Appends a steering behavior as a child of this container.;
|
||||
|
||||
void GSAIPriority::add_behavior(const GSAISteeringBehavior &behavior) {
|
||||
_behaviors.append(behavior);
|
||||
}
|
||||
|
||||
// Returns the behavior at the position in the pool referred to by `index`, or;
|
||||
// `null` if no behavior was found.;
|
||||
|
||||
GSAISteeringBehavior GSAIPriority::get_behavior(const int index) {
|
||||
if (_behaviors.size() > index) {
|
||||
return _behaviors[index];
|
||||
}
|
||||
|
||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||
return null;
|
||||
return _behaviors[index];
|
||||
}
|
||||
|
||||
void GSAIPriority::remove_behavior(const int index) {
|
||||
if (_behaviors.size() > index) {
|
||||
_behaviors.remove(index);
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_INDEX(index, _behaviors.size());
|
||||
|
||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||
return;
|
||||
_behaviors.remove(index);
|
||||
}
|
||||
|
||||
int GSAIPriority::get_behaviour_count() {
|
||||
return _behaviors.size();
|
||||
}
|
||||
|
||||
void GSAIPriority::_calculate_steering(const GSAITargetAcceleration &accel) {
|
||||
void GSAIPriority::_calculate_steering(Ref<GSAITargetAcceleration> accel) {
|
||||
float threshold_squared = zero_threshold * zero_threshold;
|
||||
_last_selected_index = -1;
|
||||
int size = _behaviors.size();
|
||||
|
||||
if (size > 0) {
|
||||
for (int i = 0; i < size; ++i) { //i in range(size)
|
||||
_last_selected_index = i;
|
||||
GSAISteeringBehavior *behavior = _behaviors[i];
|
||||
behavior.calculate_steering(accel);
|
||||
|
||||
if (accel.get_magnitude_squared() > threshold_squared) {
|
||||
Ref<GSAISteeringBehavior> behavior = _behaviors[i];
|
||||
|
||||
ERR_CONTINUE(!behavior.is_valid());
|
||||
|
||||
_last_selected_index = i;
|
||||
|
||||
behavior->calculate_steering(accel);
|
||||
|
||||
if (accel->get_magnitude_squared() > threshold_squared) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
accel->set_zero();
|
||||
}
|
||||
|
||||
else {
|
||||
accel.set_zero();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSAIPriority::GSAIPriority() {
|
||||
zero_threshold = 0.0;
|
||||
_last_selected_index = 0;
|
||||
_behaviors = Array();
|
||||
}
|
||||
|
||||
GSAIPriority::~GSAIPriority() {
|
||||
}
|
||||
|
||||
static void GSAIPriority::_bind_methods() {
|
||||
void GSAIPriority::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_zero_threshold"), &GSAIPriority::get_zero_threshold);
|
||||
ClassDB::bind_method(D_METHOD("set_zero_threshold", "value"), &GSAIPriority::set_zero_threshold);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "zero_threshold"), "set_zero_threshold", "get_zero_threshold");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get__last_selected_index"), &GSAIPriority::get__last_selected_index);
|
||||
ClassDB::bind_method(D_METHOD("set__last_selected_index", "value"), &GSAIPriority::set__last_selected_index);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_last_selected_index"), "set__last_selected_index", "get__last_selected_index");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get__behaviors"), &GSAIPriority::get__behaviors);
|
||||
ClassDB::bind_method(D_METHOD("set__behaviors", "value"), &GSAIPriority::set__behaviors);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_behaviors"), "set__behaviors", "get__behaviors");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_behavior", "behavior"), &GSAIPriority::add_behavior);
|
||||
ClassDB::bind_method(D_METHOD("get_behavior", "index"), &GSAIPriority::get_behavior);
|
||||
ClassDB::bind_method(D_METHOD("remove_behavior", "index"), &GSAIPriority::remove_behavior);
|
||||
ClassDB::bind_method(D_METHOD("get_behaviour_count"), &GSAIPriority::get_behaviour_count);
|
||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "accel"), &GSAIPriority::_calculate_steering);
|
||||
}
|
||||
|
@ -1,6 +1,13 @@
|
||||
#ifndef GSAI_PRIORITY_H
|
||||
#define GSAI_PRIORITY_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "../gsai_steering_behavior.h"
|
||||
|
||||
class GSAISteeringBehavior;
|
||||
class GSAITargetAcceleration;
|
||||
|
||||
class GSAIPriority : public GSAISteeringBehavior {
|
||||
GDCLASS(GSAIPriority, GSAISteeringBehavior);
|
||||
|
||||
@ -8,17 +15,12 @@ public:
|
||||
float get_zero_threshold() const;
|
||||
void set_zero_threshold(const float val);
|
||||
|
||||
int get__last_selected_index() const;
|
||||
void set__last_selected_index(const int val);
|
||||
|
||||
Array get__behaviors();
|
||||
void set__behaviors(const Array &val);
|
||||
|
||||
void add_behavior(const GSAISteeringBehavior &behavior);
|
||||
GSAISteeringBehavior get_behavior(const int index);
|
||||
void add_behavior(const Ref<GSAISteeringBehavior> &behavior);
|
||||
Ref<GSAISteeringBehavior> get_behavior(const int index);
|
||||
void remove_behavior(const int index);
|
||||
int get_behaviour_count();
|
||||
void _calculate_steering(const GSAITargetAcceleration &accel);
|
||||
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> accel);
|
||||
|
||||
GSAIPriority();
|
||||
~GSAIPriority();
|
||||
@ -31,10 +33,10 @@ protected:
|
||||
// @category - Combination behaviors
|
||||
// If a behavior's acceleration is lower than this threshold, the container
|
||||
// considers it has an acceleration of zero.
|
||||
float zero_threshold = 0.0;
|
||||
float zero_threshold;
|
||||
// The index of the last behavior the container prioritized.
|
||||
int _last_selected_index = 0;
|
||||
Array _behaviors = Array();
|
||||
int _last_selected_index;
|
||||
Vector<Ref<GSAISteeringBehavior>> _behaviors;
|
||||
// Appends a steering behavior as a child of this container.
|
||||
// Returns the behavior at the position in the pool referred to by `index`, or
|
||||
// `null` if no behavior was found.
|
||||
|
@ -1,12 +1,17 @@
|
||||
|
||||
#include "gsai_pursue.h"
|
||||
|
||||
GSAISteeringAgent GSAIPursue::get_ *target() {
|
||||
return *target;
|
||||
#include "core/math/math_funcs.h"
|
||||
|
||||
#include "../gsai_steering_agent.h"
|
||||
#include "../gsai_target_acceleration.h"
|
||||
|
||||
Ref<GSAISteeringAgent> GSAIPursue::get_target() {
|
||||
return target;
|
||||
}
|
||||
|
||||
void GSAIPursue::set_ *target(const GSAISteeringAgent &val) {
|
||||
*target = val;
|
||||
void GSAIPursue::set_target(const Ref<GSAISteeringAgent> &val) {
|
||||
target = val;
|
||||
}
|
||||
|
||||
float GSAIPursue::get_predict_time_max() const {
|
||||
@ -17,32 +22,28 @@ void GSAIPursue::set_predict_time_max(const float val) {
|
||||
predict_time_max = val;
|
||||
}
|
||||
|
||||
// Calculates an acceleration to make an agent intercept another based on the;
|
||||
// target agent's movement.;
|
||||
// @category - Individual behaviors;
|
||||
// The target agent that the behavior is trying to intercept.;
|
||||
GSAISteeringAgent *target;
|
||||
// The maximum amount of time in the future the behavior predicts the target's;
|
||||
// location.;
|
||||
float predict_time_max = 1.0;
|
||||
void GSAIPursue::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
|
||||
ERR_FAIL_COND(!target.is_valid());
|
||||
ERR_FAIL_COND(!agent.is_valid());
|
||||
|
||||
void GSAIPursue::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||
Vector3 target_position = target.position;
|
||||
float distance_squared = (target_position - agent.position).length_squared();
|
||||
float speed_squared = agent.linear_velocity.length_squared();
|
||||
Vector3 target_position = target->get_position();
|
||||
float distance_squared = (target_position - agent->get_position()).length_squared();
|
||||
float speed_squared = agent->get_linear_velocity().length_squared();
|
||||
float predict_time = predict_time_max;
|
||||
|
||||
if (speed_squared > 0) {
|
||||
Variant predict_time_squared = distance_squared / speed_squared;
|
||||
float predict_time_squared = distance_squared / speed_squared;
|
||||
|
||||
if (predict_time_squared < predict_time_max * predict_time_max) {
|
||||
predict_time = sqrt(predict_time_squared);
|
||||
predict_time = Math::sqrt(predict_time_squared);
|
||||
}
|
||||
}
|
||||
|
||||
acceleration.linear = ((target_position + (target.linear_velocity * predict_time)) - agent.position).normalized();
|
||||
acceleration.linear *= get_modified_acceleration();
|
||||
acceleration.angular = 0;
|
||||
Vector3 linear = ((target_position + (target->get_linear_velocity() * predict_time)) - agent->get_position()).normalized();
|
||||
linear *= get_modified_acceleration();
|
||||
|
||||
acceleration->set_linear(linear);
|
||||
acceleration->set_angular(0);
|
||||
}
|
||||
|
||||
float GSAIPursue::get_modified_acceleration() {
|
||||
@ -50,28 +51,28 @@ float GSAIPursue::get_modified_acceleration() {
|
||||
}
|
||||
|
||||
float GSAIPursue::_get_modified_acceleration() {
|
||||
return agent.linear_acceleration_max;
|
||||
}
|
||||
ERR_FAIL_COND_V(!agent.is_valid(), 0);
|
||||
|
||||
return agent->get_linear_acceleration_max();
|
||||
}
|
||||
|
||||
GSAIPursue::GSAIPursue() {
|
||||
*target;
|
||||
predict_time_max = 1.0;
|
||||
}
|
||||
|
||||
GSAIPursue::~GSAIPursue() {
|
||||
}
|
||||
|
||||
static void GSAIPursue::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIPursue::get_ * target);
|
||||
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIPursue::set_ * target);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*target", "get_*target");
|
||||
void GSAIPursue::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_target"), &GSAIPursue::get_target);
|
||||
ClassDB::bind_method(D_METHOD("set_target", "value"), &GSAIPursue::set_target);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "target", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_target", "get_target");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_predict_time_max"), &GSAIPursue::get_predict_time_max);
|
||||
ClassDB::bind_method(D_METHOD("set_predict_time_max", "value"), &GSAIPursue::set_predict_time_max);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "predict_time_max"), "set_predict_time_max", "get_predict_time_max");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIPursue::_calculate_steering);
|
||||
BIND_VMETHOD(MethodInfo(Variant::REAL, "_get_modified_acceleration"));
|
||||
ClassDB::bind_method(D_METHOD("get_modified_acceleration"), &GSAIPursue::get_modified_acceleration);
|
||||
ClassDB::bind_method(D_METHOD("_get_modified_acceleration"), &GSAIPursue::_get_modified_acceleration);
|
||||
}
|
||||
|
@ -1,19 +1,26 @@
|
||||
#ifndef GSAI_PURSUE_H
|
||||
#define GSAI_PURSUE_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "../gsai_steering_behavior.h"
|
||||
|
||||
class GSAISteeringAgent;
|
||||
class GSAITargetAcceleration;
|
||||
|
||||
class GSAIPursue : public GSAISteeringBehavior {
|
||||
GDCLASS(GSAIPursue, GSAISteeringBehavior);
|
||||
|
||||
public:
|
||||
GSAISteeringAgent get_ *target();
|
||||
void set_ *target(const GSAISteeringAgent &val);
|
||||
Ref<GSAISteeringAgent> get_target();
|
||||
void set_target(const Ref<GSAISteeringAgent> &val);
|
||||
|
||||
float get_predict_time_max() const;
|
||||
void set_predict_time_max(const float val);
|
||||
|
||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
|
||||
float get_modified_acceleration();
|
||||
float _get_modified_acceleration();
|
||||
virtual float _get_modified_acceleration();
|
||||
|
||||
GSAIPursue();
|
||||
~GSAIPursue();
|
||||
@ -25,10 +32,10 @@ protected:
|
||||
// target agent's movement.
|
||||
// @category - Individual behaviors
|
||||
// The target agent that the behavior is trying to intercept.
|
||||
GSAISteeringAgent *target;
|
||||
Ref<GSAISteeringAgent> target;
|
||||
// The maximum amount of time in the future the behavior predicts the target's
|
||||
// location.
|
||||
float predict_time_max = 1.0;
|
||||
float predict_time_max;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,37 +1,34 @@
|
||||
|
||||
#include "gsai_seek.h"
|
||||
|
||||
GSAIAgentLocation GSAISeek::get_ *target() {
|
||||
return *target;
|
||||
#include "../gsai_agent_location.h"
|
||||
#include "../gsai_steering_agent.h"
|
||||
#include "../gsai_target_acceleration.h"
|
||||
|
||||
Ref<GSAIAgentLocation> GSAISeek::get_target() {
|
||||
return target;
|
||||
}
|
||||
|
||||
void GSAISeek::set_ *target(const GSAIAgentLocation &val) {
|
||||
*target = val;
|
||||
void GSAISeek::set_target(const Ref<GSAIAgentLocation> &val) {
|
||||
target = val;
|
||||
}
|
||||
|
||||
// Calculates an acceleration to take an agent to a target agent's position;
|
||||
// directly.;
|
||||
// @category - Individual behaviors;
|
||||
// The target that the behavior aims to move the agent to.;
|
||||
GSAIAgentLocation *target;
|
||||
void GSAISeek::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
|
||||
ERR_FAIL_COND(!agent.is_valid());
|
||||
ERR_FAIL_COND(!target.is_valid());
|
||||
|
||||
void GSAISeek::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||
acceleration.linear = ((target.position - agent.position).normalized() * agent.linear_acceleration_max);
|
||||
acceleration.angular = 0;
|
||||
}
|
||||
acceleration->set_linear(((target->get_position() - agent->get_position()).normalized() * agent->get_linear_acceleration_max()));
|
||||
acceleration->set_angular(0);
|
||||
}
|
||||
|
||||
GSAISeek::GSAISeek() {
|
||||
*target;
|
||||
}
|
||||
|
||||
GSAISeek::~GSAISeek() {
|
||||
}
|
||||
|
||||
static void GSAISeek::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_*target"), &GSAISeek::get_ * target);
|
||||
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAISeek::set_ * target);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAISeek::_calculate_steering);
|
||||
void GSAISeek::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_target"), &GSAISeek::get_target);
|
||||
ClassDB::bind_method(D_METHOD("set_target", "value"), &GSAISeek::set_target);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_target", "get_target");
|
||||
}
|
||||
|
@ -1,14 +1,21 @@
|
||||
#ifndef GSAI_SEEK_H
|
||||
#define GSAI_SEEK_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "../gsai_steering_behavior.h"
|
||||
|
||||
class GSAITargetAcceleration;
|
||||
class GSAIAgentLocation;
|
||||
|
||||
class GSAISeek : public GSAISteeringBehavior {
|
||||
GDCLASS(GSAISeek, GSAISteeringBehavior);
|
||||
|
||||
public:
|
||||
GSAIAgentLocation get_ *target();
|
||||
void set_ *target(const GSAIAgentLocation &val);
|
||||
Ref<GSAIAgentLocation> get_target();
|
||||
void set_target(const Ref<GSAIAgentLocation> &val);
|
||||
|
||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
|
||||
|
||||
GSAISeek();
|
||||
~GSAISeek();
|
||||
@ -20,7 +27,7 @@ protected:
|
||||
// directly.
|
||||
// @category - Individual behaviors
|
||||
// The target that the behavior aims to move the agent to.
|
||||
GSAIAgentLocation *target;
|
||||
Ref<GSAIAgentLocation> target;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,10 @@
|
||||
|
||||
#include "gsai_separation.h"
|
||||
|
||||
#include "../gsai_steering_agent.h"
|
||||
#include "../gsai_target_acceleration.h"
|
||||
#include "../proximities/gsai_proximity.h"
|
||||
|
||||
float GSAISeparation::get_decay_coefficient() const {
|
||||
return decay_coefficient;
|
||||
}
|
||||
@ -9,68 +13,54 @@ void GSAISeparation::set_decay_coefficient(const float val) {
|
||||
decay_coefficient = val;
|
||||
}
|
||||
|
||||
GSAITargetAcceleration GSAISeparation::get_ *acceleration() {
|
||||
return *acceleration;
|
||||
Ref<GSAITargetAcceleration> GSAISeparation::get_acceleration() {
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
void GSAISeparation::set_ *acceleration(const GSAITargetAcceleration &val) {
|
||||
*acceleration = val;
|
||||
void GSAISeparation::set_acceleration(const Ref<GSAITargetAcceleration> &val) {
|
||||
acceleration = val;
|
||||
}
|
||||
|
||||
// Calculates an acceleration that repels the agent from its neighbors in the;
|
||||
// given `GSAIProximity`.;
|
||||
//;
|
||||
// The acceleration is an average based on all neighbors, multiplied by a;
|
||||
// strength decreasing by the inverse square law in relation to distance, and it;
|
||||
// accumulates.;
|
||||
// @category - Group behaviors;
|
||||
// The coefficient to calculate how fast the separation strength decays with distance.;
|
||||
float decay_coefficient = 1.0;
|
||||
GSAITargetAcceleration *acceleration;
|
||||
void GSAISeparation::_calculate_steering(Ref<GSAITargetAcceleration> p_acceleration) {
|
||||
acceleration = p_acceleration;
|
||||
|
||||
void GSAISeparation::_calculate_steering(const GSAITargetAcceleration &_acceleration) {
|
||||
self.acceleration = _acceleration;
|
||||
acceleration.set_zero();
|
||||
// warning-ignore:return_value_discarded;
|
||||
proximity.find_neighbors(_callback);
|
||||
acceleration->set_zero();
|
||||
|
||||
ERR_FAIL_COND(!proximity.is_valid());
|
||||
|
||||
proximity->find_neighbors(_callback);
|
||||
}
|
||||
|
||||
// Callback for the proximity to call when finding neighbors. Determines the amount of;
|
||||
// acceleration that `neighbor` imposes based on its distance from the owner agent.;
|
||||
// @tags - virtual;
|
||||
bool GSAISeparation::_report_neighbor(Ref<GSAISteeringAgent> p_neighbor) {
|
||||
ERR_FAIL_COND_V(!agent.is_valid(), false);
|
||||
|
||||
bool GSAISeparation::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
||||
Vector3 to_agent = agent.position - neighbor.position;
|
||||
Vector3 to_agent = agent->get_position() - p_neighbor->get_position();
|
||||
float distance_squared = to_agent.length_squared();
|
||||
float acceleration_max = agent.linear_acceleration_max;
|
||||
Variant strength = decay_coefficient / distance_squared;
|
||||
float acceleration_max = agent->get_linear_acceleration_max();
|
||||
float strength = decay_coefficient / distance_squared;
|
||||
|
||||
if (strength > acceleration_max) {
|
||||
strength = acceleration_max;
|
||||
}
|
||||
|
||||
acceleration.linear += to_agent * (strength / sqrt(distance_squared));
|
||||
acceleration->set_linear(acceleration->get_linear() + to_agent * (strength / sqrt(distance_squared)));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
GSAISeparation::GSAISeparation() {
|
||||
decay_coefficient = 1.0;
|
||||
*acceleration;
|
||||
}
|
||||
|
||||
GSAISeparation::~GSAISeparation() {
|
||||
}
|
||||
|
||||
static void GSAISeparation::_bind_methods() {
|
||||
void GSAISeparation::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_decay_coefficient"), &GSAISeparation::get_decay_coefficient);
|
||||
ClassDB::bind_method(D_METHOD("set_decay_coefficient", "value"), &GSAISeparation::set_decay_coefficient);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "decay_coefficient"), "set_decay_coefficient", "get_decay_coefficient");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_*acceleration"), &GSAISeparation::get_ * acceleration);
|
||||
ClassDB::bind_method(D_METHOD("set_*acceleration", "value"), &GSAISeparation::set_ * acceleration);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*acceleration", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), "set_*acceleration", "get_*acceleration");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "_acceleration"), &GSAISeparation::_calculate_steering);
|
||||
ClassDB::bind_method(D_METHOD("_report_neighbor", "neighbor"), &GSAISeparation::_report_neighbor);
|
||||
ClassDB::bind_method(D_METHOD("get_acceleration"), &GSAISeparation::get_acceleration);
|
||||
ClassDB::bind_method(D_METHOD("set_acceleration", "value"), &GSAISeparation::set_acceleration);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "acceleration", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), "set_acceleration", "get_acceleration");
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
#ifndef GSAI_SEPARATION_H
|
||||
#define GSAI_SEPARATION_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "../gsai_group_behavior.h"
|
||||
|
||||
class GSAITargetAcceleration;
|
||||
|
||||
class GSAISeparation : public GSAIGroupBehavior {
|
||||
GDCLASS(GSAISeparation, GSAIGroupBehavior);
|
||||
|
||||
@ -8,11 +14,11 @@ public:
|
||||
float get_decay_coefficient() const;
|
||||
void set_decay_coefficient(const float val);
|
||||
|
||||
GSAITargetAcceleration get_ *acceleration();
|
||||
void set_ *acceleration(const GSAITargetAcceleration &val);
|
||||
Ref<GSAITargetAcceleration> get_acceleration();
|
||||
void set_acceleration(const Ref<GSAITargetAcceleration> &val);
|
||||
|
||||
void _calculate_steering(const GSAITargetAcceleration &_acceleration);
|
||||
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
||||
void _calculate_steering(Ref<GSAITargetAcceleration> p_acceleration);
|
||||
bool _report_neighbor(Ref<GSAISteeringAgent> p_neighbor);
|
||||
|
||||
GSAISeparation();
|
||||
~GSAISeparation();
|
||||
@ -28,8 +34,8 @@ protected:
|
||||
// accumulates.
|
||||
// @category - Group behaviors
|
||||
// The coefficient to calculate how fast the separation strength decays with distance.
|
||||
float decay_coefficient = 1.0;
|
||||
GSAITargetAcceleration *acceleration;
|
||||
float decay_coefficient;
|
||||
Ref<GSAITargetAcceleration> acceleration;
|
||||
// Callback for the proximity to call when finding neighbors. Determines the amount of
|
||||
// acceleration that `neighbor` imposes based on its distance from the owner agent.
|
||||
// @tags - virtual
|
||||
|
@ -20,7 +20,7 @@ void GSAIGroupBehavior::set_callback(const Ref<FuncRef> &val) {
|
||||
_callback = val;
|
||||
}
|
||||
|
||||
bool GSAIGroupBehavior::_report_neighbor(const Ref<GSAISteeringAgent> &neighbor) {
|
||||
bool GSAIGroupBehavior::_report_neighbor(Ref<GSAISteeringAgent> neighbor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
Ref<FuncRef> get_callback();
|
||||
void set_callback(const Ref<FuncRef> &val);
|
||||
|
||||
virtual bool _report_neighbor(const Ref<GSAISteeringAgent> &neighbor);
|
||||
virtual bool _report_neighbor(Ref<GSAISteeringAgent> neighbor);
|
||||
|
||||
GSAIGroupBehavior();
|
||||
~GSAIGroupBehavior();
|
||||
|
Loading…
Reference in New Issue
Block a user