mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-11-23 01:19:20 +01:00
Behaviors cleanup part2.
This commit is contained in:
parent
9bca0fae16
commit
6f27129fe5
@ -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();
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user