Behaviors cleanup part2.

This commit is contained in:
Relintai 2023-01-14 02:31:42 +01:00
parent 9bca0fae16
commit 6f27129fe5
13 changed files with 185 additions and 311 deletions

View File

@ -19,6 +19,7 @@ public:
void arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
void _arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
void _calculate_steering(const GSAITargetAcceleration &acceleration);
GSAIArrive();

View File

@ -1,96 +1,45 @@
#include "gsai_avoid_collisions.h"
GSAISteeringAgent GSAIAvoidCollisions::get_ *_first_neighbor() {
return *_first_neighbor;
}
#include "../gsai_steering_agent.h"
#include "../gsai_target_acceleration.h"
#include "../proximities/gsai_proximity.h"
void GSAIAvoidCollisions::set_ *_first_neighbor(const GSAISteeringAgent &val) {
*_first_neighbor = val;
}
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
float GSAIAvoidCollisions::get__shortest_time() const {
return _shortest_time;
}
void GSAIAvoidCollisions::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
ERR_FAIL_COND(!proximity.is_valid());
ERR_FAIL_COND(!agent.is_valid());
void GSAIAvoidCollisions::set__shortest_time(const float val) {
_shortest_time = val;
}
float GSAIAvoidCollisions::get__first_minimum_separation() const {
return _first_minimum_separation;
}
void GSAIAvoidCollisions::set__first_minimum_separation(const float val) {
_first_minimum_separation = val;
}
float GSAIAvoidCollisions::get__first_distance() const {
return _first_distance;
}
void GSAIAvoidCollisions::set__first_distance(const float val) {
_first_distance = val;
}
Vector3 GSAIAvoidCollisions::get__first_relative_position() {
return _first_relative_position;
}
void GSAIAvoidCollisions::set__first_relative_position(const Vector3 &val) {
_first_relative_position = val;
}
Vector3 GSAIAvoidCollisions::get__first_relative_velocity() {
return _first_relative_velocity;
}
void GSAIAvoidCollisions::set__first_relative_velocity(const Vector3 &val) {
_first_relative_velocity = val;
}
// Steers the agent to avoid obstacles in its path. Approximates obstacles as;
// spheres.;
// @category - Group behaviors;
GSAISteeringAgent *_first_neighbor;
float _shortest_time = 0.0;
float _first_minimum_separation = 0.0;
float _first_distance = 0.0;
Vector3 _first_relative_position = ;
Vector3 _first_relative_velocity = ;
void GSAIAvoidCollisions::_calculate_steering(const GSAITargetAcceleration &acceleration) {
_shortest_time = INF;
_first_neighbor = null;
_shortest_time = Math_INF;
_first_neighbor.unref();
_first_minimum_separation = 0;
_first_distance = 0;
int neighbor_count = proximity.find_neighbors(_callback);
int neighbor_count = proximity->find_neighbors(_callback);
if (neighbor_count == 0 || not _first_neighbor) {
acceleration.set_zero();
}
Vector3 linear = acceleration->get_linear();
else {
if ((_first_minimum_separation <= 0 || _first_distance < agent.bounding_radius + _first_neighbor.bounding_radius)) {
acceleration.linear = _first_neighbor.position - agent.position;
}
else {
acceleration.linear = (_first_relative_position + (_first_relative_velocity * _shortest_time));
if (neighbor_count == 0 || !_first_neighbor.is_valid()) {
acceleration->set_zero();
} else {
if ((_first_minimum_separation <= 0 || _first_distance < agent->get_bounding_radius() + _first_neighbor->get_bounding_radius())) {
linear = _first_neighbor->get_position() - agent->get_position();
} else {
linear = (_first_relative_position + (_first_relative_velocity * _shortest_time));
}
}
acceleration.linear = (acceleration.linear.normalized() * -agent.linear_acceleration_max);
acceleration.angular = 0;
linear = (linear.normalized() * -agent->get_linear_acceleration_max());
acceleration->set_linear(linear);
acceleration->set_angular(0);
}
// Callback for the proximity to call when finding neighbors. Keeps track of every `neighbor`;
// that was found but only keeps the one the owning agent will most likely collide with.;
// @tags - virtual;
bool GSAIAvoidCollisions::_report_neighbor(Ref<GSAISteeringAgent> neighbor) {
ERR_FAIL_COND_V(!agent.is_valid(), false);
bool GSAIAvoidCollisions::_report_neighbor(const GSAISteeringAgent &neighbor) {
Vector3 relative_position = neighbor.position - agent.position;
Vector3 relative_velocity = neighbor.linear_velocity - agent.linear_velocity;
Vector3 relative_position = neighbor->get_position() - agent->get_position();
Vector3 relative_velocity = neighbor->get_linear_velocity() - agent->get_linear_velocity();
float relative_speed_squared = relative_velocity.length_squared();
if (relative_speed_squared == 0) {
@ -102,17 +51,13 @@ bool GSAIAvoidCollisions::_report_neighbor(const GSAISteeringAgent &neighbor) {
if (time_to_collision <= 0 || time_to_collision >= _shortest_time) {
return false;
}
} else {
float distance = relative_position.length();
float minimum_separation = (distance - Math::sqrt(relative_speed_squared) * time_to_collision);
else {
Variant = relative_position.length();
float minimum_separation = (distance - sqrt(relative_speed_squared) * time_to_collision);
if (minimum_separation > agent.bounding_radius + neighbor.bounding_radius) {
if (minimum_separation > agent->get_bounding_radius() + neighbor->get_bounding_radius()) {
return false;
}
else {
} else {
_shortest_time = time_to_collision;
_first_neighbor = neighbor;
_first_minimum_separation = minimum_separation;
@ -124,45 +69,15 @@ bool GSAIAvoidCollisions::_report_neighbor(const GSAISteeringAgent &neighbor) {
}
}
}
}
GSAIAvoidCollisions::GSAIAvoidCollisions() {
*_first_neighbor;
_shortest_time = 0.0;
_first_minimum_separation = 0.0;
_first_distance = 0.0;
_first_relative_position = ;
_first_relative_velocity = ;
}
GSAIAvoidCollisions::~GSAIAvoidCollisions() {
}
static void GSAIAvoidCollisions::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_*_first_neighbor"), &GSAIAvoidCollisions::get_ * _first_neighbor);
ClassDB::bind_method(D_METHOD("set_*_first_neighbor", "value"), &GSAIAvoidCollisions::set_ * _first_neighbor);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*_first_neighbor", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*_first_neighbor", "get_*_first_neighbor");
ClassDB::bind_method(D_METHOD("get__shortest_time"), &GSAIAvoidCollisions::get__shortest_time);
ClassDB::bind_method(D_METHOD("set__shortest_time", "value"), &GSAIAvoidCollisions::set__shortest_time);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "_shortest_time"), "set__shortest_time", "get__shortest_time");
ClassDB::bind_method(D_METHOD("get__first_minimum_separation"), &GSAIAvoidCollisions::get__first_minimum_separation);
ClassDB::bind_method(D_METHOD("set__first_minimum_separation", "value"), &GSAIAvoidCollisions::set__first_minimum_separation);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "_first_minimum_separation"), "set__first_minimum_separation", "get__first_minimum_separation");
ClassDB::bind_method(D_METHOD("get__first_distance"), &GSAIAvoidCollisions::get__first_distance);
ClassDB::bind_method(D_METHOD("set__first_distance", "value"), &GSAIAvoidCollisions::set__first_distance);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "_first_distance"), "set__first_distance", "get__first_distance");
ClassDB::bind_method(D_METHOD("get__first_relative_position"), &GSAIAvoidCollisions::get__first_relative_position);
ClassDB::bind_method(D_METHOD("set__first_relative_position", "value"), &GSAIAvoidCollisions::set__first_relative_position);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_first_relative_position"), "set__first_relative_position", "get__first_relative_position");
ClassDB::bind_method(D_METHOD("get__first_relative_velocity"), &GSAIAvoidCollisions::get__first_relative_velocity);
ClassDB::bind_method(D_METHOD("set__first_relative_velocity", "value"), &GSAIAvoidCollisions::set__first_relative_velocity);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_first_relative_velocity"), "set__first_relative_velocity", "get__first_relative_velocity");
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIAvoidCollisions::_calculate_steering);
ClassDB::bind_method(D_METHOD("_report_neighbor", "neighbor"), &GSAIAvoidCollisions::_report_neighbor);
void GSAIAvoidCollisions::_bind_methods() {
}

View File

@ -1,30 +1,19 @@
#ifndef GSAI_AVOID_COLLISIONS_H
#define GSAI_AVOID_COLLISIONS_H
#include "core/object/reference.h"
#include "../gsai_group_behavior.h"
class GSAITargetAcceleration;
class GSAISteeringAgent;
class GSAIAvoidCollisions : public GSAIGroupBehavior {
GDCLASS(GSAIAvoidCollisions, GSAIGroupBehavior);
public:
GSAISteeringAgent get_ *_first_neighbor();
void set_ *_first_neighbor(const GSAISteeringAgent &val);
float get__shortest_time() const;
void set__shortest_time(const float val);
float get__first_minimum_separation() const;
void set__first_minimum_separation(const float val);
float get__first_distance() const;
void set__first_distance(const float val);
Vector3 get__first_relative_position();
void set__first_relative_position(const Vector3 &val);
Vector3 get__first_relative_velocity();
void set__first_relative_velocity(const Vector3 &val);
void _calculate_steering(const GSAITargetAcceleration &acceleration);
bool _report_neighbor(const GSAISteeringAgent &neighbor);
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
bool _report_neighbor(Ref<GSAISteeringAgent> neighbor);
GSAIAvoidCollisions();
~GSAIAvoidCollisions();
@ -35,15 +24,12 @@ protected:
// Steers the agent to avoid obstacles in its path. Approximates obstacles as
// spheres.
// @category - Group behaviors
GSAISteeringAgent *_first_neighbor;
float _shortest_time = 0.0;
float _first_minimum_separation = 0.0;
float _first_distance = 0.0;
Vector3 _first_relative_position = ;
Vector3 _first_relative_velocity = ;
// Callback for the proximity to call when finding neighbors. Keeps track of every `neighbor`
// that was found but only keeps the one the owning agent will most likely collide with.
// @tags - virtual
Ref<GSAISteeringAgent> _first_neighbor;
float _shortest_time;
float _first_minimum_separation;
float _first_distance;
Vector3 _first_relative_position;
Vector3 _first_relative_velocity;
};
#endif

View File

@ -1,108 +1,73 @@
#include "gsai_blend.h"
Array GSAIBlend::get__behaviors() {
return _behaviors;
#include "../gsai_steering_agent.h"
#include "../gsai_target_acceleration.h"
#include "../gsai_utils.h"
void GSAIBlend::add_behavior(const Ref<GSAISteeringBehavior> &behavior, const float weight) {
ERR_FAIL_COND(!behavior.is_valid());
GSAIBlendBehaviorEntry e;
e.behavior = behavior;
e.weight = weight;
_behaviors.push_back(e);
}
void GSAIBlend::set__behaviors(const Array &val) {
_behaviors = val;
Ref<GSAISteeringBehavior> GSAIBlend::get_behavior(const int index) {
ERR_FAIL_INDEX_V(index, _behaviors.size(), Ref<GSAISteeringBehavior>());
return _behaviors[index].behavior;
}
GSAITargetAcceleration GSAIBlend::get_ *_accel() {
return *_accel;
}
float GSAIBlend::get_behavior_weight(const int index) {
ERR_FAIL_INDEX_V(index, _behaviors.size(), 0);
void GSAIBlend::set_ *_accel(const GSAITargetAcceleration &val) {
*_accel = val;
}
// Blends multiple steering behaviors into one, and returns a weighted;
// acceleration from their calculations.;
//;
// Stores the behaviors internally as dictionaries of the form;
// {;
// behavior : GSAISteeringBehavior,;
// weight : float;
// };
// @category - Combination behaviors;
Array _behaviors = Array();
GSAITargetAcceleration *_accel = GSAITargetAcceleration.new();
// Appends a behavior to the internal array along with its `weight`.;
void GSAIBlend::add_behavior(const GSAISteeringBehavior &behavior, const float weight) {
behavior.agent = agent;
Dictionary dict = Dictionary();
dict["behavior"] = behavior;
dict["weight"] = weight;
_behaviors.append(dict);
}
// Returns the behavior at the specified `index`, or an empty `Dictionary` if;
// none was found.;
Dictionary GSAIBlend::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 Dictionary();
return _behaviors[index].weight;
}
void GSAIBlend::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 GSAIBlend::get_behaviour_count() {
return _behaviors.size();
}
GSAITargetAcceleration GSAIBlend::get_accel() {
Ref<GSAITargetAcceleration> GSAIBlend::get_accel() {
return _accel;
}
void GSAIBlend::_calculate_steering(const GSAITargetAcceleration &blended_accel) {
blended_accel.set_zero();
void GSAIBlend::_calculate_steering(Ref<GSAITargetAcceleration> blended_accel) {
ERR_FAIL_COND(!agent.is_valid());
blended_accel->set_zero();
for (int i = 0; i < _behaviors.size(); ++i) { //i in range(_behaviors.size())
Dictionary bw = _behaviors[i];
bw.behavior.calculate_steering(_accel);
blended_accel.add_scaled_accel(_accel, bw.weight);
GSAIBlendBehaviorEntry bw = _behaviors[i];
bw.behavior->calculate_steering(_accel);
blended_accel->add_scaled_accel(_accel, bw.weight);
}
blended_accel.linear = GSAIUtils.clampedv3(blended_accel.linear, agent.linear_acceleration_max);
blended_accel.angular = clamp(blended_accel.angular, -agent.angular_acceleration_max, agent.angular_acceleration_max);
}
blended_accel->set_linear(GSAIUtils::clampedv3(blended_accel->get_linear(), agent->get_linear_acceleration_max()));
float angular_acceleration_max = agent->get_angular_acceleration_max();
blended_accel->set_angular(CLAMP(blended_accel->get_angular(), -angular_acceleration_max, angular_acceleration_max));
}
GSAIBlend::GSAIBlend() {
_behaviors = Array();
*_accel = GSAITargetAcceleration.new();
_accel.instance();
}
GSAIBlend::~GSAIBlend() {
}
static void GSAIBlend::_bind_methods() {
ClassDB::bind_method(D_METHOD("get__behaviors"), &GSAIBlend::get__behaviors);
ClassDB::bind_method(D_METHOD("set__behaviors", "value"), &GSAIBlend::set__behaviors);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_behaviors"), "set__behaviors", "get__behaviors");
ClassDB::bind_method(D_METHOD("get_*_accel"), &GSAIBlend::get_ * _accel);
ClassDB::bind_method(D_METHOD("set_*_accel", "value"), &GSAIBlend::set_ * _accel);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*_accel", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), "set_*_accel", "get_*_accel");
void GSAIBlend::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_behavior", "behavior", "weight"), &GSAIBlend::add_behavior);
ClassDB::bind_method(D_METHOD("get_behavior", "index"), &GSAIBlend::get_behavior);
ClassDB::bind_method(D_METHOD("remove_behavior", "index"), &GSAIBlend::remove_behavior);
ClassDB::bind_method(D_METHOD("get_behaviour_count"), &GSAIBlend::get_behaviour_count);
ClassDB::bind_method(D_METHOD("get_accel"), &GSAIBlend::get_accel);
ClassDB::bind_method(D_METHOD("_calculate_steering", "blended_accel"), &GSAIBlend::_calculate_steering);
}

View File

@ -1,40 +1,44 @@
#ifndef GSAI_BLEND_H
#define GSAI_BLEND_H
#include "core/object/reference.h"
#include "../gsai_steering_behavior.h"
class GSAISteeringBehavior;
class GSAITargetAcceleration;
class GSAIBlend : public GSAISteeringBehavior {
GDCLASS(GSAIBlend, GSAISteeringBehavior);
public:
Array get__behaviors();
void set__behaviors(const Array &val);
GSAITargetAcceleration get_ *_accel();
void set_ *_accel(const GSAITargetAcceleration &val);
void add_behavior(const GSAISteeringBehavior &behavior, const float weight);
Dictionary get_behavior(const int index);
void add_behavior(const Ref<GSAISteeringBehavior> &behavior, const float weight);
Ref<GSAISteeringBehavior> get_behavior(const int index);
float get_behavior_weight(const int index);
void remove_behavior(const int index);
int get_behaviour_count();
GSAITargetAcceleration get_accel();
void _calculate_steering(const GSAITargetAcceleration &blended_accel);
Ref<GSAITargetAcceleration> get_accel();
void _calculate_steering(Ref<GSAITargetAcceleration> blended_accel);
GSAIBlend();
~GSAIBlend();
protected:
struct GSAIBlendBehaviorEntry {
Ref<GSAISteeringBehavior> behavior;
float weight;
};
protected:
static void _bind_methods();
// Blends multiple steering behaviors into one, and returns a weighted
// acceleration from their calculations.
//
// Stores the behaviors internally as dictionaries of the form
// {
// behavior : GSAISteeringBehavior,
// weight : float
// }
// @category - Combination behaviors
Array _behaviors = Array();
GSAITargetAcceleration *_accel = GSAITargetAcceleration.new();
Vector<GSAIBlendBehaviorEntry> _behaviors;
Ref<GSAITargetAcceleration> _accel;
// Appends a behavior to the internal array along with its `weight`.
// Returns the behavior at the specified `index`, or an empty `Dictionary` if
// none was found.

View File

@ -1,52 +1,34 @@
#include "gsai_cohesion.h"
Vector3 GSAICohesion::get__center_of_mass() {
return _center_of_mass;
}
#include "../gsai_steering_agent.h"
#include "../gsai_target_acceleration.h"
#include "../proximities/gsai_proximity.h"
void GSAICohesion::set__center_of_mass(const Vector3 &val) {
_center_of_mass = val;
}
void GSAICohesion::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
ERR_FAIL_COND(!proximity.is_valid());
ERR_FAIL_COND(!agent.is_valid());
// Calculates an acceleration that attempts to move the agent towards the center;
// of mass of the agents in the area defined by the `GSAIProximity`.;
// @category - Group behaviors;
Vector3 _center_of_mass = ;
void GSAICohesion::_calculate_steering(const GSAITargetAcceleration &acceleration) {
acceleration.set_zero();
_center_of_mass = Vector3.ZERO;
Variant = proximity.find_neighbors(_callback);
acceleration->set_zero();
_center_of_mass = Vector3();
int neighbor_count = proximity->find_neighbors(_callback);
if (neighbor_count > 0) {
_center_of_mass *= 1.0 / neighbor_count;
acceleration.linear = ((_center_of_mass - agent.position).normalized() * agent.linear_acceleration_max);
acceleration->set_linear((_center_of_mass - agent->get_position()).normalized() * agent->get_linear_acceleration_max());
}
// Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position;
// to the center of mass of the group.;
// @tags - virtual;
}
bool GSAICohesion::_report_neighbor(const GSAISteeringAgent &neighbor) {
_center_of_mass += neighbor.position;
bool GSAICohesion::_report_neighbor(Ref<GSAISteeringAgent> neighbor) {
_center_of_mass += neighbor->get_position();
return true;
}
}
GSAICohesion::GSAICohesion() {
_center_of_mass = ;
}
GSAICohesion::~GSAICohesion() {
}
static void GSAICohesion::_bind_methods() {
ClassDB::bind_method(D_METHOD("get__center_of_mass"), &GSAICohesion::get__center_of_mass);
ClassDB::bind_method(D_METHOD("set__center_of_mass", "value"), &GSAICohesion::set__center_of_mass);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_center_of_mass"), "set__center_of_mass", "get__center_of_mass");
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAICohesion::_calculate_steering);
ClassDB::bind_method(D_METHOD("_report_neighbor", "neighbor"), &GSAICohesion::_report_neighbor);
void GSAICohesion::_bind_methods() {
}

View File

@ -1,15 +1,19 @@
#ifndef GSAI_COHESION_H
#define GSAI_COHESION_H
#include "core/object/reference.h"
#include "../gsai_group_behavior.h"
class GSAITargetAcceleration;
class GSAISteeringAgent;
class GSAICohesion : public GSAIGroupBehavior {
GDCLASS(GSAICohesion, GSAIGroupBehavior);
public:
Vector3 get__center_of_mass();
void set__center_of_mass(const Vector3 &val);
void _calculate_steering(const GSAITargetAcceleration &acceleration);
bool _report_neighbor(const GSAISteeringAgent &neighbor);
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
bool _report_neighbor(Ref<GSAISteeringAgent> neighbor);
GSAICohesion();
~GSAICohesion();
@ -20,7 +24,7 @@ protected:
// Calculates an acceleration that attempts to move the agent towards the center
// of mass of the agents in the area defined by the `GSAIProximity`.
// @category - Group behaviors
Vector3 _center_of_mass = ;
Vector3 _center_of_mass;
};
#endif

View File

@ -1,13 +1,12 @@
#include "gsai_evade.h"
// Calculates acceleration to take an agent away from where a target agent is;
// moving.;
// @category - Individual behaviors;
#include "../gsai_steering_agent.h"
float GSAIEvade::_get_modified_acceleration() {
return -agent.linear_acceleration_max;
}
ERR_FAIL_COND_V(!agent.is_valid(), 0);
return -(agent->get_linear_acceleration_max());
}
GSAIEvade::GSAIEvade() {
@ -16,6 +15,5 @@ GSAIEvade::GSAIEvade() {
GSAIEvade::~GSAIEvade() {
}
static void GSAIEvade::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_modified_acceleration"), &GSAIEvade::_get_modified_acceleration);
void GSAIEvade::_bind_methods() {
}

View File

@ -1,6 +1,10 @@
#ifndef GSAI_EVADE_H
#define GSAI_EVADE_H
#include "core/object/reference.h"
#include "gsai_pursue.h"
class GSAIEvade : public GSAIPursue {
GDCLASS(GSAIEvade, GSAIPursue);

View File

@ -1,40 +1,40 @@
#include "gsai_face.h"
// Calculates angular acceleration to rotate a target to face its target's;
// position. The behavior attemps to arrive with zero remaining angular velocity.;
// @category - Individual behaviors;
#include "../gsai_steering_agent.h"
void GSAIFace::face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
#include "../gsai_target_acceleration.h"
#include "../gsai_utils.h"
void GSAIFace::face(const Ref<GSAITargetAcceleration> &acceleration, const Vector3 &target_position) {
call("_face", acceleration, target_position);
}
void GSAIFace::_face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
Vector3 to_target = target_position - agent.position;
void GSAIFace::_face(Ref<GSAITargetAcceleration> acceleration, Vector3 target_position) {
ERR_FAIL_COND(!agent.is_valid());
Vector3 to_target = target_position - agent->get_position();
float distance_squared = to_target.length_squared();
if (distance_squared < agent.zero_linear_speed_threshold) {
acceleration.set_zero();
}
else {
float orientation = ;
if (distance_squared < agent->get_zero_linear_speed_threshold()) {
acceleration->set_zero();
} else {
float orientation;
if (use_z) {
orientation = GSAIUtils.vector3_to_angle(to_target);
}
else {
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(to_target));
orientation = GSAIUtils::vector3_to_angle(to_target);
} else {
orientation = GSAIUtils::vector2_to_angle(GSAIUtils::to_vector2(to_target));
}
match_orientation(acceleration, orientation);
}
}
void GSAIFace::_calculate_steering(const GSAITargetAcceleration &acceleration) {
face(acceleration, target.position);
}
void GSAIFace::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
ERR_FAIL_COND(!target.is_valid());
face(acceleration, target->get_position());
}
GSAIFace::GSAIFace() {
@ -43,8 +43,8 @@ GSAIFace::GSAIFace() {
GSAIFace::~GSAIFace() {
}
static void GSAIFace::_bind_methods() {
void GSAIFace::_bind_methods() {
BIND_VMETHOD(MethodInfo("_face", PropertyInfo(Variant::OBJECT, "acceleration", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), PropertyInfo(Variant::VECTOR3, "target_position")));
ClassDB::bind_method(D_METHOD("face", "acceleration", "target_position"), &GSAIFace::face);
ClassDB::bind_method(D_METHOD("_face", "acceleration", "target_position"), &GSAIFace::_face);
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFace::_calculate_steering);
}

View File

@ -1,13 +1,20 @@
#ifndef GSAI_FACE_H
#define GSAI_FACE_H
#include "core/object/reference.h"
#include "gsai_match_orientation.h"
class GSAITargetAcceleration;
class GSAIFace : public GSAIMatchOrientation {
GDCLASS(GSAIFace, GSAIMatchOrientation);
public:
void face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
void _face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
void _calculate_steering(const GSAITargetAcceleration &acceleration);
void face(const Ref<GSAITargetAcceleration> &acceleration, const Vector3 &target_position);
void _face(Ref<GSAITargetAcceleration> acceleration, Vector3 target_position);
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
GSAIFace();
~GSAIFace();

View File

@ -1,13 +1,16 @@
#include "gsai_flee.h"
// Calculates acceleration to take an agent directly away from a target agent.;
// @category - Individual behaviors;
#include "../gsai_agent_location.h"
#include "../gsai_steering_agent.h"
#include "../gsai_target_acceleration.h"
void GSAIFlee::_calculate_steering(const GSAITargetAcceleration &acceleration) {
acceleration.linear = ((agent.position - target.position).normalized() * agent.linear_acceleration_max);
acceleration.angular = 0;
}
void GSAIFlee::_calculate_steering(Ref<GSAITargetAcceleration> acceleration) {
ERR_FAIL_COND(!agent.is_valid());
ERR_FAIL_COND(!target.is_valid());
acceleration->set_linear((agent->get_position() - target->get_position()).normalized() * agent->get_linear_acceleration_max());
acceleration->set_angular(0);
}
GSAIFlee::GSAIFlee() {
@ -16,6 +19,5 @@ GSAIFlee::GSAIFlee() {
GSAIFlee::~GSAIFlee() {
}
static void GSAIFlee::_bind_methods() {
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFlee::_calculate_steering);
void GSAIFlee::_bind_methods() {
}

View File

@ -1,11 +1,17 @@
#ifndef GSAI_FLEE_H
#define GSAI_FLEE_H
#include "core/object/reference.h"
#include "gsai_seek.h"
class GSAITargetAcceleration;
class GSAIFlee : public GSAISeek {
GDCLASS(GSAIFlee, GSAISeek);
public:
void _calculate_steering(const GSAITargetAcceleration &acceleration);
void _calculate_steering(Ref<GSAITargetAcceleration> acceleration);
GSAIFlee();
~GSAIFlee();