mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-30 21:09:19 +01:00
Cang formatted everything in the new module.
This commit is contained in:
parent
0d2aa86bc3
commit
402e8ff689
@ -1,296 +1,260 @@
|
|||||||
|
|
||||||
#include "gsai_kinematic_body_2d_agent.h"
|
#include "gsai_kinematic_body_2d_agent.h"
|
||||||
|
|
||||||
|
KinematicBody2D GSAIKinematicBody2DAgent::get_ *body() {
|
||||||
KinematicBody2D GSAIKinematicBody2DAgent::get_*body() {
|
return *body;
|
||||||
return *body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::set_*body(const KinematicBody2D &val) {
|
void GSAIKinematicBody2DAgent::set_ *body(const KinematicBody2D &val) {
|
||||||
*body = val;
|
*body = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GSAIKinematicBody2DAgent::get_movement_type() const {
|
int GSAIKinematicBody2DAgent::get_movement_type() const {
|
||||||
return movement_type;
|
return movement_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::set_movement_type(const int val) {
|
void GSAIKinematicBody2DAgent::set_movement_type(const int val) {
|
||||||
movement_type = val;
|
movement_type = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector2 GSAIKinematicBody2DAgent::get__last_position() {
|
Vector2 GSAIKinematicBody2DAgent::get__last_position() {
|
||||||
return _last_position;
|
return _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::set__last_position(const Vector2 &val) {
|
void GSAIKinematicBody2DAgent::set__last_position(const Vector2 &val) {
|
||||||
_last_position = val;
|
_last_position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<WeakRef> GSAIKinematicBody2DAgent::get__body_ref() {
|
Ref<WeakRef> GSAIKinematicBody2DAgent::get__body_ref() {
|
||||||
return _body_ref;
|
return _body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
void GSAIKinematicBody2DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
||||||
_body_ref = val;
|
_body_ref = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does;
|
||||||
|
// not have to using a KinematicBody2D;
|
||||||
|
// @category - Specialized agents;
|
||||||
|
// SLIDE uses `move_and_slide`;
|
||||||
|
// COLLIDE uses `move_and_collide`;
|
||||||
|
// POSITION changes the `global_position` directly;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
// The KinematicBody2D to keep track of;
|
||||||
|
// setget _set_body;
|
||||||
|
KinematicBody2D *body;
|
||||||
|
// The type of movement the body executes;
|
||||||
|
int movement_type = MovementType.SLIDE;
|
||||||
|
Vector2 _last_position = ;
|
||||||
|
Ref<WeakRef> _body_ref;
|
||||||
|
|
||||||
|
void GSAIKinematicBody2DAgent::_body_ready() {
|
||||||
// A specialized steering agent that updates itself every frame so the user does;
|
// warning-ignore:return_value_discarded;
|
||||||
// not have to using a KinematicBody2D;
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
|
||||||
// @category - Specialized agents;
|
|
||||||
// SLIDE uses `move_and_slide`;
|
|
||||||
// COLLIDE uses `move_and_collide`;
|
|
||||||
// POSITION changes the `global_position` directly;
|
|
||||||
};
|
|
||||||
// The KinematicBody2D to keep track of;
|
|
||||||
// setget _set_body;
|
|
||||||
KinematicBody2D *body;
|
|
||||||
// The type of movement the body executes;
|
|
||||||
int movement_type = MovementType.SLIDE;
|
|
||||||
Vector2 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_body_ready() {
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the agent's `body` by target `acceleration`.;
|
// Moves the agent's `body` by target `acceleration`.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
|
void GSAIKinematicBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
|
||||||
applied_steering = true;
|
applied_steering = true;
|
||||||
|
|
||||||
if (movement_type == MovementType.COLLIDE) {
|
if (movement_type == MovementType.COLLIDE) {
|
||||||
_apply_collide_steering(acceleration.linear, delta);
|
_apply_collide_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (movement_type == MovementType.SLIDE) {
|
||||||
|
_apply_sliding_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_apply_position_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
_apply_orientation_steering(acceleration.angular, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody2DAgent::_apply_sliding_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
else if (movement_type == MovementType.SLIDE) {
|
if (!_body) {
|
||||||
_apply_sliding_steering(acceleration.linear, delta);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 velocity = GSAIUtils.to_vector2(linear_velocity + accel * delta).clamped(linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity = _body.move_and_slide(velocity);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = GSAIUtils.to_vector3(velocity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody2DAgent::_apply_collide_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
else {
|
if (!_body) {
|
||||||
_apply_position_steering(acceleration.linear, delta);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning-ignore:return_value_discarded;
|
||||||
|
_body.move_and_collide(GSAIUtils.to_vector2(velocity) * delta);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_apply_orientation_steering(acceleration.angular, delta);
|
void GSAIKinematicBody2DAgent::_apply_position_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
|
if (!_body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_body.global_position += GSAIUtils.to_vector2(velocity) * delta;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody2DAgent::_apply_orientation_steering(const float angular_acceleration, const float delta) {
|
||||||
|
KinematicBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_apply_sliding_steering(const Vector3 &accel, const float delta) {
|
if (!_body) {
|
||||||
KinematicBody2D *_body = _body_ref.get_ref();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_body) {
|
Variant = clamp(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max);
|
||||||
return;
|
|
||||||
|
if (apply_angular_drag) {
|
||||||
|
velocity = lerp(velocity, 0, angular_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_body.rotation += velocity * delta;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
angular_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody2DAgent::_set_body(const KinematicBody2D &value) {
|
||||||
|
bool had_body = false;
|
||||||
|
|
||||||
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
if (body) {
|
||||||
return;
|
had_body = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = value;
|
||||||
|
_body_ref = weakref(body);
|
||||||
|
_last_position = value.global_position;
|
||||||
|
last_orientation = value.rotation;
|
||||||
|
position = GSAIUtils.to_vector3(_last_position);
|
||||||
|
orientation = last_orientation;
|
||||||
|
|
||||||
|
if (!had_body) {
|
||||||
|
if (!body.is_inside_tree()) {
|
||||||
|
body.connect("ready", self, "_body_ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_body_ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 velocity = GSAIUtils.to_vector2(linear_velocity + accel * delta).clamped(linear_speed_max);
|
void GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame() {
|
||||||
|
KinematicBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
if (!_body) {
|
||||||
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag_percentage);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 current_position = _body.global_position;
|
||||||
|
float current_orientation = _body.rotation;
|
||||||
|
position = GSAIUtils.to_vector3(current_position);
|
||||||
|
orientation = current_orientation;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
if (applied_steering) {
|
||||||
|
applied_steering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
linear_velocity = GSAIUtils.clampedv3(GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
angular_velocity = clamp(last_orientation - current_orientation, -angular_speed_max, angular_speed_max);
|
||||||
|
|
||||||
|
if (apply_angular_drag) {
|
||||||
|
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_last_position = current_position;
|
||||||
|
last_orientation = current_orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity = _body.move_and_slide(velocity);
|
GSAIKinematicBody2DAgent::GSAIKinematicBody2DAgent() {
|
||||||
|
*body;
|
||||||
if (calculate_velocities) {
|
movement_type = MovementType.SLIDE;
|
||||||
linear_velocity = GSAIUtils.to_vector3(velocity);
|
_last_position = ;
|
||||||
|
_body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIKinematicBody2DAgent::~GSAIKinematicBody2DAgent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIKinematicBody2DAgent::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIKinematicBody2DAgent::get_ * body);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIKinematicBody2DAgent::set_ * body);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "KinematicBody2D"), "set_*body", "get_*body");
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_apply_collide_steering(const Vector3 &accel, const float delta) {
|
ClassDB::bind_method(D_METHOD("get_movement_type"), &GSAIKinematicBody2DAgent::get_movement_type);
|
||||||
KinematicBody2D *_body = _body_ref.get_ref();
|
ClassDB::bind_method(D_METHOD("set_movement_type", "value"), &GSAIKinematicBody2DAgent::set_movement_type);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "movement_type"), "set_movement_type", "get_movement_type");
|
||||||
|
|
||||||
if (!_body) {
|
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIKinematicBody2DAgent::get__last_position);
|
||||||
return;
|
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIKinematicBody2DAgent::set__last_position);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "_last_position"), "set__last_position", "get__last_position");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIKinematicBody2DAgent::get__body_ref);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIKinematicBody2DAgent::set__body_ref);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIKinematicBody2DAgent::_body_ready);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "delta"), &GSAIKinematicBody2DAgent::_apply_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_sliding_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_sliding_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_collide_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_collide_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_position_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_position_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_orientation_steering", "angular_acceleration", "delta"), &GSAIKinematicBody2DAgent::_apply_orientation_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIKinematicBody2DAgent::_set_body);
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_SceneTree_physics_frame"), &GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
_body.move_and_collide(GSAIUtils.to_vector2(velocity) * delta);
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
linear_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_apply_position_steering(const Vector3 &accel, const float delta) {
|
|
||||||
KinematicBody2D *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_body.global_position += GSAIUtils.to_vector2(velocity) * delta;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
linear_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_apply_orientation_steering(const float angular_acceleration, const float delta) {
|
|
||||||
KinematicBody2D *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant = clamp(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max);
|
|
||||||
|
|
||||||
if (apply_angular_drag) {
|
|
||||||
velocity = lerp(velocity, 0, angular_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_body.rotation += velocity * delta;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
angular_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_set_body(const KinematicBody2D &value) {
|
|
||||||
bool had_body = false;
|
|
||||||
|
|
||||||
if (body) {
|
|
||||||
had_body = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
body = value;
|
|
||||||
_body_ref = weakref(body);
|
|
||||||
_last_position = value.global_position;
|
|
||||||
last_orientation = value.rotation;
|
|
||||||
position = GSAIUtils.to_vector3(_last_position);
|
|
||||||
orientation = last_orientation;
|
|
||||||
|
|
||||||
if (!had_body) {
|
|
||||||
|
|
||||||
if (!body.is_inside_tree()) {
|
|
||||||
body.connect("ready", self, "_body_ready");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
_body_ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame() {
|
|
||||||
KinematicBody2D *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 current_position = _body.global_position;
|
|
||||||
float current_orientation = _body.rotation;
|
|
||||||
position = GSAIUtils.to_vector3(current_position);
|
|
||||||
orientation = current_orientation;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
|
|
||||||
if (applied_steering) {
|
|
||||||
applied_steering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
linear_velocity = GSAIUtils.clampedv3(GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max);
|
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
|
||||||
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
angular_velocity = clamp(last_orientation - current_orientation, -angular_speed_max, angular_speed_max);
|
|
||||||
|
|
||||||
if (apply_angular_drag) {
|
|
||||||
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_last_position = current_position;
|
|
||||||
last_orientation = current_orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIKinematicBody2DAgent::GSAIKinematicBody2DAgent() {
|
|
||||||
*body;
|
|
||||||
movement_type = MovementType.SLIDE;
|
|
||||||
_last_position = ;
|
|
||||||
_body_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIKinematicBody2DAgent::~GSAIKinematicBody2DAgent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIKinematicBody2DAgent::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIKinematicBody2DAgent::get_*body);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIKinematicBody2DAgent::set_*body);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "KinematicBody2D"), "set_*body", "get_*body");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_movement_type"), &GSAIKinematicBody2DAgent::get_movement_type);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_movement_type", "value"), &GSAIKinematicBody2DAgent::set_movement_type);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "movement_type"), "set_movement_type", "get_movement_type");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIKinematicBody2DAgent::get__last_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIKinematicBody2DAgent::set__last_position);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "_last_position"), "set__last_position", "get__last_position");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIKinematicBody2DAgent::get__body_ref);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIKinematicBody2DAgent::set__body_ref);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIKinematicBody2DAgent::_body_ready);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "delta"), &GSAIKinematicBody2DAgent::_apply_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_sliding_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_sliding_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_collide_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_collide_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_position_steering", "accel", "delta"), &GSAIKinematicBody2DAgent::_apply_position_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_orientation_steering", "angular_acceleration", "delta"), &GSAIKinematicBody2DAgent::_apply_orientation_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIKinematicBody2DAgent::_set_body);
|
|
||||||
ClassDB::bind_method(D_METHOD("_on_SceneTree_physics_frame"), &GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,63 +1,61 @@
|
|||||||
#ifndef GSAIKINEMATICBODY2DAGENT_H
|
#ifndef GSAIKINEMATICBODY2DAGENT_H
|
||||||
#define GSAIKINEMATICBODY2DAGENT_H
|
#define GSAIKINEMATICBODY2DAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIKinematicBody2DAgent : public GSAISpecializedAgent {
|
class GSAIKinematicBody2DAgent : public GSAISpecializedAgent {
|
||||||
GDCLASS(GSAIKinematicBody2DAgent, GSAISpecializedAgent);
|
GDCLASS(GSAIKinematicBody2DAgent, GSAISpecializedAgent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
KinematicBody2D get_ *body();
|
||||||
|
void set_ *body(const KinematicBody2D &val);
|
||||||
|
|
||||||
KinematicBody2D get_*body();
|
int get_movement_type() const;
|
||||||
void set_*body(const KinematicBody2D &val);
|
void set_movement_type(const int val);
|
||||||
|
|
||||||
int get_movement_type() const;
|
Vector2 get__last_position();
|
||||||
void set_movement_type(const int val);
|
void set__last_position(const Vector2 &val);
|
||||||
|
|
||||||
Vector2 get__last_position();
|
Ref<WeakRef> get__body_ref();
|
||||||
void set__last_position(const Vector2 &val);
|
void set__body_ref(const Ref<WeakRef> &val);
|
||||||
|
|
||||||
Ref<WeakRef> get__body_ref();
|
enum MovementType {
|
||||||
void set__body_ref(const Ref<WeakRef> &val);
|
|
||||||
|
|
||||||
enum MovementType {
|
SLIDE,
|
||||||
|
COLLIDE,
|
||||||
|
POSITION
|
||||||
|
};
|
||||||
|
|
||||||
SLIDE,
|
void _body_ready();
|
||||||
COLLIDE,
|
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
|
||||||
POSITION
|
void _apply_sliding_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_collide_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_position_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_orientation_steering(const float angular_acceleration, const float delta);
|
||||||
|
void _set_body(const KinematicBody2D &value);
|
||||||
|
void _on_SceneTree_physics_frame();
|
||||||
|
|
||||||
|
GSAIKinematicBody2DAgent();
|
||||||
|
~GSAIKinematicBody2DAgent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does
|
||||||
|
// not have to using a KinematicBody2D
|
||||||
|
// @category - Specialized agents
|
||||||
|
// SLIDE uses `move_and_slide`
|
||||||
|
// COLLIDE uses `move_and_collide`
|
||||||
|
// POSITION changes the `global_position` directly
|
||||||
};
|
};
|
||||||
|
// The KinematicBody2D to keep track of
|
||||||
void _body_ready();
|
// setget _set_body
|
||||||
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
|
KinematicBody2D *body;
|
||||||
void _apply_sliding_steering(const Vector3 &accel, const float delta);
|
// The type of movement the body executes
|
||||||
void _apply_collide_steering(const Vector3 &accel, const float delta);
|
int movement_type = MovementType.SLIDE;
|
||||||
void _apply_position_steering(const Vector3 &accel, const float delta);
|
Vector2 _last_position = ;
|
||||||
void _apply_orientation_steering(const float angular_acceleration, const float delta);
|
Ref<WeakRef> _body_ref;
|
||||||
void _set_body(const KinematicBody2D &value);
|
// Moves the agent's `body` by target `acceleration`.
|
||||||
void _on_SceneTree_physics_frame();
|
// @tags - virtual
|
||||||
|
}
|
||||||
GSAIKinematicBody2DAgent();
|
;
|
||||||
~GSAIKinematicBody2DAgent();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
// A specialized steering agent that updates itself every frame so the user does
|
|
||||||
// not have to using a KinematicBody2D
|
|
||||||
// @category - Specialized agents
|
|
||||||
// SLIDE uses `move_and_slide`
|
|
||||||
// COLLIDE uses `move_and_collide`
|
|
||||||
// POSITION changes the `global_position` directly
|
|
||||||
};
|
|
||||||
// The KinematicBody2D to keep track of
|
|
||||||
// setget _set_body
|
|
||||||
KinematicBody2D *body;
|
|
||||||
// The type of movement the body executes
|
|
||||||
int movement_type = MovementType.SLIDE;
|
|
||||||
Vector2 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
// Moves the agent's `body` by target `acceleration`.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,296 +1,260 @@
|
|||||||
|
|
||||||
#include "gsai_kinematic_body_3d_agent.h"
|
#include "gsai_kinematic_body_3d_agent.h"
|
||||||
|
|
||||||
|
KinematicBody GSAIKinematicBody3DAgent::get_ *body() {
|
||||||
KinematicBody GSAIKinematicBody3DAgent::get_*body() {
|
return *body;
|
||||||
return *body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::set_*body(const KinematicBody &val) {
|
void GSAIKinematicBody3DAgent::set_ *body(const KinematicBody &val) {
|
||||||
*body = val;
|
*body = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GSAIKinematicBody3DAgent::get_movement_type() const {
|
int GSAIKinematicBody3DAgent::get_movement_type() const {
|
||||||
return movement_type;
|
return movement_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::set_movement_type(const int val) {
|
void GSAIKinematicBody3DAgent::set_movement_type(const int val) {
|
||||||
movement_type = val;
|
movement_type = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIKinematicBody3DAgent::get__last_position() {
|
Vector3 GSAIKinematicBody3DAgent::get__last_position() {
|
||||||
return _last_position;
|
return _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::set__last_position(const Vector3 &val) {
|
void GSAIKinematicBody3DAgent::set__last_position(const Vector3 &val) {
|
||||||
_last_position = val;
|
_last_position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<WeakRef> GSAIKinematicBody3DAgent::get__body_ref() {
|
Ref<WeakRef> GSAIKinematicBody3DAgent::get__body_ref() {
|
||||||
return _body_ref;
|
return _body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
void GSAIKinematicBody3DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
||||||
_body_ref = val;
|
_body_ref = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does;
|
||||||
|
// not have to using a KinematicBody;
|
||||||
|
// @category - Specialized agents;
|
||||||
|
// SLIDE uses `move_and_slide`;
|
||||||
|
// COLLIDE uses `move_and_collide`;
|
||||||
|
// POSITION changes the global_position directly;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
// The KinematicBody to keep track of;
|
||||||
|
// setget _set_body;
|
||||||
|
KinematicBody *body;
|
||||||
|
// The type of movement the body executes;
|
||||||
|
int movement_type = 0;
|
||||||
|
Vector3 _last_position = ;
|
||||||
|
Ref<WeakRef> _body_ref;
|
||||||
|
|
||||||
|
void GSAIKinematicBody3DAgent::_body_ready() {
|
||||||
// A specialized steering agent that updates itself every frame so the user does;
|
// warning-ignore:return_value_discarded;
|
||||||
// not have to using a KinematicBody;
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
|
||||||
// @category - Specialized agents;
|
|
||||||
// SLIDE uses `move_and_slide`;
|
|
||||||
// COLLIDE uses `move_and_collide`;
|
|
||||||
// POSITION changes the global_position directly;
|
|
||||||
};
|
|
||||||
// The KinematicBody to keep track of;
|
|
||||||
// setget _set_body;
|
|
||||||
KinematicBody *body;
|
|
||||||
// The type of movement the body executes;
|
|
||||||
int movement_type = 0;
|
|
||||||
Vector3 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_body_ready() {
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the agent's `body` by target `acceleration`.;
|
// Moves the agent's `body` by target `acceleration`.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
|
void GSAIKinematicBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
|
||||||
applied_steering = true;
|
applied_steering = true;
|
||||||
|
|
||||||
if (movement_type == MovementType.COLLIDE) {
|
if (movement_type == MovementType.COLLIDE) {
|
||||||
_apply_collide_steering(acceleration.linear, delta);
|
_apply_collide_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (movement_type == MovementType.SLIDE) {
|
||||||
|
_apply_sliding_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_apply_position_steering(acceleration.linear, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
_apply_orientation_steering(acceleration.angular, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody3DAgent::_apply_sliding_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
else if (movement_type == MovementType.SLIDE) {
|
if (!_body) {
|
||||||
_apply_sliding_steering(acceleration.linear, delta);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity = _body.move_and_slide(velocity);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody3DAgent::_apply_collide_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
else {
|
if (!_body) {
|
||||||
_apply_position_steering(acceleration.linear, delta);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning-ignore:return_value_discarded;
|
||||||
|
_body.move_and_collide(velocity * delta);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_apply_orientation_steering(acceleration.angular, delta);
|
void GSAIKinematicBody3DAgent::_apply_position_steering(const Vector3 &accel, const float delta) {
|
||||||
|
KinematicBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
|
if (!_body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_body.global_transform.origin += velocity * delta;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIKinematicBody3DAgent::_apply_orientation_steering(const float angular_acceleration, const float delta) {
|
||||||
|
KinematicBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_apply_sliding_steering(const Vector3 &accel, const float delta) {
|
if (!_body) {
|
||||||
KinematicBody *_body = _body_ref.get_ref();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_body) {
|
Variant = clamp(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max);
|
||||||
return;
|
|
||||||
|
if (apply_angular_drag) {
|
||||||
|
velocity = lerp(velocity, 0, angular_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_body.rotation.y += velocity * delta;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
angular_velocity = velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
void GSAIKinematicBody3DAgent::_set_body(const KinematicBody &value) {
|
||||||
|
bool had_body = false;
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
if (body) {
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
had_body = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = value;
|
||||||
|
_body_ref = weakref(value);
|
||||||
|
_last_position = value.transform.origin;
|
||||||
|
last_orientation = value.rotation.y;
|
||||||
|
position = _last_position;
|
||||||
|
orientation = last_orientation;
|
||||||
|
|
||||||
|
if (!had_body) {
|
||||||
|
if (!body.is_inside_tree()) {
|
||||||
|
body.connect("ready", self, "_body_ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_body_ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity = _body.move_and_slide(velocity);
|
void GSAIKinematicBody3DAgent::_on_SceneTree_physics_frame() {
|
||||||
|
KinematicBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
if (calculate_velocities) {
|
if (!_body) {
|
||||||
linear_velocity = velocity;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 current_position = _body.transform.origin;
|
||||||
|
float current_orientation = _body.rotation.y;
|
||||||
|
position = current_position;
|
||||||
|
orientation = current_orientation;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
if (applied_steering) {
|
||||||
|
applied_steering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
linear_velocity = GSAIUtils.clampedv3(current_position - _last_position, linear_speed_max);
|
||||||
|
|
||||||
|
if (apply_linear_drag) {
|
||||||
|
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
angular_velocity = clamp(last_orientation - current_orientation, -angular_speed_max, angular_speed_max);
|
||||||
|
|
||||||
|
if (apply_angular_drag) {
|
||||||
|
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
_last_position = current_position;
|
||||||
|
last_orientation = current_orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIKinematicBody3DAgent::GSAIKinematicBody3DAgent() {
|
||||||
|
*body;
|
||||||
|
movement_type = 0;
|
||||||
|
_last_position = ;
|
||||||
|
_body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIKinematicBody3DAgent::~GSAIKinematicBody3DAgent() {
|
||||||
void GSAIKinematicBody3DAgent::_apply_collide_steering(const Vector3 &accel, const float delta) {
|
|
||||||
KinematicBody *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
static void GSAIKinematicBody3DAgent::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIKinematicBody3DAgent::get_ * body);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIKinematicBody3DAgent::set_ * body);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "KinematicBody"), "set_*body", "get_*body");
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
ClassDB::bind_method(D_METHOD("get_movement_type"), &GSAIKinematicBody3DAgent::get_movement_type);
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
ClassDB::bind_method(D_METHOD("set_movement_type", "value"), &GSAIKinematicBody3DAgent::set_movement_type);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "movement_type"), "set_movement_type", "get_movement_type");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIKinematicBody3DAgent::get__last_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIKinematicBody3DAgent::set__last_position);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_last_position"), "set__last_position", "get__last_position");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIKinematicBody3DAgent::get__body_ref);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIKinematicBody3DAgent::set__body_ref);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIKinematicBody3DAgent::_body_ready);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "delta"), &GSAIKinematicBody3DAgent::_apply_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_sliding_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_sliding_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_collide_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_collide_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_position_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_position_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_orientation_steering", "angular_acceleration", "delta"), &GSAIKinematicBody3DAgent::_apply_orientation_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIKinematicBody3DAgent::_set_body);
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_SceneTree_physics_frame"), &GSAIKinematicBody3DAgent::_on_SceneTree_physics_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
_body.move_and_collide(velocity * delta);
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
linear_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_apply_position_steering(const Vector3 &accel, const float delta) {
|
|
||||||
KinematicBody *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
|
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_body.global_transform.origin += velocity * delta;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
linear_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_apply_orientation_steering(const float angular_acceleration, const float delta) {
|
|
||||||
KinematicBody *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant = clamp(angular_velocity + angular_acceleration * delta,-angular_speed_max,angular_speed_max);
|
|
||||||
|
|
||||||
if (apply_angular_drag) {
|
|
||||||
velocity = lerp(velocity, 0, angular_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_body.rotation.y += velocity * delta;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
angular_velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_set_body(const KinematicBody &value) {
|
|
||||||
bool had_body = false;
|
|
||||||
|
|
||||||
if (body) {
|
|
||||||
had_body = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
body = value;
|
|
||||||
_body_ref = weakref(value);
|
|
||||||
_last_position = value.transform.origin;
|
|
||||||
last_orientation = value.rotation.y;
|
|
||||||
position = _last_position;
|
|
||||||
orientation = last_orientation;
|
|
||||||
|
|
||||||
if (!had_body) {
|
|
||||||
|
|
||||||
if (!body.is_inside_tree()) {
|
|
||||||
body.connect("ready", self, "_body_ready");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
_body_ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIKinematicBody3DAgent::_on_SceneTree_physics_frame() {
|
|
||||||
KinematicBody *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 current_position = _body.transform.origin;
|
|
||||||
float current_orientation = _body.rotation.y;
|
|
||||||
position = current_position;
|
|
||||||
orientation = current_orientation;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
|
|
||||||
if (applied_steering) {
|
|
||||||
applied_steering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
linear_velocity = GSAIUtils.clampedv3(current_position - _last_position, linear_speed_max);
|
|
||||||
|
|
||||||
if (apply_linear_drag) {
|
|
||||||
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
angular_velocity = clamp(last_orientation - current_orientation,-angular_speed_max,angular_speed_max);
|
|
||||||
|
|
||||||
if (apply_angular_drag) {
|
|
||||||
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
_last_position = current_position;
|
|
||||||
last_orientation = current_orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIKinematicBody3DAgent::GSAIKinematicBody3DAgent() {
|
|
||||||
*body;
|
|
||||||
movement_type = 0;
|
|
||||||
_last_position = ;
|
|
||||||
_body_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIKinematicBody3DAgent::~GSAIKinematicBody3DAgent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIKinematicBody3DAgent::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIKinematicBody3DAgent::get_*body);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIKinematicBody3DAgent::set_*body);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "KinematicBody"), "set_*body", "get_*body");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_movement_type"), &GSAIKinematicBody3DAgent::get_movement_type);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_movement_type", "value"), &GSAIKinematicBody3DAgent::set_movement_type);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "movement_type"), "set_movement_type", "get_movement_type");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIKinematicBody3DAgent::get__last_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIKinematicBody3DAgent::set__last_position);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_last_position"), "set__last_position", "get__last_position");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIKinematicBody3DAgent::get__body_ref);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIKinematicBody3DAgent::set__body_ref);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIKinematicBody3DAgent::_body_ready);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "delta"), &GSAIKinematicBody3DAgent::_apply_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_sliding_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_sliding_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_collide_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_collide_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_position_steering", "accel", "delta"), &GSAIKinematicBody3DAgent::_apply_position_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_orientation_steering", "angular_acceleration", "delta"), &GSAIKinematicBody3DAgent::_apply_orientation_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIKinematicBody3DAgent::_set_body);
|
|
||||||
ClassDB::bind_method(D_METHOD("_on_SceneTree_physics_frame"), &GSAIKinematicBody3DAgent::_on_SceneTree_physics_frame);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,63 +1,61 @@
|
|||||||
#ifndef GSAIKINEMATICBODY3DAGENT_H
|
#ifndef GSAIKINEMATICBODY3DAGENT_H
|
||||||
#define GSAIKINEMATICBODY3DAGENT_H
|
#define GSAIKINEMATICBODY3DAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIKinematicBody3DAgent : public GSAISpecializedAgent {
|
class GSAIKinematicBody3DAgent : public GSAISpecializedAgent {
|
||||||
GDCLASS(GSAIKinematicBody3DAgent, GSAISpecializedAgent);
|
GDCLASS(GSAIKinematicBody3DAgent, GSAISpecializedAgent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
KinematicBody get_ *body();
|
||||||
|
void set_ *body(const KinematicBody &val);
|
||||||
|
|
||||||
KinematicBody get_*body();
|
int get_movement_type() const;
|
||||||
void set_*body(const KinematicBody &val);
|
void set_movement_type(const int val);
|
||||||
|
|
||||||
int get_movement_type() const;
|
Vector3 get__last_position();
|
||||||
void set_movement_type(const int val);
|
void set__last_position(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__last_position();
|
Ref<WeakRef> get__body_ref();
|
||||||
void set__last_position(const Vector3 &val);
|
void set__body_ref(const Ref<WeakRef> &val);
|
||||||
|
|
||||||
Ref<WeakRef> get__body_ref();
|
enum MovementType {
|
||||||
void set__body_ref(const Ref<WeakRef> &val);
|
|
||||||
|
|
||||||
enum MovementType {
|
SLIDE,
|
||||||
|
COLLIDE,
|
||||||
|
POSITION
|
||||||
|
};
|
||||||
|
|
||||||
SLIDE,
|
void _body_ready();
|
||||||
COLLIDE,
|
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
|
||||||
POSITION
|
void _apply_sliding_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_collide_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_position_steering(const Vector3 &accel, const float delta);
|
||||||
|
void _apply_orientation_steering(const float angular_acceleration, const float delta);
|
||||||
|
void _set_body(const KinematicBody &value);
|
||||||
|
void _on_SceneTree_physics_frame();
|
||||||
|
|
||||||
|
GSAIKinematicBody3DAgent();
|
||||||
|
~GSAIKinematicBody3DAgent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does
|
||||||
|
// not have to using a KinematicBody
|
||||||
|
// @category - Specialized agents
|
||||||
|
// SLIDE uses `move_and_slide`
|
||||||
|
// COLLIDE uses `move_and_collide`
|
||||||
|
// POSITION changes the global_position directly
|
||||||
};
|
};
|
||||||
|
// The KinematicBody to keep track of
|
||||||
void _body_ready();
|
// setget _set_body
|
||||||
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
|
KinematicBody *body;
|
||||||
void _apply_sliding_steering(const Vector3 &accel, const float delta);
|
// The type of movement the body executes
|
||||||
void _apply_collide_steering(const Vector3 &accel, const float delta);
|
int movement_type = 0;
|
||||||
void _apply_position_steering(const Vector3 &accel, const float delta);
|
Vector3 _last_position = ;
|
||||||
void _apply_orientation_steering(const float angular_acceleration, const float delta);
|
Ref<WeakRef> _body_ref;
|
||||||
void _set_body(const KinematicBody &value);
|
// Moves the agent's `body` by target `acceleration`.
|
||||||
void _on_SceneTree_physics_frame();
|
// @tags - virtual
|
||||||
|
}
|
||||||
GSAIKinematicBody3DAgent();
|
;
|
||||||
~GSAIKinematicBody3DAgent();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
// A specialized steering agent that updates itself every frame so the user does
|
|
||||||
// not have to using a KinematicBody
|
|
||||||
// @category - Specialized agents
|
|
||||||
// SLIDE uses `move_and_slide`
|
|
||||||
// COLLIDE uses `move_and_collide`
|
|
||||||
// POSITION changes the global_position directly
|
|
||||||
};
|
|
||||||
// The KinematicBody to keep track of
|
|
||||||
// setget _set_body
|
|
||||||
KinematicBody *body;
|
|
||||||
// The type of movement the body executes
|
|
||||||
int movement_type = 0;
|
|
||||||
Vector3 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
// Moves the agent's `body` by target `acceleration`.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,168 +1,142 @@
|
|||||||
|
|
||||||
#include "gsai_rigid_body_2d_agent.h"
|
#include "gsai_rigid_body_2d_agent.h"
|
||||||
|
|
||||||
|
RigidBody2D GSAIRigidBody2DAgent::get_ *body() {
|
||||||
RigidBody2D GSAIRigidBody2DAgent::get_*body() {
|
return *body;
|
||||||
return *body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::set_*body(const RigidBody2D &val) {
|
void GSAIRigidBody2DAgent::set_ *body(const RigidBody2D &val) {
|
||||||
*body = val;
|
*body = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector2 GSAIRigidBody2DAgent::get__last_position() {
|
Vector2 GSAIRigidBody2DAgent::get__last_position() {
|
||||||
return _last_position;
|
return _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::set__last_position(const Vector2 &val) {
|
void GSAIRigidBody2DAgent::set__last_position(const Vector2 &val) {
|
||||||
_last_position = val;
|
_last_position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<WeakRef> GSAIRigidBody2DAgent::get__body_ref() {
|
Ref<WeakRef> GSAIRigidBody2DAgent::get__body_ref() {
|
||||||
return _body_ref;
|
return _body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
void GSAIRigidBody2DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
||||||
_body_ref = val;
|
_body_ref = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does;
|
||||||
|
// not have to using a RigidBody2D;
|
||||||
|
// @category - Specialized agents;
|
||||||
|
// The RigidBody2D to keep track of;
|
||||||
|
// setget _set_body;
|
||||||
|
RigidBody2D *body;
|
||||||
|
Vector2 _last_position = ;
|
||||||
|
Ref<WeakRef> _body_ref;
|
||||||
|
|
||||||
|
void GSAIRigidBody2DAgent::_body_ready() {
|
||||||
// A specialized steering agent that updates itself every frame so the user does;
|
// warning-ignore:return_value_discarded;
|
||||||
// not have to using a RigidBody2D;
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
|
||||||
// @category - Specialized agents;
|
|
||||||
// The RigidBody2D to keep track of;
|
|
||||||
// setget _set_body;
|
|
||||||
RigidBody2D *body;
|
|
||||||
Vector2 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::_body_ready() {
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the agent's `body` by target `acceleration`.;
|
// Moves the agent's `body` by target `acceleration`.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
|
void GSAIRigidBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
|
||||||
RigidBody2D *_body = _body_ref.get_ref();
|
RigidBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
if (not _body) {
|
if (not _body) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applied_steering = true;
|
||||||
|
_body.apply_central_impulse(GSAIUtils.to_vector2(acceleration.linear));
|
||||||
|
_body.apply_torque_impulse(acceleration.angular);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = GSAIUtils.to_vector3(_body.linear_velocity);
|
||||||
|
angular_velocity = _body.angular_velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applied_steering = true;
|
void GSAIRigidBody2DAgent::_set_body(const RigidBody2D &value) {
|
||||||
_body.apply_central_impulse(GSAIUtils.to_vector2(acceleration.linear));
|
bool had_body = false;
|
||||||
_body.apply_torque_impulse(acceleration.angular);
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
if (body) {
|
||||||
linear_velocity = GSAIUtils.to_vector3(_body.linear_velocity);
|
had_body = true;
|
||||||
angular_velocity = _body.angular_velocity;
|
}
|
||||||
|
|
||||||
|
body = value;
|
||||||
|
_body_ref = weakref(value);
|
||||||
|
_last_position = value.global_position;
|
||||||
|
last_orientation = value.rotation;
|
||||||
|
position = GSAIUtils.to_vector3(_last_position);
|
||||||
|
orientation = last_orientation;
|
||||||
|
|
||||||
|
if (!had_body) {
|
||||||
|
if (!body.is_inside_tree()) {
|
||||||
|
body.connect("ready", self, "_body_ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_body_ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIRigidBody2DAgent::_on_SceneTree_frame() {
|
||||||
|
RigidBody2D *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
|
if (!_body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 current_position = _body.global_position;
|
||||||
|
float current_orientation = _body.rotation;
|
||||||
|
position = GSAIUtils.to_vector3(current_position);
|
||||||
|
orientation = current_orientation;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
if (applied_steering) {
|
||||||
|
applied_steering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
linear_velocity = GSAIUtils.to_vector3(_body.linear_velocity);
|
||||||
|
angular_velocity = _body.angular_velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIRigidBody2DAgent::GSAIRigidBody2DAgent() {
|
||||||
void GSAIRigidBody2DAgent::_set_body(const RigidBody2D &value) {
|
*body;
|
||||||
bool had_body = false;
|
_last_position = ;
|
||||||
|
_body_ref;
|
||||||
if (body) {
|
|
||||||
had_body = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body = value;
|
GSAIRigidBody2DAgent::~GSAIRigidBody2DAgent() {
|
||||||
_body_ref = weakref(value);
|
|
||||||
_last_position = value.global_position;
|
|
||||||
last_orientation = value.rotation;
|
|
||||||
position = GSAIUtils.to_vector3(_last_position);
|
|
||||||
orientation = last_orientation;
|
|
||||||
|
|
||||||
if (!had_body) {
|
|
||||||
|
|
||||||
if (!body.is_inside_tree()) {
|
|
||||||
body.connect("ready", self, "_body_ready");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIRigidBody2DAgent::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIRigidBody2DAgent::get_ * body);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIRigidBody2DAgent::set_ * body);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "RigidBody2D"), "set_*body", "get_*body");
|
||||||
|
|
||||||
else {
|
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIRigidBody2DAgent::get__last_position);
|
||||||
_body_ready();
|
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIRigidBody2DAgent::set__last_position);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "_last_position"), "set__last_position", "get__last_position");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIRigidBody2DAgent::get__body_ref);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIRigidBody2DAgent::set__body_ref);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIRigidBody2DAgent::_body_ready);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "_delta"), &GSAIRigidBody2DAgent::_apply_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIRigidBody2DAgent::_set_body);
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_SceneTree_frame"), &GSAIRigidBody2DAgent::_on_SceneTree_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIRigidBody2DAgent::_on_SceneTree_frame() {
|
|
||||||
RigidBody2D *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (!_body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!_body.is_inside_tree() || _body.get_tree().paused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 current_position = _body.global_position;
|
|
||||||
float current_orientation = _body.rotation;
|
|
||||||
position = GSAIUtils.to_vector3(current_position);
|
|
||||||
orientation = current_orientation;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
|
|
||||||
if (applied_steering) {
|
|
||||||
applied_steering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
linear_velocity = GSAIUtils.to_vector3(_body.linear_velocity);
|
|
||||||
angular_velocity = _body.angular_velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRigidBody2DAgent::GSAIRigidBody2DAgent() {
|
|
||||||
*body;
|
|
||||||
_last_position = ;
|
|
||||||
_body_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRigidBody2DAgent::~GSAIRigidBody2DAgent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIRigidBody2DAgent::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIRigidBody2DAgent::get_*body);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIRigidBody2DAgent::set_*body);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "RigidBody2D"), "set_*body", "get_*body");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIRigidBody2DAgent::get__last_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIRigidBody2DAgent::set__last_position);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "_last_position"), "set__last_position", "get__last_position");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIRigidBody2DAgent::get__body_ref);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIRigidBody2DAgent::set__body_ref);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIRigidBody2DAgent::_body_ready);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "_delta"), &GSAIRigidBody2DAgent::_apply_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIRigidBody2DAgent::_set_body);
|
|
||||||
ClassDB::bind_method(D_METHOD("_on_SceneTree_frame"), &GSAIRigidBody2DAgent::_on_SceneTree_frame);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,43 +1,40 @@
|
|||||||
#ifndef GSAIRIGIDBODY2DAGENT_H
|
#ifndef GSAIRIGIDBODY2DAGENT_H
|
||||||
#define GSAIRIGIDBODY2DAGENT_H
|
#define GSAIRIGIDBODY2DAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIRigidBody2DAgent : public GSAISpecializedAgent {
|
class GSAIRigidBody2DAgent : public GSAISpecializedAgent {
|
||||||
GDCLASS(GSAIRigidBody2DAgent, GSAISpecializedAgent);
|
GDCLASS(GSAIRigidBody2DAgent, GSAISpecializedAgent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RigidBody2D get_ *body();
|
||||||
|
void set_ *body(const RigidBody2D &val);
|
||||||
|
|
||||||
RigidBody2D get_*body();
|
Vector2 get__last_position();
|
||||||
void set_*body(const RigidBody2D &val);
|
void set__last_position(const Vector2 &val);
|
||||||
|
|
||||||
Vector2 get__last_position();
|
Ref<WeakRef> get__body_ref();
|
||||||
void set__last_position(const Vector2 &val);
|
void set__body_ref(const Ref<WeakRef> &val);
|
||||||
|
|
||||||
Ref<WeakRef> get__body_ref();
|
void _body_ready();
|
||||||
void set__body_ref(const Ref<WeakRef> &val);
|
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
|
||||||
|
void _set_body(const RigidBody2D &value);
|
||||||
|
void _on_SceneTree_frame();
|
||||||
|
|
||||||
void _body_ready();
|
GSAIRigidBody2DAgent();
|
||||||
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
|
~GSAIRigidBody2DAgent();
|
||||||
void _set_body(const RigidBody2D &value);
|
|
||||||
void _on_SceneTree_frame();
|
|
||||||
|
|
||||||
GSAIRigidBody2DAgent();
|
protected:
|
||||||
~GSAIRigidBody2DAgent();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// A specialized steering agent that updates itself every frame so the user does
|
||||||
static void _bind_methods();
|
// not have to using a RigidBody2D
|
||||||
|
// @category - Specialized agents
|
||||||
// A specialized steering agent that updates itself every frame so the user does
|
// The RigidBody2D to keep track of
|
||||||
// not have to using a RigidBody2D
|
// setget _set_body
|
||||||
// @category - Specialized agents
|
RigidBody2D *body;
|
||||||
// The RigidBody2D to keep track of
|
Vector2 _last_position = ;
|
||||||
// setget _set_body
|
Ref<WeakRef> _body_ref;
|
||||||
RigidBody2D *body;
|
// Moves the agent's `body` by target `acceleration`.
|
||||||
Vector2 _last_position = ;
|
// @tags - virtual
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
// Moves the agent's `body` by target `acceleration`.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,168 +1,142 @@
|
|||||||
|
|
||||||
#include "gsai_rigid_body_3d_agent.h"
|
#include "gsai_rigid_body_3d_agent.h"
|
||||||
|
|
||||||
|
RigidBody GSAIRigidBody3DAgent::get_ *body() {
|
||||||
RigidBody GSAIRigidBody3DAgent::get_*body() {
|
return *body;
|
||||||
return *body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::set_*body(const RigidBody &val) {
|
void GSAIRigidBody3DAgent::set_ *body(const RigidBody &val) {
|
||||||
*body = val;
|
*body = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIRigidBody3DAgent::get__last_position() {
|
Vector3 GSAIRigidBody3DAgent::get__last_position() {
|
||||||
return _last_position;
|
return _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::set__last_position(const Vector3 &val) {
|
void GSAIRigidBody3DAgent::set__last_position(const Vector3 &val) {
|
||||||
_last_position = val;
|
_last_position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<WeakRef> GSAIRigidBody3DAgent::get__body_ref() {
|
Ref<WeakRef> GSAIRigidBody3DAgent::get__body_ref() {
|
||||||
return _body_ref;
|
return _body_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
void GSAIRigidBody3DAgent::set__body_ref(const Ref<WeakRef> &val) {
|
||||||
_body_ref = val;
|
_body_ref = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A specialized steering agent that updates itself every frame so the user does;
|
||||||
|
// not have to using a RigidBody;
|
||||||
|
// @category - Specialized agents;
|
||||||
|
// The RigidBody to keep track of;
|
||||||
|
// setget _set_body;
|
||||||
|
RigidBody *body;
|
||||||
|
Vector3 _last_position = ;
|
||||||
|
Ref<WeakRef> _body_ref;
|
||||||
|
|
||||||
|
void GSAIRigidBody3DAgent::_body_ready() {
|
||||||
// A specialized steering agent that updates itself every frame so the user does;
|
// warning-ignore:return_value_discarded;
|
||||||
// not have to using a RigidBody;
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
|
||||||
// @category - Specialized agents;
|
|
||||||
// The RigidBody to keep track of;
|
|
||||||
// setget _set_body;
|
|
||||||
RigidBody *body;
|
|
||||||
Vector3 _last_position = ;
|
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::_body_ready() {
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the agent's `body` by target `acceleration`.;
|
// Moves the agent's `body` by target `acceleration`.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
|
void GSAIRigidBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
|
||||||
RigidBody *_body = _body_ref.get_ref();
|
RigidBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
if (!_body) {
|
if (!_body) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applied_steering = true;
|
||||||
|
_body.apply_central_impulse(acceleration.linear);
|
||||||
|
_body.apply_torque_impulse(Vector3.UP * acceleration.angular);
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
linear_velocity = _body.linear_velocity;
|
||||||
|
angular_velocity = _body.angular_velocity.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applied_steering = true;
|
void GSAIRigidBody3DAgent::_set_body(const RigidBody &value) {
|
||||||
_body.apply_central_impulse(acceleration.linear);
|
bool had_body = false;
|
||||||
_body.apply_torque_impulse(Vector3.UP * acceleration.angular);
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
if (body) {
|
||||||
linear_velocity = _body.linear_velocity;
|
had_body = true;
|
||||||
angular_velocity = _body.angular_velocity.y;
|
}
|
||||||
|
|
||||||
|
body = value;
|
||||||
|
_body_ref = weakref(value);
|
||||||
|
_last_position = value.transform.origin;
|
||||||
|
last_orientation = value.rotation.y;
|
||||||
|
position = _last_position;
|
||||||
|
orientation = last_orientation;
|
||||||
|
|
||||||
|
if (!had_body) {
|
||||||
|
if (!body.is_inside_tree()) {
|
||||||
|
body.connect("ready", self, "_body_ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_body_ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIRigidBody3DAgent::_on_SceneTree_frame() {
|
||||||
|
RigidBody *_body = _body_ref.get_ref();
|
||||||
|
|
||||||
|
if (not _body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not _body.is_inside_tree() || _body.get_tree().paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 current_position = _body.transform.origin;
|
||||||
|
float current_orientation = _body.rotation.y;
|
||||||
|
position = current_position;
|
||||||
|
orientation = current_orientation;
|
||||||
|
|
||||||
|
if (calculate_velocities) {
|
||||||
|
if (applied_steering) {
|
||||||
|
applied_steering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
linear_velocity = _body.linear_velocity;
|
||||||
|
angular_velocity = _body.angular_velocity.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIRigidBody3DAgent::GSAIRigidBody3DAgent() {
|
||||||
void GSAIRigidBody3DAgent::_set_body(const RigidBody &value) {
|
*body;
|
||||||
bool had_body = false;
|
_last_position = ;
|
||||||
|
_body_ref;
|
||||||
if (body) {
|
|
||||||
had_body = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body = value;
|
GSAIRigidBody3DAgent::~GSAIRigidBody3DAgent() {
|
||||||
_body_ref = weakref(value);
|
|
||||||
_last_position = value.transform.origin;
|
|
||||||
last_orientation = value.rotation.y;
|
|
||||||
position = _last_position;
|
|
||||||
orientation = last_orientation;
|
|
||||||
|
|
||||||
if (!had_body) {
|
|
||||||
|
|
||||||
if (!body.is_inside_tree()) {
|
|
||||||
body.connect("ready", self, "_body_ready");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIRigidBody3DAgent::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIRigidBody3DAgent::get_ * body);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIRigidBody3DAgent::set_ * body);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "RigidBody"), "set_*body", "get_*body");
|
||||||
|
|
||||||
else {
|
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIRigidBody3DAgent::get__last_position);
|
||||||
_body_ready();
|
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIRigidBody3DAgent::set__last_position);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_last_position"), "set__last_position", "get__last_position");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIRigidBody3DAgent::get__body_ref);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIRigidBody3DAgent::set__body_ref);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIRigidBody3DAgent::_body_ready);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "_delta"), &GSAIRigidBody3DAgent::_apply_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIRigidBody3DAgent::_set_body);
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_SceneTree_frame"), &GSAIRigidBody3DAgent::_on_SceneTree_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GSAIRigidBody3DAgent::_on_SceneTree_frame() {
|
|
||||||
RigidBody *_body = _body_ref.get_ref();
|
|
||||||
|
|
||||||
if (not _body) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (not _body.is_inside_tree() || _body.get_tree().paused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 current_position = _body.transform.origin;
|
|
||||||
float current_orientation = _body.rotation.y;
|
|
||||||
position = current_position;
|
|
||||||
orientation = current_orientation;
|
|
||||||
|
|
||||||
if (calculate_velocities) {
|
|
||||||
|
|
||||||
if (applied_steering) {
|
|
||||||
applied_steering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
linear_velocity = _body.linear_velocity;
|
|
||||||
angular_velocity = _body.angular_velocity.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRigidBody3DAgent::GSAIRigidBody3DAgent() {
|
|
||||||
*body;
|
|
||||||
_last_position = ;
|
|
||||||
_body_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRigidBody3DAgent::~GSAIRigidBody3DAgent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIRigidBody3DAgent::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*body"), &GSAIRigidBody3DAgent::get_*body);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*body", "value"), &GSAIRigidBody3DAgent::set_*body);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*body", PROPERTY_HINT_RESOURCE_TYPE, "RigidBody"), "set_*body", "get_*body");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__last_position"), &GSAIRigidBody3DAgent::get__last_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__last_position", "value"), &GSAIRigidBody3DAgent::set__last_position);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_last_position"), "set__last_position", "get__last_position");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__body_ref"), &GSAIRigidBody3DAgent::get__body_ref);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__body_ref", "value"), &GSAIRigidBody3DAgent::set__body_ref);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_body_ref", PROPERTY_HINT_RESOURCE_TYPE, "Ref<WeakRef>"), "set__body_ref", "get__body_ref");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_body_ready"), &GSAIRigidBody3DAgent::_body_ready);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "_delta"), &GSAIRigidBody3DAgent::_apply_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_set_body", "value"), &GSAIRigidBody3DAgent::_set_body);
|
|
||||||
ClassDB::bind_method(D_METHOD("_on_SceneTree_frame"), &GSAIRigidBody3DAgent::_on_SceneTree_frame);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,43 +1,40 @@
|
|||||||
#ifndef GSAIRIGIDBODY3DAGENT_H
|
#ifndef GSAIRIGIDBODY3DAGENT_H
|
||||||
#define GSAIRIGIDBODY3DAGENT_H
|
#define GSAIRIGIDBODY3DAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIRigidBody3DAgent : public GSAISpecializedAgent {
|
class GSAIRigidBody3DAgent : public GSAISpecializedAgent {
|
||||||
GDCLASS(GSAIRigidBody3DAgent, GSAISpecializedAgent);
|
GDCLASS(GSAIRigidBody3DAgent, GSAISpecializedAgent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RigidBody get_ *body();
|
||||||
|
void set_ *body(const RigidBody &val);
|
||||||
|
|
||||||
RigidBody get_*body();
|
Vector3 get__last_position();
|
||||||
void set_*body(const RigidBody &val);
|
void set__last_position(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__last_position();
|
Ref<WeakRef> get__body_ref();
|
||||||
void set__last_position(const Vector3 &val);
|
void set__body_ref(const Ref<WeakRef> &val);
|
||||||
|
|
||||||
Ref<WeakRef> get__body_ref();
|
void _body_ready();
|
||||||
void set__body_ref(const Ref<WeakRef> &val);
|
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
|
||||||
|
void _set_body(const RigidBody &value);
|
||||||
|
void _on_SceneTree_frame();
|
||||||
|
|
||||||
void _body_ready();
|
GSAIRigidBody3DAgent();
|
||||||
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
|
~GSAIRigidBody3DAgent();
|
||||||
void _set_body(const RigidBody &value);
|
|
||||||
void _on_SceneTree_frame();
|
|
||||||
|
|
||||||
GSAIRigidBody3DAgent();
|
protected:
|
||||||
~GSAIRigidBody3DAgent();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// A specialized steering agent that updates itself every frame so the user does
|
||||||
static void _bind_methods();
|
// not have to using a RigidBody
|
||||||
|
// @category - Specialized agents
|
||||||
// A specialized steering agent that updates itself every frame so the user does
|
// The RigidBody to keep track of
|
||||||
// not have to using a RigidBody
|
// setget _set_body
|
||||||
// @category - Specialized agents
|
RigidBody *body;
|
||||||
// The RigidBody to keep track of
|
Vector3 _last_position = ;
|
||||||
// setget _set_body
|
Ref<WeakRef> _body_ref;
|
||||||
RigidBody *body;
|
// Moves the agent's `body` by target `acceleration`.
|
||||||
Vector3 _last_position = ;
|
// @tags - virtual
|
||||||
Ref<WeakRef> _body_ref;
|
|
||||||
// Moves the agent's `body` by target `acceleration`.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,164 +1,142 @@
|
|||||||
|
|
||||||
#include "gsai_specialize_dagent.h"
|
#include "gsai_specialize_dagent.h"
|
||||||
|
|
||||||
|
|
||||||
bool GSAISpecializedAgent::get_calculate_velocities() const {
|
bool GSAISpecializedAgent::get_calculate_velocities() const {
|
||||||
return calculate_velocities;
|
return calculate_velocities;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_calculate_velocities(const bool val) {
|
void GSAISpecializedAgent::set_calculate_velocities(const bool val) {
|
||||||
calculate_velocities = val;
|
calculate_velocities = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAISpecializedAgent::get_apply_linear_drag() const {
|
bool GSAISpecializedAgent::get_apply_linear_drag() const {
|
||||||
return apply_linear_drag;
|
return apply_linear_drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_apply_linear_drag(const bool val) {
|
void GSAISpecializedAgent::set_apply_linear_drag(const bool val) {
|
||||||
apply_linear_drag = val;
|
apply_linear_drag = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAISpecializedAgent::get_apply_angular_drag() const {
|
bool GSAISpecializedAgent::get_apply_angular_drag() const {
|
||||||
return apply_angular_drag;
|
return apply_angular_drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_apply_angular_drag(const bool val) {
|
void GSAISpecializedAgent::set_apply_angular_drag(const bool val) {
|
||||||
apply_angular_drag = val;
|
apply_angular_drag = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISpecializedAgent::get_linear_drag_percentage() const {
|
float GSAISpecializedAgent::get_linear_drag_percentage() const {
|
||||||
return linear_drag_percentage;
|
return linear_drag_percentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_linear_drag_percentage(const float val) {
|
void GSAISpecializedAgent::set_linear_drag_percentage(const float val) {
|
||||||
linear_drag_percentage = val;
|
linear_drag_percentage = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISpecializedAgent::get_angular_drag_percentage() const {
|
float GSAISpecializedAgent::get_angular_drag_percentage() const {
|
||||||
return angular_drag_percentage;
|
return angular_drag_percentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_angular_drag_percentage(const float val) {
|
void GSAISpecializedAgent::set_angular_drag_percentage(const float val) {
|
||||||
angular_drag_percentage = val;
|
angular_drag_percentage = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISpecializedAgent::get_last_orientation() const {
|
float GSAISpecializedAgent::get_last_orientation() const {
|
||||||
return last_orientation;
|
return last_orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_last_orientation(const float val) {
|
void GSAISpecializedAgent::set_last_orientation(const float val) {
|
||||||
last_orientation = val;
|
last_orientation = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAISpecializedAgent::get_applied_steering() const {
|
bool GSAISpecializedAgent::get_applied_steering() const {
|
||||||
return applied_steering;
|
return applied_steering;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISpecializedAgent::set_applied_steering(const bool val) {
|
void GSAISpecializedAgent::set_applied_steering(const bool val) {
|
||||||
applied_steering = val;
|
applied_steering = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A base class for a specialized steering agent that updates itself every frame;
|
||||||
|
// so the user does not have to. All other specialized agents derive from this.;
|
||||||
|
// @category - Specialized agents;
|
||||||
|
// @tags - abstract;
|
||||||
|
// If `true`, calculates linear and angular velocities based on the previous;
|
||||||
|
// frame. When `false`, the user must keep those values updated.;
|
||||||
|
bool calculate_velocities = true;
|
||||||
|
// If `true`, interpolates the current linear velocity towards 0 by the;
|
||||||
|
// `linear_drag_percentage` value.;
|
||||||
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
||||||
|
bool apply_linear_drag = true;
|
||||||
|
// If `true`, interpolates the current angular velocity towards 0 by the;
|
||||||
|
// `angular_drag_percentage` value.;
|
||||||
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
||||||
|
bool apply_angular_drag = true;
|
||||||
|
// The percentage between the current linear velocity and 0 to interpolate by if;
|
||||||
|
// `apply_linear_drag` is true.;
|
||||||
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
||||||
|
float linear_drag_percentage = 0.0;
|
||||||
|
// The percentage between the current angular velocity and 0 to interpolate by if;
|
||||||
|
// `apply_angular_drag` is true.;
|
||||||
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
||||||
|
float angular_drag_percentage = 0.0;
|
||||||
|
float last_orientation = 0.0;
|
||||||
|
bool applied_steering = false;
|
||||||
|
|
||||||
|
void GSAISpecializedAgent::apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta) {
|
||||||
// A base class for a specialized steering agent that updates itself every frame;
|
call("_apply_steering", _acceleration, _delta);
|
||||||
// so the user does not have to. All other specialized agents derive from this.;
|
|
||||||
// @category - Specialized agents;
|
|
||||||
// @tags - abstract;
|
|
||||||
// If `true`, calculates linear and angular velocities based on the previous;
|
|
||||||
// frame. When `false`, the user must keep those values updated.;
|
|
||||||
bool calculate_velocities = true;
|
|
||||||
// If `true`, interpolates the current linear velocity towards 0 by the;
|
|
||||||
// `linear_drag_percentage` value.;
|
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
|
||||||
bool apply_linear_drag = true;
|
|
||||||
// If `true`, interpolates the current angular velocity towards 0 by the;
|
|
||||||
// `angular_drag_percentage` value.;
|
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
|
||||||
bool apply_angular_drag = true;
|
|
||||||
// The percentage between the current linear velocity and 0 to interpolate by if;
|
|
||||||
// `apply_linear_drag` is true.;
|
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
|
||||||
float linear_drag_percentage = 0.0;
|
|
||||||
// The percentage between the current angular velocity and 0 to interpolate by if;
|
|
||||||
// `apply_angular_drag` is true.;
|
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.;
|
|
||||||
float angular_drag_percentage = 0.0;
|
|
||||||
float last_orientation = 0.0;
|
|
||||||
bool applied_steering = false;
|
|
||||||
|
|
||||||
void GSAISpecializedAgent::apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta) {
|
|
||||||
call("_apply_steering", _acceleration, _delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the agent's body by target `acceleration`.;
|
// Moves the agent's body by target `acceleration`.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
void GSAISpecializedAgent::_apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta) {
|
void GSAISpecializedAgent::_apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta) {
|
||||||
pass;
|
pass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISpecializedAgent::GSAISpecializedAgent() {
|
||||||
|
calculate_velocities = true;
|
||||||
|
apply_linear_drag = true;
|
||||||
|
apply_angular_drag = true;
|
||||||
|
linear_drag_percentage = 0.0;
|
||||||
|
angular_drag_percentage = 0.0;
|
||||||
|
last_orientation = 0.0;
|
||||||
|
applied_steering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISpecializedAgent::GSAISpecializedAgent() {
|
GSAISpecializedAgent::~GSAISpecializedAgent() {
|
||||||
calculate_velocities = true;
|
}
|
||||||
apply_linear_drag = true;
|
|
||||||
apply_angular_drag = true;
|
|
||||||
linear_drag_percentage = 0.0;
|
|
||||||
angular_drag_percentage = 0.0;
|
|
||||||
last_orientation = 0.0;
|
|
||||||
applied_steering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAISpecializedAgent::~GSAISpecializedAgent() {
|
static void GSAISpecializedAgent::_bind_methods() {
|
||||||
}
|
ClassDB::bind_method(D_METHOD("get_calculate_velocities"), &GSAISpecializedAgent::get_calculate_velocities);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_calculate_velocities", "value"), &GSAISpecializedAgent::set_calculate_velocities);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_velocities"), "set_calculate_velocities", "get_calculate_velocities");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_apply_linear_drag"), &GSAISpecializedAgent::get_apply_linear_drag);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_apply_linear_drag", "value"), &GSAISpecializedAgent::set_apply_linear_drag);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "apply_linear_drag"), "set_apply_linear_drag", "get_apply_linear_drag");
|
||||||
|
|
||||||
static void GSAISpecializedAgent::_bind_methods() {
|
ClassDB::bind_method(D_METHOD("get_apply_angular_drag"), &GSAISpecializedAgent::get_apply_angular_drag);
|
||||||
ClassDB::bind_method(D_METHOD("get_calculate_velocities"), &GSAISpecializedAgent::get_calculate_velocities);
|
ClassDB::bind_method(D_METHOD("set_apply_angular_drag", "value"), &GSAISpecializedAgent::set_apply_angular_drag);
|
||||||
ClassDB::bind_method(D_METHOD("set_calculate_velocities", "value"), &GSAISpecializedAgent::set_calculate_velocities);
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "apply_angular_drag"), "set_apply_angular_drag", "get_apply_angular_drag");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_velocities"), "set_calculate_velocities", "get_calculate_velocities");
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_linear_drag_percentage"), &GSAISpecializedAgent::get_linear_drag_percentage);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_linear_drag_percentage", "value"), &GSAISpecializedAgent::set_linear_drag_percentage);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_drag_percentage"), "set_linear_drag_percentage", "get_linear_drag_percentage");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_apply_linear_drag"), &GSAISpecializedAgent::get_apply_linear_drag);
|
ClassDB::bind_method(D_METHOD("get_angular_drag_percentage"), &GSAISpecializedAgent::get_angular_drag_percentage);
|
||||||
ClassDB::bind_method(D_METHOD("set_apply_linear_drag", "value"), &GSAISpecializedAgent::set_apply_linear_drag);
|
ClassDB::bind_method(D_METHOD("set_angular_drag_percentage", "value"), &GSAISpecializedAgent::set_angular_drag_percentage);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "apply_linear_drag"), "set_apply_linear_drag", "get_apply_linear_drag");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_drag_percentage"), "set_angular_drag_percentage", "get_angular_drag_percentage");
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_apply_angular_drag"), &GSAISpecializedAgent::get_apply_angular_drag);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_apply_angular_drag", "value"), &GSAISpecializedAgent::set_apply_angular_drag);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "apply_angular_drag"), "set_apply_angular_drag", "get_apply_angular_drag");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_linear_drag_percentage"), &GSAISpecializedAgent::get_linear_drag_percentage);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_linear_drag_percentage", "value"), &GSAISpecializedAgent::set_linear_drag_percentage);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_drag_percentage"), "set_linear_drag_percentage", "get_linear_drag_percentage");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_angular_drag_percentage"), &GSAISpecializedAgent::get_angular_drag_percentage);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_angular_drag_percentage", "value"), &GSAISpecializedAgent::set_angular_drag_percentage);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_drag_percentage"), "set_angular_drag_percentage", "get_angular_drag_percentage");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_last_orientation"), &GSAISpecializedAgent::get_last_orientation);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_last_orientation", "value"), &GSAISpecializedAgent::set_last_orientation);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "last_orientation"), "set_last_orientation", "get_last_orientation");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_applied_steering"), &GSAISpecializedAgent::get_applied_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_applied_steering", "value"), &GSAISpecializedAgent::set_applied_steering);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "applied_steering"), "set_applied_steering", "get_applied_steering");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("apply_steering", "_acceleration", "_delta"), &GSAISpecializedAgent::apply_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_apply_steering", "_acceleration", "_delta"), &GSAISpecializedAgent::_apply_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_last_orientation"), &GSAISpecializedAgent::get_last_orientation);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_last_orientation", "value"), &GSAISpecializedAgent::set_last_orientation);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "last_orientation"), "set_last_orientation", "get_last_orientation");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_applied_steering"), &GSAISpecializedAgent::get_applied_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_applied_steering", "value"), &GSAISpecializedAgent::set_applied_steering);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "applied_steering"), "set_applied_steering", "get_applied_steering");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("apply_steering", "_acceleration", "_delta"), &GSAISpecializedAgent::apply_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_apply_steering", "_acceleration", "_delta"), &GSAISpecializedAgent::_apply_steering);
|
||||||
|
}
|
||||||
|
@ -1,70 +1,67 @@
|
|||||||
#ifndef GSAISPECIALIZEDAGENT_H
|
#ifndef GSAISPECIALIZEDAGENT_H
|
||||||
#define GSAISPECIALIZEDAGENT_H
|
#define GSAISPECIALIZEDAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAISpecializedAgent : public GSAISteeringAgent {
|
class GSAISpecializedAgent : public GSAISteeringAgent {
|
||||||
GDCLASS(GSAISpecializedAgent, GSAISteeringAgent);
|
GDCLASS(GSAISpecializedAgent, GSAISteeringAgent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool get_calculate_velocities() const;
|
||||||
|
void set_calculate_velocities(const bool val);
|
||||||
|
|
||||||
bool get_calculate_velocities() const;
|
bool get_apply_linear_drag() const;
|
||||||
void set_calculate_velocities(const bool val);
|
void set_apply_linear_drag(const bool val);
|
||||||
|
|
||||||
bool get_apply_linear_drag() const;
|
bool get_apply_angular_drag() const;
|
||||||
void set_apply_linear_drag(const bool val);
|
void set_apply_angular_drag(const bool val);
|
||||||
|
|
||||||
bool get_apply_angular_drag() const;
|
float get_linear_drag_percentage() const;
|
||||||
void set_apply_angular_drag(const bool val);
|
void set_linear_drag_percentage(const float val);
|
||||||
|
|
||||||
float get_linear_drag_percentage() const;
|
float get_angular_drag_percentage() const;
|
||||||
void set_linear_drag_percentage(const float val);
|
void set_angular_drag_percentage(const float val);
|
||||||
|
|
||||||
float get_angular_drag_percentage() const;
|
float get_last_orientation() const;
|
||||||
void set_angular_drag_percentage(const float val);
|
void set_last_orientation(const float val);
|
||||||
|
|
||||||
float get_last_orientation() const;
|
bool get_applied_steering() const;
|
||||||
void set_last_orientation(const float val);
|
void set_applied_steering(const bool val);
|
||||||
|
|
||||||
bool get_applied_steering() const;
|
void apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta);
|
||||||
void set_applied_steering(const bool val);
|
void _apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta);
|
||||||
|
|
||||||
void apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta);
|
GSAISpecializedAgent();
|
||||||
void _apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta);
|
~GSAISpecializedAgent();
|
||||||
|
|
||||||
GSAISpecializedAgent();
|
protected:
|
||||||
~GSAISpecializedAgent();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// A base class for a specialized steering agent that updates itself every frame
|
||||||
static void _bind_methods();
|
// so the user does not have to. All other specialized agents derive from this.
|
||||||
|
// @category - Specialized agents
|
||||||
// A base class for a specialized steering agent that updates itself every frame
|
// @tags - abstract
|
||||||
// so the user does not have to. All other specialized agents derive from this.
|
// If `true`, calculates linear and angular velocities based on the previous
|
||||||
// @category - Specialized agents
|
// frame. When `false`, the user must keep those values updated.
|
||||||
// @tags - abstract
|
bool calculate_velocities = true;
|
||||||
// If `true`, calculates linear and angular velocities based on the previous
|
// If `true`, interpolates the current linear velocity towards 0 by the
|
||||||
// frame. When `false`, the user must keep those values updated.
|
// `linear_drag_percentage` value.
|
||||||
bool calculate_velocities = true;
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
// If `true`, interpolates the current linear velocity towards 0 by the
|
bool apply_linear_drag = true;
|
||||||
// `linear_drag_percentage` value.
|
// If `true`, interpolates the current angular velocity towards 0 by the
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
// `angular_drag_percentage` value.
|
||||||
bool apply_linear_drag = true;
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
// If `true`, interpolates the current angular velocity towards 0 by the
|
bool apply_angular_drag = true;
|
||||||
// `angular_drag_percentage` value.
|
// The percentage between the current linear velocity and 0 to interpolate by if
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
// `apply_linear_drag` is true.
|
||||||
bool apply_angular_drag = true;
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
// The percentage between the current linear velocity and 0 to interpolate by if
|
float linear_drag_percentage = 0.0;
|
||||||
// `apply_linear_drag` is true.
|
// The percentage between the current angular velocity and 0 to interpolate by if
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
// `apply_angular_drag` is true.
|
||||||
float linear_drag_percentage = 0.0;
|
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
// The percentage between the current angular velocity and 0 to interpolate by if
|
float angular_drag_percentage = 0.0;
|
||||||
// `apply_angular_drag` is true.
|
float last_orientation = 0.0;
|
||||||
// Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
bool applied_steering = false;
|
||||||
float angular_drag_percentage = 0.0;
|
// Moves the agent's body by target `acceleration`.
|
||||||
float last_orientation = 0.0;
|
// @tags - virtual
|
||||||
bool applied_steering = false;
|
|
||||||
// Moves the agent's body by target `acceleration`.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,130 +1,110 @@
|
|||||||
|
|
||||||
#include "gsai_arrive.h"
|
#include "gsai_arrive.h"
|
||||||
|
|
||||||
|
GSAIAgentLocation GSAIArrive::get_ *target() {
|
||||||
GSAIAgentLocation GSAIArrive::get_*target() {
|
return *target;
|
||||||
return *target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIArrive::set_*target(const GSAIAgentLocation &val) {
|
void GSAIArrive::set_ *target(const GSAIAgentLocation &val) {
|
||||||
*target = val;
|
*target = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIArrive::get_arrival_tolerance() const {
|
float GSAIArrive::get_arrival_tolerance() const {
|
||||||
return arrival_tolerance;
|
return arrival_tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIArrive::set_arrival_tolerance(const float val) {
|
void GSAIArrive::set_arrival_tolerance(const float val) {
|
||||||
arrival_tolerance = val;
|
arrival_tolerance = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIArrive::get_deceleration_radius() const {
|
float GSAIArrive::get_deceleration_radius() const {
|
||||||
return deceleration_radius;
|
return deceleration_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIArrive::set_deceleration_radius(const float val) {
|
void GSAIArrive::set_deceleration_radius(const float val) {
|
||||||
deceleration_radius = val;
|
deceleration_radius = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIArrive::get_time_to_reach() const {
|
float GSAIArrive::get_time_to_reach() const {
|
||||||
return time_to_reach;
|
return time_to_reach;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIArrive::set_time_to_reach(const float val) {
|
void GSAIArrive::set_time_to_reach(const float val) {
|
||||||
time_to_reach = val;
|
time_to_reach = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculates acceleration to take an agent to its target's location. The;
|
||||||
|
// calculation attempts to arrive with zero remaining velocity.;
|
||||||
|
// @category - Individual behaviors;
|
||||||
|
// Target agent to arrive to.;
|
||||||
|
GSAIAgentLocation *target;
|
||||||
|
// Distance from the target for the agent to be considered successfully;
|
||||||
|
// arrived.;
|
||||||
|
float arrival_tolerance = 0.0;
|
||||||
|
// Distance from the target for the agent to begin slowing down.;
|
||||||
|
float deceleration_radius = 0.0;
|
||||||
|
// Represents the time it takes to change acceleration.;
|
||||||
|
float time_to_reach = 0.1;
|
||||||
|
|
||||||
|
void GSAIArrive::arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
||||||
// Calculates acceleration to take an agent to its target's location. The;
|
call("_arrive", acceleration, target_position);
|
||||||
// calculation attempts to arrive with zero remaining velocity.;
|
|
||||||
// @category - Individual behaviors;
|
|
||||||
// Target agent to arrive to.;
|
|
||||||
GSAIAgentLocation *target;
|
|
||||||
// Distance from the target for the agent to be considered successfully;
|
|
||||||
// arrived.;
|
|
||||||
float arrival_tolerance = 0.0;
|
|
||||||
// Distance from the target for the agent to begin slowing down.;
|
|
||||||
float deceleration_radius = 0.0;
|
|
||||||
// Represents the time it takes to change acceleration.;
|
|
||||||
float time_to_reach = 0.1;
|
|
||||||
|
|
||||||
void GSAIArrive::arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
|
||||||
call("_arrive", acceleration, target_position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIArrive::_arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
||||||
|
Vector3 to_target = target_position - agent.position;
|
||||||
|
float distance = to_target.length();
|
||||||
|
|
||||||
void GSAIArrive::_arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
if (distance <= arrival_tolerance) {
|
||||||
Vector3 to_target = target_position - agent.position;
|
acceleration.set_zero();
|
||||||
float distance = to_target.length();
|
}
|
||||||
|
|
||||||
if (distance <= arrival_tolerance) {
|
else {
|
||||||
acceleration.set_zero();
|
float desired_speed = agent.linear_speed_max;
|
||||||
|
|
||||||
|
if (distance <= deceleration_radius) {
|
||||||
|
desired_speed *= distance / deceleration_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 desired_velocity = to_target * desired_speed / distance;
|
||||||
|
desired_velocity = ((desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach);
|
||||||
|
acceleration.linear = GSAIUtils.clampedv3(desired_velocity, agent.linear_acceleration_max);
|
||||||
|
acceleration.angular = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIArrive::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
else {
|
arrive(acceleration, target.position);
|
||||||
float desired_speed = agent.linear_speed_max;
|
}
|
||||||
|
|
||||||
if (distance <= deceleration_radius) {
|
|
||||||
desired_speed *= distance / deceleration_radius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 desired_velocity = to_target * desired_speed / distance;
|
GSAIArrive::GSAIArrive() {
|
||||||
desired_velocity = ((desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach);
|
*target;
|
||||||
acceleration.linear = GSAIUtils.clampedv3(desired_velocity, agent.linear_acceleration_max);
|
arrival_tolerance = 0.0;
|
||||||
acceleration.angular = 0;
|
deceleration_radius = 0.0;
|
||||||
|
time_to_reach = 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIArrive::~GSAIArrive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIArrive::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIArrive::get_ * target);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIArrive::set_ * target);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
|
||||||
|
|
||||||
void GSAIArrive::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
ClassDB::bind_method(D_METHOD("get_arrival_tolerance"), &GSAIArrive::get_arrival_tolerance);
|
||||||
arrive(acceleration, target.position);
|
ClassDB::bind_method(D_METHOD("set_arrival_tolerance", "value"), &GSAIArrive::set_arrival_tolerance);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "arrival_tolerance"), "set_arrival_tolerance", "get_arrival_tolerance");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_deceleration_radius"), &GSAIArrive::get_deceleration_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_deceleration_radius", "value"), &GSAIArrive::set_deceleration_radius);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "deceleration_radius"), "set_deceleration_radius", "get_deceleration_radius");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_time_to_reach"), &GSAIArrive::get_time_to_reach);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_time_to_reach", "value"), &GSAIArrive::set_time_to_reach);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_to_reach"), "set_time_to_reach", "get_time_to_reach");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("arrive", "acceleration", "target_position"), &GSAIArrive::arrive);
|
||||||
|
ClassDB::bind_method(D_METHOD("_arrive", "acceleration", "target_position"), &GSAIArrive::_arrive);
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIArrive::_calculate_steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIArrive::GSAIArrive() {
|
|
||||||
*target;
|
|
||||||
arrival_tolerance = 0.0;
|
|
||||||
deceleration_radius = 0.0;
|
|
||||||
time_to_reach = 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIArrive::~GSAIArrive() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIArrive::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIArrive::get_*target);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIArrive::set_*target);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_arrival_tolerance"), &GSAIArrive::get_arrival_tolerance);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_arrival_tolerance", "value"), &GSAIArrive::set_arrival_tolerance);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "arrival_tolerance"), "set_arrival_tolerance", "get_arrival_tolerance");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_deceleration_radius"), &GSAIArrive::get_deceleration_radius);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_deceleration_radius", "value"), &GSAIArrive::set_deceleration_radius);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "deceleration_radius"), "set_deceleration_radius", "get_deceleration_radius");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_time_to_reach"), &GSAIArrive::get_time_to_reach);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_time_to_reach", "value"), &GSAIArrive::set_time_to_reach);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_to_reach"), "set_time_to_reach", "get_time_to_reach");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("arrive", "acceleration", "target_position"), &GSAIArrive::arrive);
|
|
||||||
ClassDB::bind_method(D_METHOD("_arrive", "acceleration", "target_position"), &GSAIArrive::_arrive);
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIArrive::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,47 +1,44 @@
|
|||||||
#ifndef GSAIARRIVE_H
|
#ifndef GSAIARRIVE_H
|
||||||
#define GSAIARRIVE_H
|
#define GSAIARRIVE_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIArrive : public GSAISteeringBehavior {
|
class GSAIArrive : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIArrive, GSAISteeringBehavior);
|
GDCLASS(GSAIArrive, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAIAgentLocation get_ *target();
|
||||||
|
void set_ *target(const GSAIAgentLocation &val);
|
||||||
|
|
||||||
GSAIAgentLocation get_*target();
|
float get_arrival_tolerance() const;
|
||||||
void set_*target(const GSAIAgentLocation &val);
|
void set_arrival_tolerance(const float val);
|
||||||
|
|
||||||
float get_arrival_tolerance() const;
|
float get_deceleration_radius() const;
|
||||||
void set_arrival_tolerance(const float val);
|
void set_deceleration_radius(const float val);
|
||||||
|
|
||||||
float get_deceleration_radius() const;
|
float get_time_to_reach() const;
|
||||||
void set_deceleration_radius(const float val);
|
void set_time_to_reach(const float val);
|
||||||
|
|
||||||
float get_time_to_reach() const;
|
void arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
||||||
void set_time_to_reach(const float val);
|
void _arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
|
|
||||||
void arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
GSAIArrive();
|
||||||
void _arrive(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
~GSAIArrive();
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
|
||||||
|
|
||||||
GSAIArrive();
|
protected:
|
||||||
~GSAIArrive();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates acceleration to take an agent to its target's location. The
|
||||||
static void _bind_methods();
|
// calculation attempts to arrive with zero remaining velocity.
|
||||||
|
// @category - Individual behaviors
|
||||||
// Calculates acceleration to take an agent to its target's location. The
|
// Target agent to arrive to.
|
||||||
// calculation attempts to arrive with zero remaining velocity.
|
GSAIAgentLocation *target;
|
||||||
// @category - Individual behaviors
|
// Distance from the target for the agent to be considered successfully
|
||||||
// Target agent to arrive to.
|
// arrived.
|
||||||
GSAIAgentLocation *target;
|
float arrival_tolerance = 0.0;
|
||||||
// Distance from the target for the agent to be considered successfully
|
// Distance from the target for the agent to begin slowing down.
|
||||||
// arrived.
|
float deceleration_radius = 0.0;
|
||||||
float arrival_tolerance = 0.0;
|
// Represents the time it takes to change acceleration.
|
||||||
// Distance from the target for the agent to begin slowing down.
|
float time_to_reach = 0.1;
|
||||||
float deceleration_radius = 0.0;
|
|
||||||
// Represents the time it takes to change acceleration.
|
|
||||||
float time_to_reach = 0.1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,198 +1,168 @@
|
|||||||
|
|
||||||
#include "gsai_avoid_collisions.h"
|
#include "gsai_avoid_collisions.h"
|
||||||
|
|
||||||
|
GSAISteeringAgent GSAIAvoidCollisions::get_ *_first_neighbor() {
|
||||||
GSAISteeringAgent GSAIAvoidCollisions::get_*_first_neighbor() {
|
return *_first_neighbor;
|
||||||
return *_first_neighbor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set_*_first_neighbor(const GSAISteeringAgent &val) {
|
void GSAIAvoidCollisions::set_ *_first_neighbor(const GSAISteeringAgent &val) {
|
||||||
*_first_neighbor = val;
|
*_first_neighbor = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIAvoidCollisions::get__shortest_time() const {
|
float GSAIAvoidCollisions::get__shortest_time() const {
|
||||||
return _shortest_time;
|
return _shortest_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set__shortest_time(const float val) {
|
void GSAIAvoidCollisions::set__shortest_time(const float val) {
|
||||||
_shortest_time = val;
|
_shortest_time = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIAvoidCollisions::get__first_minimum_separation() const {
|
float GSAIAvoidCollisions::get__first_minimum_separation() const {
|
||||||
return _first_minimum_separation;
|
return _first_minimum_separation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set__first_minimum_separation(const float val) {
|
void GSAIAvoidCollisions::set__first_minimum_separation(const float val) {
|
||||||
_first_minimum_separation = val;
|
_first_minimum_separation = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIAvoidCollisions::get__first_distance() const {
|
float GSAIAvoidCollisions::get__first_distance() const {
|
||||||
return _first_distance;
|
return _first_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set__first_distance(const float val) {
|
void GSAIAvoidCollisions::set__first_distance(const float val) {
|
||||||
_first_distance = val;
|
_first_distance = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIAvoidCollisions::get__first_relative_position() {
|
Vector3 GSAIAvoidCollisions::get__first_relative_position() {
|
||||||
return _first_relative_position;
|
return _first_relative_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set__first_relative_position(const Vector3 &val) {
|
void GSAIAvoidCollisions::set__first_relative_position(const Vector3 &val) {
|
||||||
_first_relative_position = val;
|
_first_relative_position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIAvoidCollisions::get__first_relative_velocity() {
|
Vector3 GSAIAvoidCollisions::get__first_relative_velocity() {
|
||||||
return _first_relative_velocity;
|
return _first_relative_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAvoidCollisions::set__first_relative_velocity(const Vector3 &val) {
|
void GSAIAvoidCollisions::set__first_relative_velocity(const Vector3 &val) {
|
||||||
_first_relative_velocity = 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;
|
||||||
|
_first_minimum_separation = 0;
|
||||||
|
_first_distance = 0;
|
||||||
|
int neighbor_count = proximity.find_neighbors(_callback);
|
||||||
|
|
||||||
// Steers the agent to avoid obstacles in its path. Approximates obstacles as;
|
if (neighbor_count == 0 || not _first_neighbor) {
|
||||||
// spheres.;
|
acceleration.set_zero();
|
||||||
// @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) {
|
else {
|
||||||
_shortest_time = INF;
|
if ((_first_minimum_separation <= 0 || _first_distance < agent.bounding_radius + _first_neighbor.bounding_radius)) {
|
||||||
_first_neighbor = null;
|
acceleration.linear = _first_neighbor.position - agent.position;
|
||||||
_first_minimum_separation = 0;
|
}
|
||||||
_first_distance = 0;
|
|
||||||
int neighbor_count = proximity.find_neighbors(_callback);
|
|
||||||
|
|
||||||
if (neighbor_count == 0 || not _first_neighbor) {
|
else {
|
||||||
acceleration.set_zero();
|
acceleration.linear = (_first_relative_position + (_first_relative_velocity * _shortest_time));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acceleration.linear = (acceleration.linear.normalized() * -agent.linear_acceleration_max);
|
||||||
|
acceleration.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;
|
||||||
|
|
||||||
else {
|
bool GSAIAvoidCollisions::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
||||||
|
Vector3 relative_position = neighbor.position - agent.position;
|
||||||
|
Vector3 relative_velocity = neighbor.linear_velocity - agent.linear_velocity;
|
||||||
|
float relative_speed_squared = relative_velocity.length_squared();
|
||||||
|
|
||||||
if ((_first_minimum_separation <= 0 || _first_distance < agent.bounding_radius + _first_neighbor.bounding_radius)) {
|
if (relative_speed_squared == 0) {
|
||||||
acceleration.linear = _first_neighbor.position - agent.position;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
float time_to_collision = -relative_position.dot(relative_velocity) / relative_speed_squared;
|
||||||
|
|
||||||
|
if (time_to_collision <= 0 || time_to_collision >= _shortest_time) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
_shortest_time = time_to_collision;
|
||||||
|
_first_neighbor = neighbor;
|
||||||
|
_first_minimum_separation = minimum_separation;
|
||||||
|
_first_distance = distance;
|
||||||
|
_first_relative_position = relative_position;
|
||||||
|
_first_relative_velocity = relative_velocity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIAvoidCollisions::GSAIAvoidCollisions() {
|
||||||
else {
|
*_first_neighbor;
|
||||||
acceleration.linear = (_first_relative_position+ (_first_relative_velocity * _shortest_time));
|
_shortest_time = 0.0;
|
||||||
|
_first_minimum_separation = 0.0;
|
||||||
|
_first_distance = 0.0;
|
||||||
|
_first_relative_position = ;
|
||||||
|
_first_relative_velocity = ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIAvoidCollisions::~GSAIAvoidCollisions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
acceleration.linear = (acceleration.linear.normalized() * -agent.linear_acceleration_max);
|
static void GSAIAvoidCollisions::_bind_methods() {
|
||||||
acceleration.angular = 0;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(const GSAISteeringAgent &neighbor) {
|
|
||||||
Vector3 relative_position = neighbor.position - agent.position;
|
|
||||||
Vector3 relative_velocity = neighbor.linear_velocity - agent.linear_velocity;
|
|
||||||
float relative_speed_squared = relative_velocity.length_squared();
|
|
||||||
|
|
||||||
if (relative_speed_squared == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
float time_to_collision = -relative_position.dot(relative_velocity) / relative_speed_squared;
|
|
||||||
|
|
||||||
if (time_to_collision <= 0 || time_to_collision >= _shortest_time) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
_shortest_time = time_to_collision;
|
|
||||||
_first_neighbor = neighbor;
|
|
||||||
_first_minimum_separation = minimum_separation;
|
|
||||||
_first_distance = distance;
|
|
||||||
_first_relative_position = relative_position;
|
|
||||||
_first_relative_velocity = relative_velocity;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,52 +1,49 @@
|
|||||||
#ifndef GSAIAVOIDCOLLISIONS_H
|
#ifndef GSAIAVOIDCOLLISIONS_H
|
||||||
#define GSAIAVOIDCOLLISIONS_H
|
#define GSAIAVOIDCOLLISIONS_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIAvoidCollisions : public GSAIGroupBehavior {
|
class GSAIAvoidCollisions : public GSAIGroupBehavior {
|
||||||
GDCLASS(GSAIAvoidCollisions, GSAIGroupBehavior);
|
GDCLASS(GSAIAvoidCollisions, GSAIGroupBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAISteeringAgent get_ *_first_neighbor();
|
||||||
|
void set_ *_first_neighbor(const GSAISteeringAgent &val);
|
||||||
|
|
||||||
GSAISteeringAgent get_*_first_neighbor();
|
float get__shortest_time() const;
|
||||||
void set_*_first_neighbor(const GSAISteeringAgent &val);
|
void set__shortest_time(const float val);
|
||||||
|
|
||||||
float get__shortest_time() const;
|
float get__first_minimum_separation() const;
|
||||||
void set__shortest_time(const float val);
|
void set__first_minimum_separation(const float val);
|
||||||
|
|
||||||
float get__first_minimum_separation() const;
|
float get__first_distance() const;
|
||||||
void set__first_minimum_separation(const float val);
|
void set__first_distance(const float val);
|
||||||
|
|
||||||
float get__first_distance() const;
|
Vector3 get__first_relative_position();
|
||||||
void set__first_distance(const float val);
|
void set__first_relative_position(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__first_relative_position();
|
Vector3 get__first_relative_velocity();
|
||||||
void set__first_relative_position(const Vector3 &val);
|
void set__first_relative_velocity(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__first_relative_velocity();
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set__first_relative_velocity(const Vector3 &val);
|
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAIAvoidCollisions();
|
||||||
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
~GSAIAvoidCollisions();
|
||||||
|
|
||||||
GSAIAvoidCollisions();
|
protected:
|
||||||
~GSAIAvoidCollisions();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Steers the agent to avoid obstacles in its path. Approximates obstacles as
|
||||||
static void _bind_methods();
|
// spheres.
|
||||||
|
// @category - Group behaviors
|
||||||
// Steers the agent to avoid obstacles in its path. Approximates obstacles as
|
GSAISteeringAgent *_first_neighbor;
|
||||||
// spheres.
|
float _shortest_time = 0.0;
|
||||||
// @category - Group behaviors
|
float _first_minimum_separation = 0.0;
|
||||||
GSAISteeringAgent *_first_neighbor;
|
float _first_distance = 0.0;
|
||||||
float _shortest_time = 0.0;
|
Vector3 _first_relative_position = ;
|
||||||
float _first_minimum_separation = 0.0;
|
Vector3 _first_relative_velocity = ;
|
||||||
float _first_distance = 0.0;
|
// Callback for the proximity to call when finding neighbors. Keeps track of every `neighbor`
|
||||||
Vector3 _first_relative_position = ;
|
// that was found but only keeps the one the owning agent will most likely collide with.
|
||||||
Vector3 _first_relative_velocity = ;
|
// @tags - virtual
|
||||||
// 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,126 +1,108 @@
|
|||||||
|
|
||||||
#include "gsai_blend.h"
|
#include "gsai_blend.h"
|
||||||
|
|
||||||
|
|
||||||
Array GSAIBlend::get__behaviors() {
|
Array GSAIBlend::get__behaviors() {
|
||||||
return _behaviors;
|
return _behaviors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIBlend::set__behaviors(const Array &val) {
|
void GSAIBlend::set__behaviors(const Array &val) {
|
||||||
_behaviors = val;
|
_behaviors = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAITargetAcceleration GSAIBlend::get_ *_accel() {
|
||||||
GSAITargetAcceleration GSAIBlend::get_*_accel() {
|
return *_accel;
|
||||||
return *_accel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIBlend::set_*_accel(const GSAITargetAcceleration &val) {
|
void GSAIBlend::set_ *_accel(const GSAITargetAcceleration &val) {
|
||||||
*_accel = 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) {
|
||||||
// Blends multiple steering behaviors into one, and returns a weighted;
|
behavior.agent = agent;
|
||||||
// acceleration from their calculations.;
|
Dictionary dict = Dictionary();
|
||||||
//;
|
dict["behavior"] = behavior;
|
||||||
// Stores the behaviors internally as dictionaries of the form;
|
dict["weight"] = weight;
|
||||||
// {;
|
_behaviors.append(dict);
|
||||||
// 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;
|
// Returns the behavior at the specified `index`, or an empty `Dictionary` if;
|
||||||
// none was found.;
|
// none was found.;
|
||||||
|
|
||||||
Dictionary GSAIBlend::get_behavior(const int index) {
|
Dictionary GSAIBlend::get_behavior(const int index) {
|
||||||
|
if (_behaviors.size() > index) {
|
||||||
|
return _behaviors[index];
|
||||||
|
}
|
||||||
|
|
||||||
if (_behaviors.size() > index) {
|
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||||
return _behaviors[index];
|
return Dictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
void GSAIBlend::remove_behavior(const int index) {
|
||||||
return Dictionary();
|
if (_behaviors.size() > index) {
|
||||||
|
_behaviors.remove(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GSAIBlend::get_behaviour_count() {
|
||||||
void GSAIBlend::remove_behavior(const int index) {
|
return _behaviors.size();
|
||||||
|
|
||||||
if (_behaviors.size() > index) {
|
|
||||||
_behaviors.remove(index);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
GSAITargetAcceleration GSAIBlend::get_accel() {
|
||||||
return;
|
return _accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIBlend::_calculate_steering(const GSAITargetAcceleration &blended_accel) {
|
||||||
|
blended_accel.set_zero();
|
||||||
|
|
||||||
int GSAIBlend::get_behaviour_count() {
|
for (int i = 0; i < _behaviors.size(); ++i) { //i in range(_behaviors.size())
|
||||||
return _behaviors.size();
|
Dictionary 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIBlend::GSAIBlend() {
|
||||||
GSAITargetAcceleration GSAIBlend::get_accel() {
|
_behaviors = Array();
|
||||||
return _accel;
|
*_accel = GSAITargetAcceleration.new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIBlend::~GSAIBlend() {
|
||||||
void GSAIBlend::_calculate_steering(const GSAITargetAcceleration &blended_accel) {
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blended_accel.linear = GSAIUtils.clampedv3(blended_accel.linear, agent.linear_acceleration_max);
|
static void GSAIBlend::_bind_methods() {
|
||||||
blended_accel.angular = clamp(blended_accel.angular, -agent.angular_acceleration_max, agent.angular_acceleration_max);
|
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");
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIBlend::GSAIBlend() {
|
|
||||||
_behaviors = Array();
|
|
||||||
*_accel = GSAITargetAcceleration.new();
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
|
|
||||||
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,46 +1,43 @@
|
|||||||
#ifndef GSAIBLEND_H
|
#ifndef GSAIBLEND_H
|
||||||
#define GSAIBLEND_H
|
#define GSAIBLEND_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIBlend : public GSAISteeringBehavior {
|
class GSAIBlend : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIBlend, GSAISteeringBehavior);
|
GDCLASS(GSAIBlend, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Array get__behaviors();
|
||||||
|
void set__behaviors(const Array &val);
|
||||||
|
|
||||||
Array get__behaviors();
|
GSAITargetAcceleration get_ *_accel();
|
||||||
void set__behaviors(const Array &val);
|
void set_ *_accel(const GSAITargetAcceleration &val);
|
||||||
|
|
||||||
GSAITargetAcceleration get_*_accel();
|
void add_behavior(const GSAISteeringBehavior &behavior, const float weight);
|
||||||
void set_*_accel(const GSAITargetAcceleration &val);
|
Dictionary get_behavior(const int index);
|
||||||
|
void remove_behavior(const int index);
|
||||||
|
int get_behaviour_count();
|
||||||
|
GSAITargetAcceleration get_accel();
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &blended_accel);
|
||||||
|
|
||||||
void add_behavior(const GSAISteeringBehavior &behavior, const float weight);
|
GSAIBlend();
|
||||||
Dictionary get_behavior(const int index);
|
~GSAIBlend();
|
||||||
void remove_behavior(const int index);
|
|
||||||
int get_behaviour_count();
|
|
||||||
GSAITargetAcceleration get_accel();
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &blended_accel);
|
|
||||||
|
|
||||||
GSAIBlend();
|
protected:
|
||||||
~GSAIBlend();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Blends multiple steering behaviors into one, and returns a weighted
|
||||||
static void _bind_methods();
|
// acceleration from their calculations.
|
||||||
|
//
|
||||||
// Blends multiple steering behaviors into one, and returns a weighted
|
// Stores the behaviors internally as dictionaries of the form
|
||||||
// acceleration from their calculations.
|
// {
|
||||||
//
|
// behavior : GSAISteeringBehavior,
|
||||||
// Stores the behaviors internally as dictionaries of the form
|
// weight : float
|
||||||
// {
|
// }
|
||||||
// behavior : GSAISteeringBehavior,
|
// @category - Combination behaviors
|
||||||
// weight : float
|
Array _behaviors = Array();
|
||||||
// }
|
GSAITargetAcceleration *_accel = GSAITargetAcceleration.new();
|
||||||
// @category - Combination behaviors
|
// Appends a behavior to the internal array along with its `weight`.
|
||||||
Array _behaviors = Array();
|
// Returns the behavior at the specified `index`, or an empty `Dictionary` if
|
||||||
GSAITargetAcceleration *_accel = GSAITargetAcceleration.new();
|
// none was found.
|
||||||
// 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.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,63 +1,52 @@
|
|||||||
|
|
||||||
#include "gsai_cohesion.h"
|
#include "gsai_cohesion.h"
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAICohesion::get__center_of_mass() {
|
Vector3 GSAICohesion::get__center_of_mass() {
|
||||||
return _center_of_mass;
|
return _center_of_mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAICohesion::set__center_of_mass(const Vector3 &val) {
|
void GSAICohesion::set__center_of_mass(const Vector3 &val) {
|
||||||
_center_of_mass = val;
|
_center_of_mass = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
// Calculates an acceleration that attempts to move the agent towards the center;
|
if (neighbor_count > 0) {
|
||||||
// of mass of the agents in the area defined by the `GSAIProximity`.;
|
_center_of_mass *= 1.0 / neighbor_count;
|
||||||
// @category - Group behaviors;
|
acceleration.linear = ((_center_of_mass - agent.position).normalized() * agent.linear_acceleration_max);
|
||||||
Vector3 _center_of_mass = ;
|
}
|
||||||
|
|
||||||
void GSAICohesion::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
// Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position;
|
||||||
acceleration.set_zero();
|
// to the center of mass of the group.;
|
||||||
_center_of_mass = Vector3.ZERO;
|
// @tags - virtual;
|
||||||
Variant = 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position;
|
bool GSAICohesion::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
||||||
// to the center of mass of the group.;
|
_center_of_mass += neighbor.position;
|
||||||
// @tags - virtual;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAICohesion::GSAICohesion() {
|
||||||
bool GSAICohesion::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
_center_of_mass = ;
|
||||||
_center_of_mass += neighbor.position;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAICohesion::~GSAICohesion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAICohesion::GSAICohesion() {
|
static void GSAICohesion::_bind_methods() {
|
||||||
_center_of_mass = ;
|
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");
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAICohesion::_calculate_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_report_neighbor", "neighbor"), &GSAICohesion::_report_neighbor);
|
||||||
|
}
|
||||||
|
@ -1,29 +1,26 @@
|
|||||||
#ifndef GSAICOHESION_H
|
#ifndef GSAICOHESION_H
|
||||||
#define GSAICOHESION_H
|
#define GSAICOHESION_H
|
||||||
|
|
||||||
|
|
||||||
class GSAICohesion : public GSAIGroupBehavior {
|
class GSAICohesion : public GSAIGroupBehavior {
|
||||||
GDCLASS(GSAICohesion, GSAIGroupBehavior);
|
GDCLASS(GSAICohesion, GSAIGroupBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Vector3 get__center_of_mass();
|
||||||
|
void set__center_of_mass(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__center_of_mass();
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set__center_of_mass(const Vector3 &val);
|
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAICohesion();
|
||||||
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
~GSAICohesion();
|
||||||
|
|
||||||
GSAICohesion();
|
protected:
|
||||||
~GSAICohesion();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an acceleration that attempts to move the agent towards the center
|
||||||
static void _bind_methods();
|
// of mass of the agents in the area defined by the `GSAIProximity`.
|
||||||
|
// @category - Group behaviors
|
||||||
// Calculates an acceleration that attempts to move the agent towards the center
|
Vector3 _center_of_mass = ;
|
||||||
// of mass of the agents in the area defined by the `GSAIProximity`.
|
|
||||||
// @category - Group behaviors
|
|
||||||
Vector3 _center_of_mass = ;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,29 +1,21 @@
|
|||||||
|
|
||||||
#include "gsai_evade.h"
|
#include "gsai_evade.h"
|
||||||
|
|
||||||
|
// Calculates acceleration to take an agent away from where a target agent is;
|
||||||
|
// moving.;
|
||||||
|
// @category - Individual behaviors;
|
||||||
|
|
||||||
|
float GSAIEvade::_get_modified_acceleration() {
|
||||||
// Calculates acceleration to take an agent away from where a target agent is;
|
return -agent.linear_acceleration_max;
|
||||||
// moving.;
|
}
|
||||||
// @category - Individual behaviors;
|
|
||||||
|
|
||||||
float GSAIEvade::_get_modified_acceleration() {
|
|
||||||
return -agent.linear_acceleration_max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIEvade::GSAIEvade() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIEvade::GSAIEvade() {
|
GSAIEvade::~GSAIEvade() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIEvade::~GSAIEvade() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIEvade::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("_get_modified_acceleration"), &GSAIEvade::_get_modified_acceleration);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void GSAIEvade::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("_get_modified_acceleration"), &GSAIEvade::_get_modified_acceleration);
|
||||||
|
}
|
||||||
|
@ -1,24 +1,21 @@
|
|||||||
#ifndef GSAIEVADE_H
|
#ifndef GSAIEVADE_H
|
||||||
#define GSAIEVADE_H
|
#define GSAIEVADE_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIEvade : public GSAIPursue {
|
class GSAIEvade : public GSAIPursue {
|
||||||
GDCLASS(GSAIEvade, GSAIPursue);
|
GDCLASS(GSAIEvade, GSAIPursue);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float _get_modified_acceleration();
|
||||||
|
|
||||||
float _get_modified_acceleration();
|
GSAIEvade();
|
||||||
|
~GSAIEvade();
|
||||||
|
|
||||||
GSAIEvade();
|
protected:
|
||||||
~GSAIEvade();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates acceleration to take an agent away from where a target agent is
|
||||||
static void _bind_methods();
|
// moving.
|
||||||
|
// @category - Individual behaviors
|
||||||
// Calculates acceleration to take an agent away from where a target agent is
|
|
||||||
// moving.
|
|
||||||
// @category - Individual behaviors
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,63 +1,50 @@
|
|||||||
|
|
||||||
#include "gsai_face.h"
|
#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;
|
||||||
|
|
||||||
|
void GSAIFace::face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
||||||
// Calculates angular acceleration to rotate a target to face its target's;
|
call("_face", acceleration, target_position);
|
||||||
// position. The behavior attemps to arrive with zero remaining angular velocity.;
|
|
||||||
// @category - Individual behaviors;
|
|
||||||
|
|
||||||
void GSAIFace::face(const 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;
|
||||||
|
float distance_squared = to_target.length_squared();
|
||||||
|
|
||||||
void GSAIFace::_face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position) {
|
if (distance_squared < agent.zero_linear_speed_threshold) {
|
||||||
Vector3 to_target = target_position - agent.position;
|
acceleration.set_zero();
|
||||||
float distance_squared = to_target.length_squared();
|
}
|
||||||
|
|
||||||
if (distance_squared < agent.zero_linear_speed_threshold) {
|
else {
|
||||||
acceleration.set_zero();
|
float orientation = ;
|
||||||
|
|
||||||
|
if (use_z) {
|
||||||
|
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) {
|
||||||
else {
|
face(acceleration, target.position);
|
||||||
float orientation = ;
|
}
|
||||||
|
|
||||||
if (use_z) {
|
|
||||||
orientation = GSAIUtils.vector3_to_angle(to_target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIFace::GSAIFace() {
|
||||||
else {
|
|
||||||
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(to_target));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match_orientation(acceleration, orientation);
|
GSAIFace::~GSAIFace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIFace::_bind_methods() {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GSAIFace::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
face(acceleration, target.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIFace::GSAIFace() {
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIFace::~GSAIFace() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIFace::_bind_methods() {
|
|
||||||
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,26 +1,23 @@
|
|||||||
#ifndef GSAIFACE_H
|
#ifndef GSAIFACE_H
|
||||||
#define GSAIFACE_H
|
#define GSAIFACE_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIFace : public GSAIMatchOrientation {
|
class GSAIFace : public GSAIMatchOrientation {
|
||||||
GDCLASS(GSAIFace, GSAIMatchOrientation);
|
GDCLASS(GSAIFace, GSAIMatchOrientation);
|
||||||
|
|
||||||
public:
|
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 GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
GSAIFace();
|
||||||
void _face(const GSAITargetAcceleration &acceleration, const Vector3 &target_position);
|
~GSAIFace();
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
|
||||||
|
|
||||||
GSAIFace();
|
protected:
|
||||||
~GSAIFace();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates angular acceleration to rotate a target to face its target's
|
||||||
static void _bind_methods();
|
// position. The behavior attemps to arrive with zero remaining angular velocity.
|
||||||
|
// @category - Individual behaviors
|
||||||
// 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,29 +1,21 @@
|
|||||||
|
|
||||||
#include "gsai_flee.h"
|
#include "gsai_flee.h"
|
||||||
|
|
||||||
|
// Calculates acceleration to take an agent directly away from a target agent.;
|
||||||
|
// @category - Individual behaviors;
|
||||||
|
|
||||||
|
void GSAIFlee::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
// Calculates acceleration to take an agent directly away from a target agent.;
|
acceleration.linear = ((agent.position - target.position).normalized() * agent.linear_acceleration_max);
|
||||||
// @category - Individual behaviors;
|
acceleration.angular = 0;
|
||||||
|
}
|
||||||
void GSAIFlee::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
acceleration.linear = ((agent.position - target.position).normalized() * agent.linear_acceleration_max);
|
|
||||||
acceleration.angular = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIFlee::GSAIFlee() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIFlee::GSAIFlee() {
|
GSAIFlee::~GSAIFlee() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIFlee::~GSAIFlee() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIFlee::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFlee::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void GSAIFlee::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFlee::_calculate_steering);
|
||||||
|
}
|
||||||
|
@ -1,23 +1,20 @@
|
|||||||
#ifndef GSAIFLEE_H
|
#ifndef GSAIFLEE_H
|
||||||
#define GSAIFLEE_H
|
#define GSAIFLEE_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIFlee : public GSAISeek {
|
class GSAIFlee : public GSAISeek {
|
||||||
GDCLASS(GSAIFlee, GSAISeek);
|
GDCLASS(GSAIFlee, GSAISeek);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAIFlee();
|
||||||
|
~GSAIFlee();
|
||||||
|
|
||||||
GSAIFlee();
|
protected:
|
||||||
~GSAIFlee();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates acceleration to take an agent directly away from a target agent.
|
||||||
static void _bind_methods();
|
// @category - Individual behaviors
|
||||||
|
|
||||||
// Calculates acceleration to take an agent directly away from a target agent.
|
|
||||||
// @category - Individual behaviors
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,146 +1,121 @@
|
|||||||
|
|
||||||
#include "gsai_follow_path.h"
|
#include "gsai_follow_path.h"
|
||||||
|
|
||||||
|
GSAIPath GSAIFollowPath::get_ *path() {
|
||||||
GSAIPath GSAIFollowPath::get_*path() {
|
return *path;
|
||||||
return *path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIFollowPath::set_*path(const GSAIPath &val) {
|
void GSAIFollowPath::set_ *path(const GSAIPath &val) {
|
||||||
*path = val;
|
*path = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIFollowPath::get_path_offset() const {
|
float GSAIFollowPath::get_path_offset() const {
|
||||||
return path_offset;
|
return path_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIFollowPath::set_path_offset(const float val) {
|
void GSAIFollowPath::set_path_offset(const float val) {
|
||||||
path_offset = val;
|
path_offset = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAIFollowPath::get_is_arrive_enabled() const {
|
bool GSAIFollowPath::get_is_arrive_enabled() const {
|
||||||
return is_arrive_enabled;
|
return is_arrive_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIFollowPath::set_is_arrive_enabled(const bool val) {
|
void GSAIFollowPath::set_is_arrive_enabled(const bool val) {
|
||||||
is_arrive_enabled = val;
|
is_arrive_enabled = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIFollowPath::get_prediction_time() const {
|
float GSAIFollowPath::get_prediction_time() const {
|
||||||
return prediction_time;
|
return prediction_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIFollowPath::set_prediction_time(const float val) {
|
void GSAIFollowPath::set_prediction_time(const float val) {
|
||||||
prediction_time = val;
|
prediction_time = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Produces a linear acceleration that moves the agent along the specified path.;
|
||||||
|
// @category - Individual behaviors;
|
||||||
|
// The path to follow and travel along.;
|
||||||
|
GSAIPath *path;
|
||||||
|
// The distance along the path to generate the next target position.;
|
||||||
|
float path_offset = 0.0;
|
||||||
|
// Whether to use `GSAIArrive` behavior on an open path.;
|
||||||
|
bool is_arrive_enabled = true;
|
||||||
|
// The amount of time in the future to predict the owning agent's position along;
|
||||||
|
// the path. Setting it to 0.0 will force non-predictive path following.;
|
||||||
|
float prediction_time = 0.0;
|
||||||
|
|
||||||
|
void GSAIFollowPath::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
|
Vector3 location = ;
|
||||||
|
|
||||||
// Produces a linear acceleration that moves the agent along the specified path.;
|
if (prediction_time == 0) {
|
||||||
// @category - Individual behaviors;
|
location = agent.position;
|
||||||
// The path to follow and travel along.;
|
}
|
||||||
GSAIPath *path;
|
|
||||||
// The distance along the path to generate the next target position.;
|
|
||||||
float path_offset = 0.0;
|
|
||||||
// Whether to use `GSAIArrive` behavior on an open path.;
|
|
||||||
bool is_arrive_enabled = true;
|
|
||||||
// The amount of time in the future to predict the owning agent's position along;
|
|
||||||
// the path. Setting it to 0.0 will force non-predictive path following.;
|
|
||||||
float prediction_time = 0.0;
|
|
||||||
|
|
||||||
void GSAIFollowPath::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
else {
|
||||||
Vector3 location = ;
|
location = agent.position + (agent.linear_velocity * prediction_time);
|
||||||
|
}
|
||||||
|
|
||||||
if (prediction_time == 0) {
|
float distance = path.calculate_distance(location);
|
||||||
location = agent.position;
|
float target_distance = distance + path_offset;
|
||||||
|
|
||||||
|
if (prediction_time > 0 && path.is_open) {
|
||||||
|
if (target_distance < path.calculate_distance(agent.position)) {
|
||||||
|
target_distance = path.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 target_position = path.calculate_target_position(target_distance);
|
||||||
|
|
||||||
|
if (is_arrive_enabled && path.is_open) {
|
||||||
|
if (path_offset >= 0) {
|
||||||
|
if (target_distance > path.length - deceleration_radius) {
|
||||||
|
arrive(acceleration, target_position);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (target_distance < deceleration_radius) {
|
||||||
|
arrive(acceleration, target_position);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acceleration.linear = (target_position - agent.position).normalized();
|
||||||
|
acceleration.linear *= agent.linear_acceleration_max;
|
||||||
|
acceleration.angular = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIFollowPath::GSAIFollowPath() {
|
||||||
else {
|
*path;
|
||||||
location = agent.position + (agent.linear_velocity * prediction_time);
|
path_offset = 0.0;
|
||||||
|
is_arrive_enabled = true;
|
||||||
|
prediction_time = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float distance = path.calculate_distance(location);
|
GSAIFollowPath::~GSAIFollowPath() {
|
||||||
float target_distance = distance + path_offset;
|
|
||||||
|
|
||||||
if (prediction_time > 0 && path.is_open) {
|
|
||||||
|
|
||||||
if (target_distance < path.calculate_distance(agent.position)) {
|
|
||||||
target_distance = path.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIFollowPath::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*path"), &GSAIFollowPath::get_ * path);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*path", "value"), &GSAIFollowPath::set_ * path);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*path", PROPERTY_HINT_RESOURCE_TYPE, "GSAIPath"), "set_*path", "get_*path");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_path_offset"), &GSAIFollowPath::get_path_offset);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_path_offset", "value"), &GSAIFollowPath::set_path_offset);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_offset"), "set_path_offset", "get_path_offset");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_is_arrive_enabled"), &GSAIFollowPath::get_is_arrive_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_is_arrive_enabled", "value"), &GSAIFollowPath::set_is_arrive_enabled);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_arrive_enabled"), "set_is_arrive_enabled", "get_is_arrive_enabled");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_prediction_time"), &GSAIFollowPath::get_prediction_time);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_prediction_time", "value"), &GSAIFollowPath::set_prediction_time);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "prediction_time"), "set_prediction_time", "get_prediction_time");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFollowPath::_calculate_steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 target_position = path.calculate_target_position(target_distance);
|
|
||||||
|
|
||||||
if (is_arrive_enabled && path.is_open) {
|
|
||||||
|
|
||||||
if (path_offset >= 0) {
|
|
||||||
|
|
||||||
if (target_distance > path.length - deceleration_radius) {
|
|
||||||
arrive(acceleration, target_position);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
|
|
||||||
if (target_distance < deceleration_radius) {
|
|
||||||
arrive(acceleration, target_position);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
acceleration.linear = (target_position - agent.position).normalized();
|
|
||||||
acceleration.linear *= agent.linear_acceleration_max;
|
|
||||||
acceleration.angular = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIFollowPath::GSAIFollowPath() {
|
|
||||||
*path;
|
|
||||||
path_offset = 0.0;
|
|
||||||
is_arrive_enabled = true;
|
|
||||||
prediction_time = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIFollowPath::~GSAIFollowPath() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIFollowPath::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*path"), &GSAIFollowPath::get_*path);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*path", "value"), &GSAIFollowPath::set_*path);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*path", PROPERTY_HINT_RESOURCE_TYPE, "GSAIPath"), "set_*path", "get_*path");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_path_offset"), &GSAIFollowPath::get_path_offset);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_path_offset", "value"), &GSAIFollowPath::set_path_offset);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_offset"), "set_path_offset", "get_path_offset");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_is_arrive_enabled"), &GSAIFollowPath::get_is_arrive_enabled);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_is_arrive_enabled", "value"), &GSAIFollowPath::set_is_arrive_enabled);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_arrive_enabled"), "set_is_arrive_enabled", "get_is_arrive_enabled");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_prediction_time"), &GSAIFollowPath::get_prediction_time);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_prediction_time", "value"), &GSAIFollowPath::set_prediction_time);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "prediction_time"), "set_prediction_time", "get_prediction_time");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIFollowPath::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,44 +1,41 @@
|
|||||||
#ifndef GSAIFOLLOWPATH_H
|
#ifndef GSAIFOLLOWPATH_H
|
||||||
#define GSAIFOLLOWPATH_H
|
#define GSAIFOLLOWPATH_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIFollowPath : public GSAIArrive {
|
class GSAIFollowPath : public GSAIArrive {
|
||||||
GDCLASS(GSAIFollowPath, GSAIArrive);
|
GDCLASS(GSAIFollowPath, GSAIArrive);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAIPath get_ *path();
|
||||||
|
void set_ *path(const GSAIPath &val);
|
||||||
|
|
||||||
GSAIPath get_*path();
|
float get_path_offset() const;
|
||||||
void set_*path(const GSAIPath &val);
|
void set_path_offset(const float val);
|
||||||
|
|
||||||
float get_path_offset() const;
|
bool get_is_arrive_enabled() const;
|
||||||
void set_path_offset(const float val);
|
void set_is_arrive_enabled(const bool val);
|
||||||
|
|
||||||
bool get_is_arrive_enabled() const;
|
float get_prediction_time() const;
|
||||||
void set_is_arrive_enabled(const bool val);
|
void set_prediction_time(const float val);
|
||||||
|
|
||||||
float get_prediction_time() const;
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set_prediction_time(const float val);
|
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAIFollowPath();
|
||||||
|
~GSAIFollowPath();
|
||||||
|
|
||||||
GSAIFollowPath();
|
protected:
|
||||||
~GSAIFollowPath();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Produces a linear acceleration that moves the agent along the specified path.
|
||||||
static void _bind_methods();
|
// @category - Individual behaviors
|
||||||
|
// The path to follow and travel along.
|
||||||
// Produces a linear acceleration that moves the agent along the specified path.
|
GSAIPath *path;
|
||||||
// @category - Individual behaviors
|
// The distance along the path to generate the next target position.
|
||||||
// The path to follow and travel along.
|
float path_offset = 0.0;
|
||||||
GSAIPath *path;
|
// Whether to use `GSAIArrive` behavior on an open path.
|
||||||
// The distance along the path to generate the next target position.
|
bool is_arrive_enabled = true;
|
||||||
float path_offset = 0.0;
|
// The amount of time in the future to predict the owning agent's position along
|
||||||
// Whether to use `GSAIArrive` behavior on an open path.
|
// the path. Setting it to 0.0 will force non-predictive path following.
|
||||||
bool is_arrive_enabled = true;
|
float prediction_time = 0.0;
|
||||||
// The amount of time in the future to predict the owning agent's position along
|
|
||||||
// the path. Setting it to 0.0 will force non-predictive path following.
|
|
||||||
float prediction_time = 0.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,49 +1,37 @@
|
|||||||
|
|
||||||
#include "gsai_look_where_you_go.h"
|
#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;
|
||||||
|
|
||||||
|
void GSAILookWhereYouGo::_calculate_steering(const GSAITargetAcceleration &accel) {
|
||||||
|
if (agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold) {
|
||||||
|
accel.set_zero();
|
||||||
|
}
|
||||||
|
|
||||||
// Calculates an angular acceleration to match an agent's orientation to its;
|
else {
|
||||||
// direction of travel.;
|
float orientation = ;
|
||||||
// @category - Individual behaviors;
|
|
||||||
|
|
||||||
void GSAILookWhereYouGo::_calculate_steering(const GSAITargetAcceleration &accel) {
|
if (use_z) {
|
||||||
|
orientation = GSAIUtils.vector3_to_angle(agent.linear_velocity);
|
||||||
|
}
|
||||||
|
|
||||||
if (agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold) {
|
else {
|
||||||
accel.set_zero();
|
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(agent.linear_velocity));
|
||||||
|
}
|
||||||
|
|
||||||
|
match_orientation(accel, orientation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAILookWhereYouGo::GSAILookWhereYouGo() {
|
||||||
else {
|
|
||||||
float orientation = ;
|
|
||||||
|
|
||||||
if (use_z) {
|
|
||||||
orientation = GSAIUtils.vector3_to_angle(agent.linear_velocity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAILookWhereYouGo::~GSAILookWhereYouGo() {
|
||||||
else {
|
|
||||||
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(agent.linear_velocity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match_orientation(accel, orientation);
|
static void GSAILookWhereYouGo::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "accel"), &GSAILookWhereYouGo::_calculate_steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAILookWhereYouGo::GSAILookWhereYouGo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAILookWhereYouGo::~GSAILookWhereYouGo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAILookWhereYouGo::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "accel"), &GSAILookWhereYouGo::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,24 +1,21 @@
|
|||||||
#ifndef GSAILOOKWHEREYOUGO_H
|
#ifndef GSAILOOKWHEREYOUGO_H
|
||||||
#define GSAILOOKWHEREYOUGO_H
|
#define GSAILOOKWHEREYOUGO_H
|
||||||
|
|
||||||
|
|
||||||
class GSAILookWhereYouGo : public GSAIMatchOrientation {
|
class GSAILookWhereYouGo : public GSAIMatchOrientation {
|
||||||
GDCLASS(GSAILookWhereYouGo, GSAIMatchOrientation);
|
GDCLASS(GSAILookWhereYouGo, GSAIMatchOrientation);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &accel);
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &accel);
|
GSAILookWhereYouGo();
|
||||||
|
~GSAILookWhereYouGo();
|
||||||
|
|
||||||
GSAILookWhereYouGo();
|
protected:
|
||||||
~GSAILookWhereYouGo();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an angular acceleration to match an agent's orientation to its
|
||||||
static void _bind_methods();
|
// direction of travel.
|
||||||
|
// @category - Individual behaviors
|
||||||
// Calculates an angular acceleration to match an agent's orientation to its
|
|
||||||
// direction of travel.
|
|
||||||
// @category - Individual behaviors
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,154 +1,132 @@
|
|||||||
|
|
||||||
#include "gsai_match_orientation.h"
|
#include "gsai_match_orientation.h"
|
||||||
|
|
||||||
|
GSAIAgentLocation GSAIMatchOrientation::get_ *target() {
|
||||||
GSAIAgentLocation GSAIMatchOrientation::get_*target() {
|
return *target;
|
||||||
return *target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIMatchOrientation::set_*target(const GSAIAgentLocation &val) {
|
void GSAIMatchOrientation::set_ *target(const GSAIAgentLocation &val) {
|
||||||
*target = val;
|
*target = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIMatchOrientation::get_alignment_tolerance() const {
|
float GSAIMatchOrientation::get_alignment_tolerance() const {
|
||||||
return alignment_tolerance;
|
return alignment_tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIMatchOrientation::set_alignment_tolerance(const float val) {
|
void GSAIMatchOrientation::set_alignment_tolerance(const float val) {
|
||||||
alignment_tolerance = val;
|
alignment_tolerance = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIMatchOrientation::get_deceleration_radius() const {
|
float GSAIMatchOrientation::get_deceleration_radius() const {
|
||||||
return deceleration_radius;
|
return deceleration_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIMatchOrientation::set_deceleration_radius(const float val) {
|
void GSAIMatchOrientation::set_deceleration_radius(const float val) {
|
||||||
deceleration_radius = val;
|
deceleration_radius = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIMatchOrientation::get_time_to_reach() const {
|
float GSAIMatchOrientation::get_time_to_reach() const {
|
||||||
return time_to_reach;
|
return time_to_reach;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIMatchOrientation::set_time_to_reach(const float val) {
|
void GSAIMatchOrientation::set_time_to_reach(const float val) {
|
||||||
time_to_reach = val;
|
time_to_reach = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAIMatchOrientation::get_use_z() const {
|
bool GSAIMatchOrientation::get_use_z() const {
|
||||||
return use_z;
|
return use_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIMatchOrientation::set_use_z(const bool val) {
|
void GSAIMatchOrientation::set_use_z(const bool val) {
|
||||||
use_z = 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) {
|
||||||
// Calculates an angular acceleration to match an agent's orientation to that of;
|
call("_match_orientation", acceleration, desired_orientation);
|
||||||
// its target. Attempts to make the agent arrive with zero remaining angular;
|
|
||||||
// velocity.;
|
|
||||||
// @category - Individual behaviors;
|
|
||||||
// The target orientation for the behavior to try and match rotations to.;
|
|
||||||
GSAIAgentLocation *target;
|
|
||||||
// The amount of distance in radians for the behavior to consider itself close;
|
|
||||||
// enough to be matching the target agent's rotation.;
|
|
||||||
float alignment_tolerance = 0.0;
|
|
||||||
// The amount of distance in radians from the goal to start slowing down.;
|
|
||||||
float deceleration_radius = 0.0;
|
|
||||||
// The amount of time to reach the target velocity;
|
|
||||||
float time_to_reach = 0.1;
|
|
||||||
// Whether to use the X and Z components instead of X and Y components when;
|
|
||||||
// determining angles. X and Z should be used in 3D.;
|
|
||||||
bool use_z = false;
|
|
||||||
|
|
||||||
void GSAIMatchOrientation::match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation) {
|
|
||||||
call("_match_orientation", acceleration, desired_orientation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIMatchOrientation::_match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation) {
|
||||||
|
float rotation = wrapf(desired_orientation - agent.orientation, -PI, PI);
|
||||||
|
float rotation_size = abs(rotation);
|
||||||
|
|
||||||
void GSAIMatchOrientation::_match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation) {
|
if (rotation_size <= alignment_tolerance) {
|
||||||
float rotation = wrapf(desired_orientation - agent.orientation, -PI, PI);
|
acceleration.set_zero();
|
||||||
float rotation_size = abs(rotation);
|
}
|
||||||
|
|
||||||
if (rotation_size <= alignment_tolerance) {
|
else {
|
||||||
acceleration.set_zero();
|
float desired_rotation = agent.angular_speed_max;
|
||||||
|
|
||||||
|
if (rotation_size <= deceleration_radius) {
|
||||||
|
desired_rotation *= rotation_size / deceleration_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
desired_rotation *= rotation / rotation_size;
|
||||||
|
acceleration.angular = ((desired_rotation - agent.angular_velocity) / time_to_reach);
|
||||||
|
float limited_acceleration = abs(acceleration.angular);
|
||||||
|
|
||||||
|
if (limited_acceleration > agent.angular_acceleration_max) {
|
||||||
|
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acceleration.linear = Vector3.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAIMatchOrientation::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
else {
|
match_orientation(acceleration, target.orientation);
|
||||||
float desired_rotation = agent.angular_speed_max;
|
}
|
||||||
|
|
||||||
if (rotation_size <= deceleration_radius) {
|
|
||||||
desired_rotation *= rotation_size / deceleration_radius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
desired_rotation *= rotation / rotation_size;
|
GSAIMatchOrientation::GSAIMatchOrientation() {
|
||||||
acceleration.angular = ((desired_rotation - agent.angular_velocity) / time_to_reach);
|
*target;
|
||||||
float limited_acceleration = abs(acceleration.angular);
|
alignment_tolerance = 0.0;
|
||||||
|
deceleration_radius = 0.0;
|
||||||
if (limited_acceleration > agent.angular_acceleration_max) {
|
time_to_reach = 0.1;
|
||||||
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration);
|
use_z = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIMatchOrientation::~GSAIMatchOrientation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
acceleration.linear = Vector3.ZERO;
|
static void GSAIMatchOrientation::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIMatchOrientation::get_ * target);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIMatchOrientation::set_ * target);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_alignment_tolerance"), &GSAIMatchOrientation::get_alignment_tolerance);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_alignment_tolerance", "value"), &GSAIMatchOrientation::set_alignment_tolerance);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "alignment_tolerance"), "set_alignment_tolerance", "get_alignment_tolerance");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_deceleration_radius"), &GSAIMatchOrientation::get_deceleration_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_deceleration_radius", "value"), &GSAIMatchOrientation::set_deceleration_radius);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "deceleration_radius"), "set_deceleration_radius", "get_deceleration_radius");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_time_to_reach"), &GSAIMatchOrientation::get_time_to_reach);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_time_to_reach", "value"), &GSAIMatchOrientation::set_time_to_reach);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_to_reach"), "set_time_to_reach", "get_time_to_reach");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_use_z"), &GSAIMatchOrientation::get_use_z);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_use_z", "value"), &GSAIMatchOrientation::set_use_z);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_z"), "set_use_z", "get_use_z");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::match_orientation);
|
||||||
|
ClassDB::bind_method(D_METHOD("_match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::_match_orientation);
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIMatchOrientation::_calculate_steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GSAIMatchOrientation::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
match_orientation(acceleration, target.orientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIMatchOrientation::GSAIMatchOrientation() {
|
|
||||||
*target;
|
|
||||||
alignment_tolerance = 0.0;
|
|
||||||
deceleration_radius = 0.0;
|
|
||||||
time_to_reach = 0.1;
|
|
||||||
use_z = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIMatchOrientation::~GSAIMatchOrientation() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIMatchOrientation::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*target"), &GSAIMatchOrientation::get_*target);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*target", "value"), &GSAIMatchOrientation::set_*target);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*target", PROPERTY_HINT_RESOURCE_TYPE, "GSAIAgentLocation"), "set_*target", "get_*target");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_alignment_tolerance"), &GSAIMatchOrientation::get_alignment_tolerance);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_alignment_tolerance", "value"), &GSAIMatchOrientation::set_alignment_tolerance);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "alignment_tolerance"), "set_alignment_tolerance", "get_alignment_tolerance");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_deceleration_radius"), &GSAIMatchOrientation::get_deceleration_radius);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_deceleration_radius", "value"), &GSAIMatchOrientation::set_deceleration_radius);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "deceleration_radius"), "set_deceleration_radius", "get_deceleration_radius");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_time_to_reach"), &GSAIMatchOrientation::get_time_to_reach);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_time_to_reach", "value"), &GSAIMatchOrientation::set_time_to_reach);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_to_reach"), "set_time_to_reach", "get_time_to_reach");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_use_z"), &GSAIMatchOrientation::get_use_z);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_use_z", "value"), &GSAIMatchOrientation::set_use_z);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_z"), "set_use_z", "get_use_z");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::match_orientation);
|
|
||||||
ClassDB::bind_method(D_METHOD("_match_orientation", "acceleration", "desired_orientation"), &GSAIMatchOrientation::_match_orientation);
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAIMatchOrientation::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,54 +1,51 @@
|
|||||||
#ifndef GSAIMATCHORIENTATION_H
|
#ifndef GSAIMATCHORIENTATION_H
|
||||||
#define GSAIMATCHORIENTATION_H
|
#define GSAIMATCHORIENTATION_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIMatchOrientation : public GSAISteeringBehavior {
|
class GSAIMatchOrientation : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIMatchOrientation, GSAISteeringBehavior);
|
GDCLASS(GSAIMatchOrientation, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAIAgentLocation get_ *target();
|
||||||
|
void set_ *target(const GSAIAgentLocation &val);
|
||||||
|
|
||||||
GSAIAgentLocation get_*target();
|
float get_alignment_tolerance() const;
|
||||||
void set_*target(const GSAIAgentLocation &val);
|
void set_alignment_tolerance(const float val);
|
||||||
|
|
||||||
float get_alignment_tolerance() const;
|
float get_deceleration_radius() const;
|
||||||
void set_alignment_tolerance(const float val);
|
void set_deceleration_radius(const float val);
|
||||||
|
|
||||||
float get_deceleration_radius() const;
|
float get_time_to_reach() const;
|
||||||
void set_deceleration_radius(const float val);
|
void set_time_to_reach(const float val);
|
||||||
|
|
||||||
float get_time_to_reach() const;
|
bool get_use_z() const;
|
||||||
void set_time_to_reach(const float val);
|
void set_use_z(const bool val);
|
||||||
|
|
||||||
bool get_use_z() const;
|
void match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
||||||
void set_use_z(const bool val);
|
void _match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
|
|
||||||
void match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
GSAIMatchOrientation();
|
||||||
void _match_orientation(const GSAITargetAcceleration &acceleration, const float desired_orientation);
|
~GSAIMatchOrientation();
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
|
||||||
|
|
||||||
GSAIMatchOrientation();
|
protected:
|
||||||
~GSAIMatchOrientation();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an angular acceleration to match an agent's orientation to that of
|
||||||
static void _bind_methods();
|
// its target. Attempts to make the agent arrive with zero remaining angular
|
||||||
|
// velocity.
|
||||||
// Calculates an angular acceleration to match an agent's orientation to that of
|
// @category - Individual behaviors
|
||||||
// its target. Attempts to make the agent arrive with zero remaining angular
|
// The target orientation for the behavior to try and match rotations to.
|
||||||
// velocity.
|
GSAIAgentLocation *target;
|
||||||
// @category - Individual behaviors
|
// The amount of distance in radians for the behavior to consider itself close
|
||||||
// The target orientation for the behavior to try and match rotations to.
|
// enough to be matching the target agent's rotation.
|
||||||
GSAIAgentLocation *target;
|
float alignment_tolerance = 0.0;
|
||||||
// The amount of distance in radians for the behavior to consider itself close
|
// The amount of distance in radians from the goal to start slowing down.
|
||||||
// enough to be matching the target agent's rotation.
|
float deceleration_radius = 0.0;
|
||||||
float alignment_tolerance = 0.0;
|
// The amount of time to reach the target velocity
|
||||||
// The amount of distance in radians from the goal to start slowing down.
|
float time_to_reach = 0.1;
|
||||||
float deceleration_radius = 0.0;
|
// Whether to use the X and Z components instead of X and Y components when
|
||||||
// The amount of time to reach the target velocity
|
// determining angles. X and Z should be used in 3D.
|
||||||
float time_to_reach = 0.1;
|
bool use_z = false;
|
||||||
// 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,143 +1,120 @@
|
|||||||
|
|
||||||
#include "gsai_priority.h"
|
#include "gsai_priority.h"
|
||||||
|
|
||||||
|
|
||||||
float GSAIPriority::get_zero_threshold() const {
|
float GSAIPriority::get_zero_threshold() const {
|
||||||
return zero_threshold;
|
return zero_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPriority::set_zero_threshold(const float val) {
|
void GSAIPriority::set_zero_threshold(const float val) {
|
||||||
zero_threshold = val;
|
zero_threshold = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GSAIPriority::get__last_selected_index() const {
|
int GSAIPriority::get__last_selected_index() const {
|
||||||
return _last_selected_index;
|
return _last_selected_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPriority::set__last_selected_index(const int val) {
|
void GSAIPriority::set__last_selected_index(const int val) {
|
||||||
_last_selected_index = val;
|
_last_selected_index = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Array GSAIPriority::get__behaviors() {
|
Array GSAIPriority::get__behaviors() {
|
||||||
return _behaviors;
|
return _behaviors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPriority::set__behaviors(const Array &val) {
|
void GSAIPriority::set__behaviors(const Array &val) {
|
||||||
_behaviors = 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) {
|
||||||
// Container for multiple behaviors that returns the result of the first child;
|
_behaviors.append(behavior);
|
||||||
// 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;
|
// Returns the behavior at the position in the pool referred to by `index`, or;
|
||||||
// `null` if no behavior was found.;
|
// `null` if no behavior was found.;
|
||||||
|
|
||||||
GSAISteeringBehavior GSAIPriority::get_behavior(const int index) {
|
GSAISteeringBehavior GSAIPriority::get_behavior(const int index) {
|
||||||
|
if (_behaviors.size() > index) {
|
||||||
|
return _behaviors[index];
|
||||||
|
}
|
||||||
|
|
||||||
if (_behaviors.size() > index) {
|
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||||
return _behaviors[index];
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
void GSAIPriority::remove_behavior(const int index) {
|
||||||
return null;
|
if (_behaviors.size() > index) {
|
||||||
|
_behaviors.remove(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GSAIPriority::get_behaviour_count() {
|
||||||
void GSAIPriority::remove_behavior(const int index) {
|
return _behaviors.size();
|
||||||
|
|
||||||
if (_behaviors.size() > index) {
|
|
||||||
_behaviors.remove(index);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()));
|
void GSAIPriority::_calculate_steering(const GSAITargetAcceleration &accel) {
|
||||||
return;
|
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) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
accel.set_zero();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIPriority::GSAIPriority() {
|
||||||
int GSAIPriority::get_behaviour_count() {
|
zero_threshold = 0.0;
|
||||||
return _behaviors.size();
|
_last_selected_index = 0;
|
||||||
|
_behaviors = Array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIPriority::~GSAIPriority() {
|
||||||
void GSAIPriority::_calculate_steering(const 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) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
accel.set_zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIPriority::GSAIPriority() {
|
|
||||||
zero_threshold = 0.0;
|
|
||||||
_last_selected_index = 0;
|
|
||||||
_behaviors = Array();
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIPriority::~GSAIPriority() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static 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,46 +1,43 @@
|
|||||||
#ifndef GSAIPRIORITY_H
|
#ifndef GSAIPRIORITY_H
|
||||||
#define GSAIPRIORITY_H
|
#define GSAIPRIORITY_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIPriority : public GSAISteeringBehavior {
|
class GSAIPriority : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIPriority, GSAISteeringBehavior);
|
GDCLASS(GSAIPriority, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float get_zero_threshold() const;
|
||||||
|
void set_zero_threshold(const float val);
|
||||||
|
|
||||||
float get_zero_threshold() const;
|
int get__last_selected_index() const;
|
||||||
void set_zero_threshold(const float val);
|
void set__last_selected_index(const int val);
|
||||||
|
|
||||||
int get__last_selected_index() const;
|
Array get__behaviors();
|
||||||
void set__last_selected_index(const int val);
|
void set__behaviors(const Array &val);
|
||||||
|
|
||||||
Array get__behaviors();
|
void add_behavior(const GSAISteeringBehavior &behavior);
|
||||||
void set__behaviors(const Array &val);
|
GSAISteeringBehavior get_behavior(const int index);
|
||||||
|
void remove_behavior(const int index);
|
||||||
|
int get_behaviour_count();
|
||||||
|
void _calculate_steering(const GSAITargetAcceleration &accel);
|
||||||
|
|
||||||
void add_behavior(const GSAISteeringBehavior &behavior);
|
GSAIPriority();
|
||||||
GSAISteeringBehavior get_behavior(const int index);
|
~GSAIPriority();
|
||||||
void remove_behavior(const int index);
|
|
||||||
int get_behaviour_count();
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &accel);
|
|
||||||
|
|
||||||
GSAIPriority();
|
protected:
|
||||||
~GSAIPriority();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Container for multiple behaviors that returns the result of the first child
|
||||||
static void _bind_methods();
|
// behavior with non-zero acceleration.
|
||||||
|
// @category - Combination behaviors
|
||||||
// Container for multiple behaviors that returns the result of the first child
|
// If a behavior's acceleration is lower than this threshold, the container
|
||||||
// behavior with non-zero acceleration.
|
// considers it has an acceleration of zero.
|
||||||
// @category - Combination behaviors
|
float zero_threshold = 0.0;
|
||||||
// If a behavior's acceleration is lower than this threshold, the container
|
// The index of the last behavior the container prioritized.
|
||||||
// considers it has an acceleration of zero.
|
int _last_selected_index = 0;
|
||||||
float zero_threshold = 0.0;
|
Array _behaviors = Array();
|
||||||
// The index of the last behavior the container prioritized.
|
// Appends a steering behavior as a child of this container.
|
||||||
int _last_selected_index = 0;
|
// Returns the behavior at the position in the pool referred to by `index`, or
|
||||||
Array _behaviors = Array();
|
// `null` if no behavior was found.
|
||||||
// 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.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,92 +1,77 @@
|
|||||||
|
|
||||||
#include "gsai_pursue.h"
|
#include "gsai_pursue.h"
|
||||||
|
|
||||||
|
GSAISteeringAgent GSAIPursue::get_ *target() {
|
||||||
GSAISteeringAgent GSAIPursue::get_*target() {
|
return *target;
|
||||||
return *target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPursue::set_*target(const GSAISteeringAgent &val) {
|
void GSAIPursue::set_ *target(const GSAISteeringAgent &val) {
|
||||||
*target = val;
|
*target = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIPursue::get_predict_time_max() const {
|
float GSAIPursue::get_predict_time_max() const {
|
||||||
return predict_time_max;
|
return predict_time_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPursue::set_predict_time_max(const float val) {
|
void GSAIPursue::set_predict_time_max(const float val) {
|
||||||
predict_time_max = 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(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();
|
||||||
|
float predict_time = predict_time_max;
|
||||||
|
|
||||||
// Calculates an acceleration to make an agent intercept another based on the;
|
if (speed_squared > 0) {
|
||||||
// target agent's movement.;
|
Variant predict_time_squared = distance_squared / speed_squared;
|
||||||
// @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(const GSAITargetAcceleration &acceleration) {
|
if (predict_time_squared < predict_time_max * predict_time_max) {
|
||||||
Vector3 target_position = target.position;
|
predict_time = sqrt(predict_time_squared);
|
||||||
float distance_squared = (target_position - agent.position).length_squared();
|
}
|
||||||
float speed_squared = agent.linear_velocity.length_squared();
|
}
|
||||||
float predict_time = predict_time_max;
|
|
||||||
|
|
||||||
if (speed_squared > 0) {
|
acceleration.linear = ((target_position + (target.linear_velocity * predict_time)) - agent.position).normalized();
|
||||||
Variant predict_time_squared = distance_squared / speed_squared;
|
acceleration.linear *= get_modified_acceleration();
|
||||||
|
acceleration.angular = 0;
|
||||||
if (predict_time_squared < predict_time_max * predict_time_max) {
|
|
||||||
predict_time = sqrt(predict_time_squared);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GSAIPursue::get_modified_acceleration() {
|
||||||
|
return call("_get_modified_acceleration");
|
||||||
}
|
}
|
||||||
|
|
||||||
acceleration.linear = ((target_position + (target.linear_velocity * predict_time)) - agent.position).normalized();
|
float GSAIPursue::_get_modified_acceleration() {
|
||||||
acceleration.linear *= get_modified_acceleration();
|
return agent.linear_acceleration_max;
|
||||||
acceleration.angular = 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIPursue::GSAIPursue() {
|
||||||
float GSAIPursue::get_modified_acceleration() {
|
*target;
|
||||||
return call("_get_modified_acceleration");
|
predict_time_max = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIPursue::~GSAIPursue() {
|
||||||
float GSAIPursue::_get_modified_acceleration() {
|
|
||||||
return agent.linear_acceleration_max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_modified_acceleration"), &GSAIPursue::get_modified_acceleration);
|
||||||
|
ClassDB::bind_method(D_METHOD("_get_modified_acceleration"), &GSAIPursue::_get_modified_acceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
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,37 +1,34 @@
|
|||||||
#ifndef GSAIPURSUE_H
|
#ifndef GSAIPURSUE_H
|
||||||
#define GSAIPURSUE_H
|
#define GSAIPURSUE_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIPursue : public GSAISteeringBehavior {
|
class GSAIPursue : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIPursue, GSAISteeringBehavior);
|
GDCLASS(GSAIPursue, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAISteeringAgent get_ *target();
|
||||||
|
void set_ *target(const GSAISteeringAgent &val);
|
||||||
|
|
||||||
GSAISteeringAgent get_*target();
|
float get_predict_time_max() const;
|
||||||
void set_*target(const GSAISteeringAgent &val);
|
void set_predict_time_max(const float val);
|
||||||
|
|
||||||
float get_predict_time_max() const;
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set_predict_time_max(const float val);
|
float get_modified_acceleration();
|
||||||
|
float _get_modified_acceleration();
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAIPursue();
|
||||||
float get_modified_acceleration();
|
~GSAIPursue();
|
||||||
float _get_modified_acceleration();
|
|
||||||
|
|
||||||
GSAIPursue();
|
protected:
|
||||||
~GSAIPursue();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an acceleration to make an agent intercept another based on the
|
||||||
static void _bind_methods();
|
// target agent's movement.
|
||||||
|
// @category - Individual behaviors
|
||||||
// Calculates an acceleration to make an agent intercept another based on the
|
// The target agent that the behavior is trying to intercept.
|
||||||
// target agent's movement.
|
GSAISteeringAgent *target;
|
||||||
// @category - Individual behaviors
|
// The maximum amount of time in the future the behavior predicts the target's
|
||||||
// The target agent that the behavior is trying to intercept.
|
// location.
|
||||||
GSAISteeringAgent *target;
|
float predict_time_max = 1.0;
|
||||||
// The maximum amount of time in the future the behavior predicts the target's
|
|
||||||
// location.
|
|
||||||
float predict_time_max = 1.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,47 +1,37 @@
|
|||||||
|
|
||||||
#include "gsai_seek.h"
|
#include "gsai_seek.h"
|
||||||
|
|
||||||
|
GSAIAgentLocation GSAISeek::get_ *target() {
|
||||||
GSAIAgentLocation GSAISeek::get_*target() {
|
return *target;
|
||||||
return *target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISeek::set_*target(const GSAIAgentLocation &val) {
|
void GSAISeek::set_ *target(const GSAIAgentLocation &val) {
|
||||||
*target = 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(const GSAITargetAcceleration &acceleration) {
|
||||||
// Calculates an acceleration to take an agent to a target agent's position;
|
acceleration.linear = ((target.position - agent.position).normalized() * agent.linear_acceleration_max);
|
||||||
// directly.;
|
acceleration.angular = 0;
|
||||||
// @category - Individual behaviors;
|
}
|
||||||
// The target that the behavior aims to move the agent to.;
|
|
||||||
GSAIAgentLocation *target;
|
|
||||||
|
|
||||||
void GSAISeek::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
acceleration.linear = ((target.position - agent.position).normalized() * agent.linear_acceleration_max);
|
|
||||||
acceleration.angular = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISeek::GSAISeek() {
|
||||||
|
*target;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISeek::GSAISeek() {
|
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@ -1,29 +1,26 @@
|
|||||||
#ifndef GSAISEEK_H
|
#ifndef GSAISEEK_H
|
||||||
#define GSAISEEK_H
|
#define GSAISEEK_H
|
||||||
|
|
||||||
|
|
||||||
class GSAISeek : public GSAISteeringBehavior {
|
class GSAISeek : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAISeek, GSAISteeringBehavior);
|
GDCLASS(GSAISeek, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAIAgentLocation get_ *target();
|
||||||
|
void set_ *target(const GSAIAgentLocation &val);
|
||||||
|
|
||||||
GSAIAgentLocation get_*target();
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set_*target(const GSAIAgentLocation &val);
|
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAISeek();
|
||||||
|
~GSAISeek();
|
||||||
|
|
||||||
GSAISeek();
|
protected:
|
||||||
~GSAISeek();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an acceleration to take an agent to a target agent's position
|
||||||
static void _bind_methods();
|
// directly.
|
||||||
|
// @category - Individual behaviors
|
||||||
// Calculates an acceleration to take an agent to a target agent's position
|
// The target that the behavior aims to move the agent to.
|
||||||
// directly.
|
GSAIAgentLocation *target;
|
||||||
// @category - Individual behaviors
|
|
||||||
// The target that the behavior aims to move the agent to.
|
|
||||||
GSAIAgentLocation *target;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,88 +1,76 @@
|
|||||||
|
|
||||||
#include "gsai_separation.h"
|
#include "gsai_separation.h"
|
||||||
|
|
||||||
|
|
||||||
float GSAISeparation::get_decay_coefficient() const {
|
float GSAISeparation::get_decay_coefficient() const {
|
||||||
return decay_coefficient;
|
return decay_coefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISeparation::set_decay_coefficient(const float val) {
|
void GSAISeparation::set_decay_coefficient(const float val) {
|
||||||
decay_coefficient = val;
|
decay_coefficient = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAITargetAcceleration GSAISeparation::get_ *acceleration() {
|
||||||
GSAITargetAcceleration GSAISeparation::get_*acceleration() {
|
return *acceleration;
|
||||||
return *acceleration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISeparation::set_*acceleration(const GSAITargetAcceleration &val) {
|
void GSAISeparation::set_ *acceleration(const GSAITargetAcceleration &val) {
|
||||||
*acceleration = 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(const GSAITargetAcceleration &_acceleration) {
|
||||||
// Calculates an acceleration that repels the agent from its neighbors in the;
|
self.acceleration = _acceleration;
|
||||||
// given `GSAIProximity`.;
|
acceleration.set_zero();
|
||||||
//;
|
// warning-ignore:return_value_discarded;
|
||||||
// The acceleration is an average based on all neighbors, multiplied by a;
|
proximity.find_neighbors(_callback);
|
||||||
// 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(const GSAITargetAcceleration &_acceleration) {
|
|
||||||
self.acceleration = _acceleration;
|
|
||||||
acceleration.set_zero();
|
|
||||||
// warning-ignore:return_value_discarded;
|
|
||||||
proximity.find_neighbors(_callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for the proximity to call when finding neighbors. Determines the amount of;
|
// 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.;
|
// acceleration that `neighbor` imposes based on its distance from the owner agent.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
bool GSAISeparation::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
bool GSAISeparation::_report_neighbor(const GSAISteeringAgent &neighbor) {
|
||||||
Vector3 to_agent = agent.position - neighbor.position;
|
Vector3 to_agent = agent.position - neighbor.position;
|
||||||
float distance_squared = to_agent.length_squared();
|
float distance_squared = to_agent.length_squared();
|
||||||
float acceleration_max = agent.linear_acceleration_max;
|
float acceleration_max = agent.linear_acceleration_max;
|
||||||
Variant strength = decay_coefficient / distance_squared;
|
Variant strength = decay_coefficient / distance_squared;
|
||||||
|
|
||||||
if (strength > acceleration_max) {
|
if (strength > acceleration_max) {
|
||||||
strength = acceleration_max;
|
strength = acceleration_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
acceleration.linear += to_agent * (strength / sqrt(distance_squared));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
acceleration.linear += to_agent * (strength / sqrt(distance_squared));
|
GSAISeparation::GSAISeparation() {
|
||||||
return true;
|
decay_coefficient = 1.0;
|
||||||
|
*acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISeparation::~GSAISeparation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISeparation::GSAISeparation() {
|
static void GSAISeparation::_bind_methods() {
|
||||||
decay_coefficient = 1.0;
|
ClassDB::bind_method(D_METHOD("get_decay_coefficient"), &GSAISeparation::get_decay_coefficient);
|
||||||
*acceleration;
|
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");
|
||||||
|
|
||||||
GSAISeparation::~GSAISeparation() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static 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");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "_acceleration"), &GSAISeparation::_calculate_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_report_neighbor", "neighbor"), &GSAISeparation::_report_neighbor);
|
||||||
|
}
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
#ifndef GSAISEPARATION_H
|
#ifndef GSAISEPARATION_H
|
||||||
#define GSAISEPARATION_H
|
#define GSAISEPARATION_H
|
||||||
|
|
||||||
|
|
||||||
class GSAISeparation : public GSAIGroupBehavior {
|
class GSAISeparation : public GSAIGroupBehavior {
|
||||||
GDCLASS(GSAISeparation, GSAIGroupBehavior);
|
GDCLASS(GSAISeparation, GSAIGroupBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float get_decay_coefficient() const;
|
||||||
|
void set_decay_coefficient(const float val);
|
||||||
|
|
||||||
float get_decay_coefficient() const;
|
GSAITargetAcceleration get_ *acceleration();
|
||||||
void set_decay_coefficient(const float val);
|
void set_ *acceleration(const GSAITargetAcceleration &val);
|
||||||
|
|
||||||
GSAITargetAcceleration get_*acceleration();
|
void _calculate_steering(const GSAITargetAcceleration &_acceleration);
|
||||||
void set_*acceleration(const GSAITargetAcceleration &val);
|
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
||||||
|
|
||||||
void _calculate_steering(const GSAITargetAcceleration &_acceleration);
|
GSAISeparation();
|
||||||
bool _report_neighbor(const GSAISteeringAgent &neighbor);
|
~GSAISeparation();
|
||||||
|
|
||||||
GSAISeparation();
|
protected:
|
||||||
~GSAISeparation();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Calculates an acceleration that repels the agent from its neighbors in the
|
||||||
static void _bind_methods();
|
// given `GSAIProximity`.
|
||||||
|
//
|
||||||
// Calculates an acceleration that repels the agent from its neighbors in the
|
// The acceleration is an average based on all neighbors, multiplied by a
|
||||||
// given `GSAIProximity`.
|
// strength decreasing by the inverse square law in relation to distance, and it
|
||||||
//
|
// accumulates.
|
||||||
// The acceleration is an average based on all neighbors, multiplied by a
|
// @category - Group behaviors
|
||||||
// strength decreasing by the inverse square law in relation to distance, and it
|
// The coefficient to calculate how fast the separation strength decays with distance.
|
||||||
// accumulates.
|
float decay_coefficient = 1.0;
|
||||||
// @category - Group behaviors
|
GSAITargetAcceleration *acceleration;
|
||||||
// The coefficient to calculate how fast the separation strength decays with distance.
|
// Callback for the proximity to call when finding neighbors. Determines the amount of
|
||||||
float decay_coefficient = 1.0;
|
// acceleration that `neighbor` imposes based on its distance from the owner agent.
|
||||||
GSAITargetAcceleration *acceleration;
|
// @tags - virtual
|
||||||
// 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,56 +1,44 @@
|
|||||||
|
|
||||||
#include "gsai_agent_location.h"
|
#include "gsai_agent_location.h"
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIAgentLocation::get_position() {
|
Vector3 GSAIAgentLocation::get_position() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAgentLocation::set_position(const Vector3 &val) {
|
void GSAIAgentLocation::set_position(const Vector3 &val) {
|
||||||
position = val;
|
position = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIAgentLocation::get_orientation() const {
|
float GSAIAgentLocation::get_orientation() const {
|
||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIAgentLocation::set_orientation(const float val) {
|
void GSAIAgentLocation::set_orientation(const float val) {
|
||||||
orientation = val;
|
orientation = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Represents an agent with only a location and an orientation.;
|
||||||
|
// @category - Base types;
|
||||||
// Represents an agent with only a location and an orientation.;
|
// The agent's position in space.;
|
||||||
// @category - Base types;
|
Vector3 position = Vector3.ZERO;
|
||||||
// The agent's position in space.;
|
// The agent's orientation on its Y axis rotation.;
|
||||||
Vector3 position = Vector3.ZERO;
|
float orientation = 0.0;
|
||||||
// The agent's orientation on its Y axis rotation.;
|
|
||||||
float orientation = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIAgentLocation::GSAIAgentLocation() {
|
GSAIAgentLocation::GSAIAgentLocation() {
|
||||||
position = Vector3.ZERO;
|
position = Vector3.ZERO;
|
||||||
orientation = 0.0;
|
orientation = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIAgentLocation::~GSAIAgentLocation() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIAgentLocation::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_position"), &GSAIAgentLocation::get_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_position", "value"), &GSAIAgentLocation::set_position);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "set_position", "get_position");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_orientation"), &GSAIAgentLocation::get_orientation);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_orientation", "value"), &GSAIAgentLocation::set_orientation);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "orientation"), "set_orientation", "get_orientation");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
GSAIAgentLocation::~GSAIAgentLocation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GSAIAgentLocation::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_position"), &GSAIAgentLocation::get_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_position", "value"), &GSAIAgentLocation::set_position);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "set_position", "get_position");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_orientation"), &GSAIAgentLocation::get_orientation);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_orientation", "value"), &GSAIAgentLocation::set_orientation);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "orientation"), "set_orientation", "get_orientation");
|
||||||
|
}
|
||||||
|
@ -1,32 +1,28 @@
|
|||||||
#ifndef GSAIAGENTLOCATION_H
|
#ifndef GSAIAGENTLOCATION_H
|
||||||
#define GSAIAGENTLOCATION_H
|
#define GSAIAGENTLOCATION_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIAgentLocation : public Reference {
|
class GSAIAgentLocation : public Reference {
|
||||||
GDCLASS(GSAIAgentLocation, Reference);
|
GDCLASS(GSAIAgentLocation, Reference);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Vector3 get_position();
|
||||||
|
void set_position(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get_position();
|
float get_orientation() const;
|
||||||
void set_position(const Vector3 &val);
|
void set_orientation(const float val);
|
||||||
|
|
||||||
float get_orientation() const;
|
GSAIAgentLocation();
|
||||||
void set_orientation(const float val);
|
~GSAIAgentLocation();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
GSAIAgentLocation();
|
// Represents an agent with only a location and an orientation.
|
||||||
~GSAIAgentLocation();
|
// @category - Base types
|
||||||
|
// The agent's position in space.
|
||||||
protected:
|
Vector3 position = Vector3.ZERO;
|
||||||
static void _bind_methods();
|
// The agent's orientation on its Y axis rotation.
|
||||||
|
float orientation = 0.0;
|
||||||
// Represents an agent with only a location and an orientation.
|
|
||||||
// @category - Base types
|
|
||||||
// The agent's position in space.
|
|
||||||
Vector3 position = Vector3.ZERO;
|
|
||||||
// The agent's orientation on its Y axis rotation.
|
|
||||||
float orientation = 0.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,70 +1,58 @@
|
|||||||
|
|
||||||
#include "gsai_group_behavior.h"
|
#include "gsai_group_behavior.h"
|
||||||
|
|
||||||
|
GSAIProximity GSAIGroupBehavior::get_ *proximity() {
|
||||||
GSAIProximity GSAIGroupBehavior::get_*proximity() {
|
return *proximity;
|
||||||
return *proximity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIGroupBehavior::set_*proximity(const GSAIProximity &val) {
|
void GSAIGroupBehavior::set_ *proximity(const GSAIProximity &val) {
|
||||||
*proximity = val;
|
*proximity = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<FuncRef> GSAIGroupBehavior::get__callback() {
|
Ref<FuncRef> GSAIGroupBehavior::get__callback() {
|
||||||
return _callback;
|
return _callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIGroupBehavior::set__callback(const Ref<FuncRef> &val) {
|
void GSAIGroupBehavior::set__callback(const Ref<FuncRef> &val) {
|
||||||
_callback = val;
|
_callback = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Base type for group-based steering behaviors.;
|
||||||
|
// @category - Base types;
|
||||||
|
// Container to find neighbors of the agent and calculate group behavior.;
|
||||||
|
GSAIProximity *proximity;
|
||||||
|
Ref<FuncRef> _callback = funcref(self, "_report_neighbor");
|
||||||
|
|
||||||
|
FuncRef GSAIGroupBehavior::get_callback() {
|
||||||
// Base type for group-based steering behaviors.;
|
return _callback;
|
||||||
// @category - Base types;
|
|
||||||
// Container to find neighbors of the agent and calculate group behavior.;
|
|
||||||
GSAIProximity *proximity;
|
|
||||||
Ref<FuncRef> _callback = funcref(self, "_report_neighbor");
|
|
||||||
|
|
||||||
FuncRef GSAIGroupBehavior::get_callback() {
|
|
||||||
return _callback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal callback for the behavior to define whether or not a member is;
|
// Internal callback for the behavior to define whether or not a member is;
|
||||||
// relevant;
|
// relevant;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
bool GSAIGroupBehavior::_report_neighbor(const GSAISteeringAgent &_neighbor) {
|
bool GSAIGroupBehavior::_report_neighbor(const GSAISteeringAgent &_neighbor) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIGroupBehavior::GSAIGroupBehavior() {
|
||||||
|
*proximity;
|
||||||
|
_callback = funcref(self, "_report_neighbor");
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIGroupBehavior::GSAIGroupBehavior() {
|
GSAIGroupBehavior::~GSAIGroupBehavior() {
|
||||||
*proximity;
|
}
|
||||||
_callback = funcref(self, "_report_neighbor");
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIGroupBehavior::~GSAIGroupBehavior() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIGroupBehavior::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*proximity"), &GSAIGroupBehavior::get_*proximity);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*proximity", "value"), &GSAIGroupBehavior::set_*proximity);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*proximity", PROPERTY_HINT_RESOURCE_TYPE, "GSAIProximity"), "set_*proximity", "get_*proximity");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__callback"), &GSAIGroupBehavior::get__callback);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__callback", "value"), &GSAIGroupBehavior::set__callback);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_callback", PROPERTY_HINT_RESOURCE_TYPE, "Ref<FuncRef>"), "set__callback", "get__callback");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_callback"), &GSAIGroupBehavior::get_callback);
|
|
||||||
ClassDB::bind_method(D_METHOD("_report_neighbor", "_neighbor"), &GSAIGroupBehavior::_report_neighbor);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void GSAIGroupBehavior::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*proximity"), &GSAIGroupBehavior::get_ * proximity);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*proximity", "value"), &GSAIGroupBehavior::set_ * proximity);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*proximity", PROPERTY_HINT_RESOURCE_TYPE, "GSAIProximity"), "set_*proximity", "get_*proximity");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__callback"), &GSAIGroupBehavior::get__callback);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__callback", "value"), &GSAIGroupBehavior::set__callback);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "_callback", PROPERTY_HINT_RESOURCE_TYPE, "Ref<FuncRef>"), "set__callback", "get__callback");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_callback"), &GSAIGroupBehavior::get_callback);
|
||||||
|
ClassDB::bind_method(D_METHOD("_report_neighbor", "_neighbor"), &GSAIGroupBehavior::_report_neighbor);
|
||||||
|
}
|
||||||
|
@ -1,36 +1,33 @@
|
|||||||
#ifndef GSAIGROUPBEHAVIOR_H
|
#ifndef GSAIGROUPBEHAVIOR_H
|
||||||
#define GSAIGROUPBEHAVIOR_H
|
#define GSAIGROUPBEHAVIOR_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIGroupBehavior : public GSAISteeringBehavior {
|
class GSAIGroupBehavior : public GSAISteeringBehavior {
|
||||||
GDCLASS(GSAIGroupBehavior, GSAISteeringBehavior);
|
GDCLASS(GSAIGroupBehavior, GSAISteeringBehavior);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAIProximity get_ *proximity();
|
||||||
|
void set_ *proximity(const GSAIProximity &val);
|
||||||
|
|
||||||
GSAIProximity get_*proximity();
|
Ref<FuncRef> get__callback();
|
||||||
void set_*proximity(const GSAIProximity &val);
|
void set__callback(const Ref<FuncRef> &val);
|
||||||
|
|
||||||
Ref<FuncRef> get__callback();
|
FuncRef get_callback();
|
||||||
void set__callback(const Ref<FuncRef> &val);
|
bool _report_neighbor(const GSAISteeringAgent &_neighbor);
|
||||||
|
|
||||||
FuncRef get_callback();
|
GSAIGroupBehavior();
|
||||||
bool _report_neighbor(const GSAISteeringAgent &_neighbor);
|
~GSAIGroupBehavior();
|
||||||
|
|
||||||
GSAIGroupBehavior();
|
protected:
|
||||||
~GSAIGroupBehavior();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Base type for group-based steering behaviors.
|
||||||
static void _bind_methods();
|
// @category - Base types
|
||||||
|
// Container to find neighbors of the agent and calculate group behavior.
|
||||||
// Base type for group-based steering behaviors.
|
GSAIProximity *proximity;
|
||||||
// @category - Base types
|
Ref<FuncRef> _callback = funcref(self, "_report_neighbor");
|
||||||
// Container to find neighbors of the agent and calculate group behavior.
|
// Internal callback for the behavior to define whether or not a member is
|
||||||
GSAIProximity *proximity;
|
// relevant
|
||||||
Ref<FuncRef> _callback = funcref(self, "_report_neighbor");
|
// @tags - virtual
|
||||||
// Internal callback for the behavior to define whether or not a member is
|
|
||||||
// relevant
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,344 +1,299 @@
|
|||||||
|
|
||||||
#include "gsai_path.h"
|
#include "gsai_path.h"
|
||||||
|
|
||||||
|
|
||||||
bool GSAIPath::get_is_open() const {
|
bool GSAIPath::get_is_open() const {
|
||||||
return is_open;
|
return is_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPath::set_is_open(const bool val) {
|
void GSAIPath::set_is_open(const bool val) {
|
||||||
is_open = val;
|
is_open = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAIPath::get_length() const {
|
float GSAIPath::get_length() const {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPath::set_length(const float val) {
|
void GSAIPath::set_length(const float val) {
|
||||||
length = val;
|
length = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Array GSAIPath::get__segments() {
|
Array GSAIPath::get__segments() {
|
||||||
return _segments;
|
return _segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPath::set__segments(const Array &val) {
|
void GSAIPath::set__segments(const Array &val) {
|
||||||
_segments = val;
|
_segments = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIPath::get__nearest_point_on_segment() {
|
Vector3 GSAIPath::get__nearest_point_on_segment() {
|
||||||
return _nearest_point_on_segment;
|
return _nearest_point_on_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPath::set__nearest_point_on_segment(const Vector3 &val) {
|
void GSAIPath::set__nearest_point_on_segment(const Vector3 &val) {
|
||||||
_nearest_point_on_segment = val;
|
_nearest_point_on_segment = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAIPath::get__nearest_point_on_path() {
|
Vector3 GSAIPath::get__nearest_point_on_path() {
|
||||||
return _nearest_point_on_path;
|
return _nearest_point_on_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIPath::set__nearest_point_on_path(const Vector3 &val) {
|
void GSAIPath::set__nearest_point_on_path(const Vector3 &val) {
|
||||||
_nearest_point_on_path = val;
|
_nearest_point_on_path = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Represents a path made up of Vector3 waypoints, split into segments path;
|
||||||
|
// follow behaviors can use.;
|
||||||
|
// @category - Base types;
|
||||||
|
// If `false`, the path loops.;
|
||||||
|
bool is_open = ;
|
||||||
|
// Total length of the path.;
|
||||||
|
float length = ;
|
||||||
|
Array _segments = ;
|
||||||
|
Vector3 _nearest_point_on_segment = ;
|
||||||
|
Vector3 _nearest_point_on_path = ;
|
||||||
|
|
||||||
|
void GSAIPath::initialize(const Array &waypoints, const bool _is_open) {
|
||||||
// Represents a path made up of Vector3 waypoints, split into segments path;
|
self.is_open = _is_open;
|
||||||
// follow behaviors can use.;
|
create_path(waypoints);
|
||||||
// @category - Base types;
|
_nearest_point_on_segment = waypoints[0];
|
||||||
// If `false`, the path loops.;
|
_nearest_point_on_path = waypoints[0];
|
||||||
bool is_open = ;
|
|
||||||
// Total length of the path.;
|
|
||||||
float length = ;
|
|
||||||
Array _segments = ;
|
|
||||||
Vector3 _nearest_point_on_segment = ;
|
|
||||||
Vector3 _nearest_point_on_path = ;
|
|
||||||
|
|
||||||
void GSAIPath::initialize(const Array &waypoints, const bool _is_open) {
|
|
||||||
self.is_open = _is_open;
|
|
||||||
create_path(waypoints);
|
|
||||||
_nearest_point_on_segment = waypoints[0];
|
|
||||||
_nearest_point_on_path = waypoints[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a path from a list of waypoints.;
|
// Creates a path from a list of waypoints.;
|
||||||
|
|
||||||
void GSAIPath::create_path(const Array &waypoints) {
|
void GSAIPath::create_path(const Array &waypoints) {
|
||||||
|
if (not waypoints || waypoints.size() < 2) {
|
||||||
|
printerr("Waypoints cannot be null and must contain at least two (2) waypoints.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (not waypoints || waypoints.size() < 2) {
|
_segments = [];
|
||||||
printerr("Waypoints cannot be null and must contain at least two (2) waypoints.");
|
length = 0;
|
||||||
return;
|
Vector3 current = waypoints.front();
|
||||||
|
Vector3 previous = ;
|
||||||
|
|
||||||
|
for (int i = 1; i > waypoints.size(); i += 1) { //i in range(1, waypoints.size(), 1)
|
||||||
|
previous = current;
|
||||||
|
|
||||||
|
if (i < waypoints.size()) {
|
||||||
|
current = waypoints[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (is_open) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
current = waypoints[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
GSAISegment *segment = GSAISegment.new(previous, current);
|
||||||
|
length += segment.length;
|
||||||
|
segment.cumulative_length = length;
|
||||||
|
_segments.append(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the distance from `agent_current_position` to the next waypoint.;
|
||||||
}
|
}
|
||||||
|
|
||||||
_segments = [];
|
float GSAIPath::calculate_distance(const Vector3 &agent_current_position) {
|
||||||
length = 0;
|
if (_segments.size() == 0) {
|
||||||
Vector3 current = waypoints.front();
|
return 0.0;
|
||||||
Vector3 previous = ;
|
}
|
||||||
|
|
||||||
for (int i = 1; i > waypoints.size(); i += 1) { //i in range(1, waypoints.size(), 1)
|
float smallest_distance_squared = INF;
|
||||||
previous = current;
|
GSAISegment *nearest_segment = null;
|
||||||
|
|
||||||
if (i < waypoints.size()) {
|
for (int i = 0; i < _segments.size(); ++i) { //i in range(_segments.size())
|
||||||
current = waypoints[i];
|
GSAISegment *segment = _segments[i];
|
||||||
|
float distance_squared = _calculate_point_segment_distance_squared(segment.begin, segment.end, agent_current_position);
|
||||||
|
|
||||||
|
if (distance_squared < smallest_distance_squared) {
|
||||||
|
_nearest_point_on_path = _nearest_point_on_segment;
|
||||||
|
smallest_distance_squared = distance_squared;
|
||||||
|
nearest_segment = segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float length_on_path = nearest_segment.cumulative_length - _nearest_point_on_path.distance_to(nearest_segment.end);
|
||||||
|
return length_on_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculates a target position from the path's starting point based on the `target_distance`.;
|
||||||
|
|
||||||
else if (is_open) {
|
Vector3 GSAIPath::calculate_target_position(const float target_distance) {
|
||||||
break;
|
if (is_open) {
|
||||||
|
target_distance = clamp(target_distance, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (target_distance < 0) {
|
||||||
|
target_distance = length + fmod(target_distance, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (target_distance > length) {
|
||||||
|
target_distance = fmod(target_distance, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GSAISegment *desired_segment;
|
||||||
|
|
||||||
|
for (int i = 0; i < _segments.size(); ++i) { //i in range(_segments.size())
|
||||||
|
GSAISegment *segment = _segments[i];
|
||||||
|
|
||||||
|
if (segment.cumulative_length >= target_distance) {
|
||||||
|
desired_segment = segment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not desired_segment) {
|
||||||
|
desired_segment = _segments.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant distance = desired_segment.cumulative_length - target_distance;
|
||||||
|
return (((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length)) + desired_segment.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the position of the first point on the path.;
|
||||||
|
|
||||||
else {
|
Vector3 GSAIPath::get_start_point() {
|
||||||
current = waypoints[0];
|
return _segments.front().begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISegment *segment = GSAISegment.new(previous, current);
|
// Returns the position of the last point on the path.;
|
||||||
length += segment.length;
|
|
||||||
segment.cumulative_length = length;
|
Vector3 GSAIPath::get_end_point() {
|
||||||
_segments.append(segment);
|
return _segments.back().end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the distance from `agent_current_position` to the next waypoint.;
|
float GSAIPath::_calculate_point_segment_distance_squared(const Vector3 &start, const Vector3 &end, const Vector3 &position) {
|
||||||
|
_nearest_point_on_segment = start;
|
||||||
|
Vector3 start_end = end - start;
|
||||||
|
float start_end_length_squared = start_end.length_squared();
|
||||||
|
|
||||||
|
if (start_end_length_squared != 0) {
|
||||||
|
Variant = (position - start).dot(start_end) / start_end_length_squared;
|
||||||
|
_nearest_point_on_segment += start_end * clamp(t, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _nearest_point_on_segment.distance_squared_to(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not exposed helper struct;
|
||||||
|
|
||||||
float GSAIPath::calculate_distance(const Vector3 &agent_current_position) {
|
Vector3 GSAISegment::get_begin() {
|
||||||
|
return begin;
|
||||||
if (_segments.size() == 0) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float smallest_distance_squared = INF;
|
void GSAISegment::set_begin(const Vector3 &val) {
|
||||||
GSAISegment *nearest_segment = null;
|
begin = val;
|
||||||
|
|
||||||
for (int i = 0; i < _segments.size(); ++i) { //i in range(_segments.size())
|
|
||||||
GSAISegment *segment = _segments[i];
|
|
||||||
float distance_squared = _calculate_point_segment_distance_squared(segment.begin, segment.end, agent_current_position);
|
|
||||||
|
|
||||||
if (distance_squared < smallest_distance_squared) {
|
|
||||||
_nearest_point_on_path = _nearest_point_on_segment;
|
|
||||||
smallest_distance_squared = distance_squared;
|
|
||||||
nearest_segment = segment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector3 GSAISegment::get_end() {
|
||||||
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
float length_on_path = nearest_segment.cumulative_length - _nearest_point_on_path.distance_to(nearest_segment.end);
|
void GSAISegment::set_end(const Vector3 &val) {
|
||||||
return length_on_path;
|
end = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates a target position from the path's starting point based on the `target_distance`.;
|
float GSAISegment::get_length() const {
|
||||||
|
return length;
|
||||||
Vector3 GSAIPath::calculate_target_position(const float target_distance) {
|
|
||||||
|
|
||||||
if (is_open) {
|
|
||||||
target_distance = clamp(target_distance, 0, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAISegment::set_length(const float val) {
|
||||||
else {
|
length = val;
|
||||||
|
|
||||||
if (target_distance < 0) {
|
|
||||||
target_distance = length + fmod(target_distance, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GSAISegment::get_cumulative_length() const {
|
||||||
else if (target_distance > length) {
|
return cumulative_length;
|
||||||
target_distance = fmod(target_distance, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAISegment::set_cumulative_length(const float val) {
|
||||||
|
cumulative_length = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISegment *desired_segment;
|
Vector3 begin = ;
|
||||||
|
Vector3 end = ;
|
||||||
|
float length = ;
|
||||||
|
float cumulative_length = ;
|
||||||
|
|
||||||
for (int i = 0; i < _segments.size(); ++i) { //i in range(_segments.size())
|
void GSAISegment::_init(const Vector3 &_begin, const Vector3 &_end) {
|
||||||
GSAISegment *segment = _segments[i];
|
self.begin = _begin;
|
||||||
|
self.end = _end;
|
||||||
if (segment.cumulative_length >= target_distance) {
|
length = _begin.distance_to(_end);
|
||||||
desired_segment = segment;
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISegment::GSAISegment() {
|
||||||
|
begin = ;
|
||||||
|
end = ;
|
||||||
|
length = ;
|
||||||
|
cumulative_length = ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISegment::~GSAISegment() {
|
||||||
if (not desired_segment) {
|
|
||||||
desired_segment = _segments.back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant distance = desired_segment.cumulative_length - target_distance;
|
static void GSAISegment::_bind_methods() {
|
||||||
return (((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length)) + desired_segment.end);
|
ClassDB::bind_method(D_METHOD("get_begin"), &GSAISegment::get_begin);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_begin", "value"), &GSAISegment::set_begin);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "begin"), "set_begin", "get_begin");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_end"), &GSAISegment::get_end);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_end", "value"), &GSAISegment::set_end);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end"), "set_end", "get_end");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_length"), &GSAISegment::get_length);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_length", "value"), &GSAISegment::set_length);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_cumulative_length"), &GSAISegment::get_cumulative_length);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_cumulative_length", "value"), &GSAISegment::set_cumulative_length);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cumulative_length"), "set_cumulative_length", "get_cumulative_length");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_init", "_begin", "_end"), &GSAISegment::_init);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the position of the first point on the path.;
|
GSAIPath::GSAIPath() {
|
||||||
|
is_open = ;
|
||||||
Vector3 GSAIPath::get_start_point() {
|
length = ;
|
||||||
return _segments.front().begin;
|
_segments = ;
|
||||||
|
_nearest_point_on_segment = ;
|
||||||
|
_nearest_point_on_path = ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the position of the last point on the path.;
|
GSAIPath::~GSAIPath() {
|
||||||
|
|
||||||
Vector3 GSAIPath::get_end_point() {
|
|
||||||
return _segments.back().end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIPath::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_is_open"), &GSAIPath::get_is_open);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_is_open", "value"), &GSAIPath::set_is_open);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_open"), "set_is_open", "get_is_open");
|
||||||
|
|
||||||
float GSAIPath::_calculate_point_segment_distance_squared(const Vector3 &start, const Vector3 &end, const Vector3 &position) {
|
ClassDB::bind_method(D_METHOD("get_length"), &GSAIPath::get_length);
|
||||||
_nearest_point_on_segment = start;
|
ClassDB::bind_method(D_METHOD("set_length", "value"), &GSAIPath::set_length);
|
||||||
Vector3 start_end = end - start;
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length");
|
||||||
float start_end_length_squared = start_end.length_squared();
|
|
||||||
|
|
||||||
if (start_end_length_squared != 0) {
|
ClassDB::bind_method(D_METHOD("get__segments"), &GSAIPath::get__segments);
|
||||||
Variant = (position - start).dot(start_end) / start_end_length_squared;
|
ClassDB::bind_method(D_METHOD("set__segments", "value"), &GSAIPath::set__segments);
|
||||||
_nearest_point_on_segment += start_end * clamp(t, 0, 1);
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_segments"), "set__segments", "get__segments");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__nearest_point_on_segment"), &GSAIPath::get__nearest_point_on_segment);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__nearest_point_on_segment", "value"), &GSAIPath::set__nearest_point_on_segment);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_nearest_point_on_segment"), "set__nearest_point_on_segment", "get__nearest_point_on_segment");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__nearest_point_on_path"), &GSAIPath::get__nearest_point_on_path);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__nearest_point_on_path", "value"), &GSAIPath::set__nearest_point_on_path);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_nearest_point_on_path"), "set__nearest_point_on_path", "get__nearest_point_on_path");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("initialize", "waypoints", "_is_open"), &GSAIPath::initialize, false);
|
||||||
|
ClassDB::bind_method(D_METHOD("create_path", "waypoints"), &GSAIPath::create_path);
|
||||||
|
ClassDB::bind_method(D_METHOD("calculate_distance", "agent_current_position"), &GSAIPath::calculate_distance);
|
||||||
|
ClassDB::bind_method(D_METHOD("calculate_target_position", "target_distance"), &GSAIPath::calculate_target_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_start_point"), &GSAIPath::get_start_point);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_end_point"), &GSAIPath::get_end_point);
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_point_segment_distance_squared", "start", "end", "position"), &GSAIPath::_calculate_point_segment_distance_squared);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _nearest_point_on_segment.distance_squared_to(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not exposed helper struct;
|
|
||||||
|
|
||||||
Vector3 GSAISegment::get_begin() {
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSAISegment::set_begin(const Vector3 &val) {
|
|
||||||
begin = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAISegment::get_end() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSAISegment::set_end(const Vector3 &val) {
|
|
||||||
end = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float GSAISegment::get_length() const {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSAISegment::set_length(const float val) {
|
|
||||||
length = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float GSAISegment::get_cumulative_length() const {
|
|
||||||
return cumulative_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSAISegment::set_cumulative_length(const float val) {
|
|
||||||
cumulative_length = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vector3 begin = ;
|
|
||||||
Vector3 end = ;
|
|
||||||
float length = ;
|
|
||||||
float cumulative_length = ;
|
|
||||||
|
|
||||||
void GSAISegment::_init(const Vector3 &_begin, const Vector3 &_end) {
|
|
||||||
self.begin = _begin;
|
|
||||||
self.end = _end;
|
|
||||||
length = _begin.distance_to(_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAISegment::GSAISegment() {
|
|
||||||
begin = ;
|
|
||||||
end = ;
|
|
||||||
length = ;
|
|
||||||
cumulative_length = ;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAISegment::~GSAISegment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAISegment::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_begin"), &GSAISegment::get_begin);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_begin", "value"), &GSAISegment::set_begin);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "begin"), "set_begin", "get_begin");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_end"), &GSAISegment::get_end);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_end", "value"), &GSAISegment::set_end);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end"), "set_end", "get_end");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_length"), &GSAISegment::get_length);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_length", "value"), &GSAISegment::set_length);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_cumulative_length"), &GSAISegment::get_cumulative_length);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_cumulative_length", "value"), &GSAISegment::set_cumulative_length);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cumulative_length"), "set_cumulative_length", "get_cumulative_length");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_init", "_begin", "_end"), &GSAISegment::_init);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIPath::GSAIPath() {
|
|
||||||
is_open = ;
|
|
||||||
length = ;
|
|
||||||
_segments = ;
|
|
||||||
_nearest_point_on_segment = ;
|
|
||||||
_nearest_point_on_path = ;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIPath::~GSAIPath() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIPath::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_is_open"), &GSAIPath::get_is_open);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_is_open", "value"), &GSAIPath::set_is_open);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_open"), "set_is_open", "get_is_open");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_length"), &GSAIPath::get_length);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_length", "value"), &GSAIPath::set_length);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__segments"), &GSAIPath::get__segments);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__segments", "value"), &GSAIPath::set__segments);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_segments"), "set__segments", "get__segments");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__nearest_point_on_segment"), &GSAIPath::get__nearest_point_on_segment);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__nearest_point_on_segment", "value"), &GSAIPath::set__nearest_point_on_segment);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_nearest_point_on_segment"), "set__nearest_point_on_segment", "get__nearest_point_on_segment");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__nearest_point_on_path"), &GSAIPath::get__nearest_point_on_path);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__nearest_point_on_path", "value"), &GSAIPath::set__nearest_point_on_path);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "_nearest_point_on_path"), "set__nearest_point_on_path", "get__nearest_point_on_path");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("initialize", "waypoints", "_is_open"), &GSAIPath::initialize, false);
|
|
||||||
ClassDB::bind_method(D_METHOD("create_path", "waypoints"), &GSAIPath::create_path);
|
|
||||||
ClassDB::bind_method(D_METHOD("calculate_distance", "agent_current_position"), &GSAIPath::calculate_distance);
|
|
||||||
ClassDB::bind_method(D_METHOD("calculate_target_position", "target_distance"), &GSAIPath::calculate_target_position);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_start_point"), &GSAIPath::get_start_point);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_end_point"), &GSAIPath::get_end_point);
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_point_segment_distance_squared", "start", "end", "position"), &GSAIPath::_calculate_point_segment_distance_squared);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,86 +1,81 @@
|
|||||||
#ifndef GSAIPATH_H
|
#ifndef GSAIPATH_H
|
||||||
#define GSAIPATH_H
|
#define GSAIPATH_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIPath : public Reference {
|
class GSAIPath : public Reference {
|
||||||
GDCLASS(GSAIPath, Reference);
|
GDCLASS(GSAIPath, Reference);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool get_is_open() const;
|
||||||
|
void set_is_open(const bool val);
|
||||||
|
|
||||||
bool get_is_open() const;
|
float get_length() const;
|
||||||
void set_is_open(const bool val);
|
void set_length(const float val);
|
||||||
|
|
||||||
float get_length() const;
|
Array get__segments();
|
||||||
void set_length(const float val);
|
void set__segments(const Array &val);
|
||||||
|
|
||||||
Array get__segments();
|
Vector3 get__nearest_point_on_segment();
|
||||||
void set__segments(const Array &val);
|
void set__nearest_point_on_segment(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__nearest_point_on_segment();
|
Vector3 get__nearest_point_on_path();
|
||||||
void set__nearest_point_on_segment(const Vector3 &val);
|
void set__nearest_point_on_path(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get__nearest_point_on_path();
|
void initialize(const Array &waypoints, const bool _is_open = false);
|
||||||
void set__nearest_point_on_path(const Vector3 &val);
|
void create_path(const Array &waypoints);
|
||||||
|
float calculate_distance(const Vector3 &agent_current_position);
|
||||||
|
Vector3 calculate_target_position(const float target_distance);
|
||||||
|
Vector3 get_start_point();
|
||||||
|
Vector3 get_end_point();
|
||||||
|
float _calculate_point_segment_distance_squared(const Vector3 &start, const Vector3 &end, const Vector3 &position);
|
||||||
|
class GSAISegment {
|
||||||
|
public:
|
||||||
|
Vector3 get_begin();
|
||||||
|
void set_begin(const Vector3 &val);
|
||||||
|
|
||||||
void initialize(const Array &waypoints, const bool _is_open = false);
|
Vector3 get_end();
|
||||||
void create_path(const Array &waypoints);
|
void set_end(const Vector3 &val);
|
||||||
float calculate_distance(const Vector3 &agent_current_position);
|
|
||||||
Vector3 calculate_target_position(const float target_distance);
|
|
||||||
Vector3 get_start_point();
|
|
||||||
Vector3 get_end_point();
|
|
||||||
float _calculate_point_segment_distance_squared(const Vector3 &start, const Vector3 &end, const Vector3 &position);
|
|
||||||
class GSAISegment {
|
|
||||||
public:
|
|
||||||
|
|
||||||
Vector3 get_begin();
|
float get_length() const;
|
||||||
void set_begin(const Vector3 &val);
|
void set_length(const float val);
|
||||||
|
|
||||||
Vector3 get_end();
|
float get_cumulative_length() const;
|
||||||
void set_end(const Vector3 &val);
|
void set_cumulative_length(const float val);
|
||||||
|
|
||||||
float get_length() const;
|
void _init(const Vector3 &_begin, const Vector3 &_end);
|
||||||
void set_length(const float val);
|
|
||||||
|
|
||||||
float get_cumulative_length() const;
|
GSAISegment();
|
||||||
void set_cumulative_length(const float val);
|
~GSAISegment();
|
||||||
|
|
||||||
void _init(const Vector3 &_begin, const Vector3 &_end);
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
GSAISegment();
|
Vector3 begin = ;
|
||||||
~GSAISegment();
|
Vector3 end = ;
|
||||||
|
float length = ;
|
||||||
|
float cumulative_length = ;
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
GSAIPath();
|
||||||
static void _bind_methods();
|
~GSAIPath();
|
||||||
|
|
||||||
Vector3 begin = ;
|
protected:
|
||||||
Vector3 end = ;
|
static void _bind_methods();
|
||||||
float length = ;
|
|
||||||
float cumulative_length = ;
|
// Represents a path made up of Vector3 waypoints, split into segments path
|
||||||
|
// follow behaviors can use.
|
||||||
|
// @category - Base types
|
||||||
|
// If `false`, the path loops.
|
||||||
|
bool is_open = ;
|
||||||
|
// Total length of the path.
|
||||||
|
float length = ;
|
||||||
|
Array _segments = ;
|
||||||
|
Vector3 _nearest_point_on_segment = ;
|
||||||
|
Vector3 _nearest_point_on_path = ;
|
||||||
|
// Creates a path from a list of waypoints.
|
||||||
|
// Calculates a target position from the path's starting point based on the `target_distance`.
|
||||||
|
// Returns the position of the first point on the path.
|
||||||
|
// Returns the position of the last point on the path.
|
||||||
|
// not exposed helper struct
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GSAIPath();
|
|
||||||
~GSAIPath();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
// Represents a path made up of Vector3 waypoints, split into segments path
|
|
||||||
// follow behaviors can use.
|
|
||||||
// @category - Base types
|
|
||||||
// If `false`, the path loops.
|
|
||||||
bool is_open = ;
|
|
||||||
// Total length of the path.
|
|
||||||
float length = ;
|
|
||||||
Array _segments = ;
|
|
||||||
Vector3 _nearest_point_on_segment = ;
|
|
||||||
Vector3 _nearest_point_on_path = ;
|
|
||||||
// Creates a path from a list of waypoints.
|
|
||||||
// Calculates a target position from the path's starting point based on the `target_distance`.
|
|
||||||
// Returns the position of the first point on the path.
|
|
||||||
// Returns the position of the last point on the path.
|
|
||||||
// not exposed helper struct
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,180 +1,154 @@
|
|||||||
|
|
||||||
#include "gsai_steering_agent.h"
|
#include "gsai_steering_agent.h"
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_zero_linear_speed_threshold() const {
|
float GSAISteeringAgent::get_zero_linear_speed_threshold() const {
|
||||||
return zero_linear_speed_threshold;
|
return zero_linear_speed_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_zero_linear_speed_threshold(const float val) {
|
void GSAISteeringAgent::set_zero_linear_speed_threshold(const float val) {
|
||||||
zero_linear_speed_threshold = val;
|
zero_linear_speed_threshold = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_linear_speed_max() const {
|
float GSAISteeringAgent::get_linear_speed_max() const {
|
||||||
return linear_speed_max;
|
return linear_speed_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_linear_speed_max(const float val) {
|
void GSAISteeringAgent::set_linear_speed_max(const float val) {
|
||||||
linear_speed_max = val;
|
linear_speed_max = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_linear_acceleration_max() const {
|
float GSAISteeringAgent::get_linear_acceleration_max() const {
|
||||||
return linear_acceleration_max;
|
return linear_acceleration_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_linear_acceleration_max(const float val) {
|
void GSAISteeringAgent::set_linear_acceleration_max(const float val) {
|
||||||
linear_acceleration_max = val;
|
linear_acceleration_max = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_angular_speed_max() const {
|
float GSAISteeringAgent::get_angular_speed_max() const {
|
||||||
return angular_speed_max;
|
return angular_speed_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_angular_speed_max(const float val) {
|
void GSAISteeringAgent::set_angular_speed_max(const float val) {
|
||||||
angular_speed_max = val;
|
angular_speed_max = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_angular_acceleration_max() const {
|
float GSAISteeringAgent::get_angular_acceleration_max() const {
|
||||||
return angular_acceleration_max;
|
return angular_acceleration_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_angular_acceleration_max(const float val) {
|
void GSAISteeringAgent::set_angular_acceleration_max(const float val) {
|
||||||
angular_acceleration_max = val;
|
angular_acceleration_max = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAISteeringAgent::get_linear_velocity() {
|
Vector3 GSAISteeringAgent::get_linear_velocity() {
|
||||||
return linear_velocity;
|
return linear_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_linear_velocity(const Vector3 &val) {
|
void GSAISteeringAgent::set_linear_velocity(const Vector3 &val) {
|
||||||
linear_velocity = val;
|
linear_velocity = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_angular_velocity() const {
|
float GSAISteeringAgent::get_angular_velocity() const {
|
||||||
return angular_velocity;
|
return angular_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_angular_velocity(const float val) {
|
void GSAISteeringAgent::set_angular_velocity(const float val) {
|
||||||
angular_velocity = val;
|
angular_velocity = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAISteeringAgent::get_bounding_radius() const {
|
float GSAISteeringAgent::get_bounding_radius() const {
|
||||||
return bounding_radius;
|
return bounding_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_bounding_radius(const float val) {
|
void GSAISteeringAgent::set_bounding_radius(const float val) {
|
||||||
bounding_radius = val;
|
bounding_radius = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GSAISteeringAgent::get_is_tagged() const {
|
bool GSAISteeringAgent::get_is_tagged() const {
|
||||||
return is_tagged;
|
return is_tagged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringAgent::set_is_tagged(const bool val) {
|
void GSAISteeringAgent::set_is_tagged(const bool val) {
|
||||||
is_tagged = val;
|
is_tagged = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds velocity, speed, and size data to `GSAIAgentLocation`.;
|
||||||
|
//;
|
||||||
// Adds velocity, speed, and size data to `GSAIAgentLocation`.;
|
// It is the character's responsibility to keep this information up to date for;
|
||||||
//;
|
// the steering toolkit to work correctly.;
|
||||||
// It is the character's responsibility to keep this information up to date for;
|
// @category - Base types;
|
||||||
// the steering toolkit to work correctly.;
|
// The amount of velocity to be considered effectively not moving.;
|
||||||
// @category - Base types;
|
float zero_linear_speed_threshold = 0.01;
|
||||||
// The amount of velocity to be considered effectively not moving.;
|
// The maximum speed at which the agent can move.;
|
||||||
float zero_linear_speed_threshold = 0.01;
|
float linear_speed_max = 0.0;
|
||||||
// The maximum speed at which the agent can move.;
|
// The maximum amount of acceleration that any behavior can apply to the agent.;
|
||||||
float linear_speed_max = 0.0;
|
float linear_acceleration_max = 0.0;
|
||||||
// The maximum amount of acceleration that any behavior can apply to the agent.;
|
// The maximum amount of angular speed at which the agent can rotate.;
|
||||||
float linear_acceleration_max = 0.0;
|
float angular_speed_max = 0.0;
|
||||||
// The maximum amount of angular speed at which the agent can rotate.;
|
// The maximum amount of angular acceleration that any behavior can apply to an;
|
||||||
float angular_speed_max = 0.0;
|
// agent.;
|
||||||
// The maximum amount of angular acceleration that any behavior can apply to an;
|
float angular_acceleration_max = 0.0;
|
||||||
// agent.;
|
// Current velocity of the agent.;
|
||||||
float angular_acceleration_max = 0.0;
|
Vector3 linear_velocity = Vector3.ZERO;
|
||||||
// Current velocity of the agent.;
|
// Current angular velocity of the agent.;
|
||||||
Vector3 linear_velocity = Vector3.ZERO;
|
float angular_velocity = 0.0;
|
||||||
// Current angular velocity of the agent.;
|
// The radius of the sphere that approximates the agent's size in space.;
|
||||||
float angular_velocity = 0.0;
|
float bounding_radius = 0.0;
|
||||||
// The radius of the sphere that approximates the agent's size in space.;
|
// Used internally by group behaviors and proximities to mark the agent as already;
|
||||||
float bounding_radius = 0.0;
|
// considered.;
|
||||||
// Used internally by group behaviors and proximities to mark the agent as already;
|
bool is_tagged = false;
|
||||||
// considered.;
|
|
||||||
bool is_tagged = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISteeringAgent::GSAISteeringAgent() {
|
GSAISteeringAgent::GSAISteeringAgent() {
|
||||||
zero_linear_speed_threshold = 0.01;
|
zero_linear_speed_threshold = 0.01;
|
||||||
linear_speed_max = 0.0;
|
linear_speed_max = 0.0;
|
||||||
linear_acceleration_max = 0.0;
|
linear_acceleration_max = 0.0;
|
||||||
angular_speed_max = 0.0;
|
angular_speed_max = 0.0;
|
||||||
angular_acceleration_max = 0.0;
|
angular_acceleration_max = 0.0;
|
||||||
linear_velocity = Vector3.ZERO;
|
linear_velocity = Vector3.ZERO;
|
||||||
angular_velocity = 0.0;
|
angular_velocity = 0.0;
|
||||||
bounding_radius = 0.0;
|
bounding_radius = 0.0;
|
||||||
is_tagged = false;
|
is_tagged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISteeringAgent::~GSAISteeringAgent() {
|
GSAISteeringAgent::~GSAISteeringAgent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAISteeringAgent::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_zero_linear_speed_threshold"), &GSAISteeringAgent::get_zero_linear_speed_threshold);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_zero_linear_speed_threshold", "value"), &GSAISteeringAgent::set_zero_linear_speed_threshold);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "zero_linear_speed_threshold"), "set_zero_linear_speed_threshold", "get_zero_linear_speed_threshold");
|
||||||
|
|
||||||
static void GSAISteeringAgent::_bind_methods() {
|
ClassDB::bind_method(D_METHOD("get_linear_speed_max"), &GSAISteeringAgent::get_linear_speed_max);
|
||||||
ClassDB::bind_method(D_METHOD("get_zero_linear_speed_threshold"), &GSAISteeringAgent::get_zero_linear_speed_threshold);
|
ClassDB::bind_method(D_METHOD("set_linear_speed_max", "value"), &GSAISteeringAgent::set_linear_speed_max);
|
||||||
ClassDB::bind_method(D_METHOD("set_zero_linear_speed_threshold", "value"), &GSAISteeringAgent::set_zero_linear_speed_threshold);
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_speed_max"), "set_linear_speed_max", "get_linear_speed_max");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "zero_linear_speed_threshold"), "set_zero_linear_speed_threshold", "get_zero_linear_speed_threshold");
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_linear_acceleration_max"), &GSAISteeringAgent::get_linear_acceleration_max);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_linear_acceleration_max", "value"), &GSAISteeringAgent::set_linear_acceleration_max);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_acceleration_max"), "set_linear_acceleration_max", "get_linear_acceleration_max");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_linear_speed_max"), &GSAISteeringAgent::get_linear_speed_max);
|
ClassDB::bind_method(D_METHOD("get_angular_speed_max"), &GSAISteeringAgent::get_angular_speed_max);
|
||||||
ClassDB::bind_method(D_METHOD("set_linear_speed_max", "value"), &GSAISteeringAgent::set_linear_speed_max);
|
ClassDB::bind_method(D_METHOD("set_angular_speed_max", "value"), &GSAISteeringAgent::set_angular_speed_max);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_speed_max"), "set_linear_speed_max", "get_linear_speed_max");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_speed_max"), "set_angular_speed_max", "get_angular_speed_max");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_angular_acceleration_max"), &GSAISteeringAgent::get_angular_acceleration_max);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_angular_acceleration_max", "value"), &GSAISteeringAgent::set_angular_acceleration_max);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_acceleration_max"), "set_angular_acceleration_max", "get_angular_acceleration_max");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_linear_acceleration_max"), &GSAISteeringAgent::get_linear_acceleration_max);
|
ClassDB::bind_method(D_METHOD("get_linear_velocity"), &GSAISteeringAgent::get_linear_velocity);
|
||||||
ClassDB::bind_method(D_METHOD("set_linear_acceleration_max", "value"), &GSAISteeringAgent::set_linear_acceleration_max);
|
ClassDB::bind_method(D_METHOD("set_linear_velocity", "value"), &GSAISteeringAgent::set_linear_velocity);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_acceleration_max"), "set_linear_acceleration_max", "get_linear_acceleration_max");
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_angular_speed_max"), &GSAISteeringAgent::get_angular_speed_max);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_angular_speed_max", "value"), &GSAISteeringAgent::set_angular_speed_max);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_speed_max"), "set_angular_speed_max", "get_angular_speed_max");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_angular_acceleration_max"), &GSAISteeringAgent::get_angular_acceleration_max);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_angular_acceleration_max", "value"), &GSAISteeringAgent::set_angular_acceleration_max);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_acceleration_max"), "set_angular_acceleration_max", "get_angular_acceleration_max");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_linear_velocity"), &GSAISteeringAgent::get_linear_velocity);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_linear_velocity", "value"), &GSAISteeringAgent::set_linear_velocity);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_angular_velocity"), &GSAISteeringAgent::get_angular_velocity);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_angular_velocity", "value"), &GSAISteeringAgent::set_angular_velocity);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_bounding_radius"), &GSAISteeringAgent::get_bounding_radius);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_bounding_radius", "value"), &GSAISteeringAgent::set_bounding_radius);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounding_radius"), "set_bounding_radius", "get_bounding_radius");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_is_tagged"), &GSAISteeringAgent::get_is_tagged);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_is_tagged", "value"), &GSAISteeringAgent::set_is_tagged);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_tagged"), "set_is_tagged", "get_is_tagged");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_angular_velocity"), &GSAISteeringAgent::get_angular_velocity);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_angular_velocity", "value"), &GSAISteeringAgent::set_angular_velocity);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_bounding_radius"), &GSAISteeringAgent::get_bounding_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bounding_radius", "value"), &GSAISteeringAgent::set_bounding_radius);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounding_radius"), "set_bounding_radius", "get_bounding_radius");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_is_tagged"), &GSAISteeringAgent::get_is_tagged);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_is_tagged", "value"), &GSAISteeringAgent::set_is_tagged);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_tagged"), "set_is_tagged", "get_is_tagged");
|
||||||
|
}
|
||||||
|
@ -1,72 +1,68 @@
|
|||||||
#ifndef GSAISTEERINGAGENT_H
|
#ifndef GSAISTEERINGAGENT_H
|
||||||
#define GSAISTEERINGAGENT_H
|
#define GSAISTEERINGAGENT_H
|
||||||
|
|
||||||
|
|
||||||
class GSAISteeringAgent : public GSAIAgentLocation {
|
class GSAISteeringAgent : public GSAIAgentLocation {
|
||||||
GDCLASS(GSAISteeringAgent, GSAIAgentLocation);
|
GDCLASS(GSAISteeringAgent, GSAIAgentLocation);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float get_zero_linear_speed_threshold() const;
|
||||||
|
void set_zero_linear_speed_threshold(const float val);
|
||||||
|
|
||||||
float get_zero_linear_speed_threshold() const;
|
float get_linear_speed_max() const;
|
||||||
void set_zero_linear_speed_threshold(const float val);
|
void set_linear_speed_max(const float val);
|
||||||
|
|
||||||
float get_linear_speed_max() const;
|
float get_linear_acceleration_max() const;
|
||||||
void set_linear_speed_max(const float val);
|
void set_linear_acceleration_max(const float val);
|
||||||
|
|
||||||
float get_linear_acceleration_max() const;
|
float get_angular_speed_max() const;
|
||||||
void set_linear_acceleration_max(const float val);
|
void set_angular_speed_max(const float val);
|
||||||
|
|
||||||
float get_angular_speed_max() const;
|
float get_angular_acceleration_max() const;
|
||||||
void set_angular_speed_max(const float val);
|
void set_angular_acceleration_max(const float val);
|
||||||
|
|
||||||
float get_angular_acceleration_max() const;
|
Vector3 get_linear_velocity();
|
||||||
void set_angular_acceleration_max(const float val);
|
void set_linear_velocity(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get_linear_velocity();
|
float get_angular_velocity() const;
|
||||||
void set_linear_velocity(const Vector3 &val);
|
void set_angular_velocity(const float val);
|
||||||
|
|
||||||
float get_angular_velocity() const;
|
float get_bounding_radius() const;
|
||||||
void set_angular_velocity(const float val);
|
void set_bounding_radius(const float val);
|
||||||
|
|
||||||
float get_bounding_radius() const;
|
bool get_is_tagged() const;
|
||||||
void set_bounding_radius(const float val);
|
void set_is_tagged(const bool val);
|
||||||
|
|
||||||
bool get_is_tagged() const;
|
GSAISteeringAgent();
|
||||||
void set_is_tagged(const bool val);
|
~GSAISteeringAgent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
GSAISteeringAgent();
|
// Adds velocity, speed, and size data to `GSAIAgentLocation`.
|
||||||
~GSAISteeringAgent();
|
//
|
||||||
|
// It is the character's responsibility to keep this information up to date for
|
||||||
protected:
|
// the steering toolkit to work correctly.
|
||||||
static void _bind_methods();
|
// @category - Base types
|
||||||
|
// The amount of velocity to be considered effectively not moving.
|
||||||
// Adds velocity, speed, and size data to `GSAIAgentLocation`.
|
float zero_linear_speed_threshold = 0.01;
|
||||||
//
|
// The maximum speed at which the agent can move.
|
||||||
// It is the character's responsibility to keep this information up to date for
|
float linear_speed_max = 0.0;
|
||||||
// the steering toolkit to work correctly.
|
// The maximum amount of acceleration that any behavior can apply to the agent.
|
||||||
// @category - Base types
|
float linear_acceleration_max = 0.0;
|
||||||
// The amount of velocity to be considered effectively not moving.
|
// The maximum amount of angular speed at which the agent can rotate.
|
||||||
float zero_linear_speed_threshold = 0.01;
|
float angular_speed_max = 0.0;
|
||||||
// The maximum speed at which the agent can move.
|
// The maximum amount of angular acceleration that any behavior can apply to an
|
||||||
float linear_speed_max = 0.0;
|
// agent.
|
||||||
// The maximum amount of acceleration that any behavior can apply to the agent.
|
float angular_acceleration_max = 0.0;
|
||||||
float linear_acceleration_max = 0.0;
|
// Current velocity of the agent.
|
||||||
// The maximum amount of angular speed at which the agent can rotate.
|
Vector3 linear_velocity = Vector3.ZERO;
|
||||||
float angular_speed_max = 0.0;
|
// Current angular velocity of the agent.
|
||||||
// The maximum amount of angular acceleration that any behavior can apply to an
|
float angular_velocity = 0.0;
|
||||||
// agent.
|
// The radius of the sphere that approximates the agent's size in space.
|
||||||
float angular_acceleration_max = 0.0;
|
float bounding_radius = 0.0;
|
||||||
// Current velocity of the agent.
|
// Used internally by group behaviors and proximities to mark the agent as already
|
||||||
Vector3 linear_velocity = Vector3.ZERO;
|
// considered.
|
||||||
// Current angular velocity of the agent.
|
bool is_tagged = false;
|
||||||
float angular_velocity = 0.0;
|
|
||||||
// The radius of the sphere that approximates the agent's size in space.
|
|
||||||
float bounding_radius = 0.0;
|
|
||||||
// Used internally by group behaviors and proximities to mark the agent as already
|
|
||||||
// considered.
|
|
||||||
bool is_tagged = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,84 +1,68 @@
|
|||||||
|
|
||||||
#include "gsai_steering_behavior.h"
|
#include "gsai_steering_behavior.h"
|
||||||
|
|
||||||
|
|
||||||
bool GSAISteeringBehavior::get_is_enabled() const {
|
bool GSAISteeringBehavior::get_is_enabled() const {
|
||||||
return is_enabled;
|
return is_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringBehavior::set_is_enabled(const bool val) {
|
void GSAISteeringBehavior::set_is_enabled(const bool val) {
|
||||||
is_enabled = val;
|
is_enabled = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISteeringAgent GSAISteeringBehavior::get_ *agent() {
|
||||||
GSAISteeringAgent GSAISteeringBehavior::get_*agent() {
|
return *agent;
|
||||||
return *agent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAISteeringBehavior::set_*agent(const GSAISteeringAgent &val) {
|
void GSAISteeringBehavior::set_ *agent(const GSAISteeringAgent &val) {
|
||||||
*agent = val;
|
*agent = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Base class for all steering behaviors.;
|
||||||
|
//;
|
||||||
|
// Steering behaviors calculate the linear and the angular acceleration to be;
|
||||||
|
// to the agent that owns them.;
|
||||||
|
//;
|
||||||
|
// The `calculate_steering` function is the entry point for all behaviors.;
|
||||||
|
// Individual steering behaviors encapsulate the steering logic.;
|
||||||
|
// @category - Base types;
|
||||||
|
// If `false`, all calculations return zero amounts of acceleration.;
|
||||||
|
bool is_enabled = true;
|
||||||
|
// The AI agent on which the steering behavior bases its calculations.;
|
||||||
|
GSAISteeringAgent *agent;
|
||||||
|
// Sets the `acceleration` with the behavior's desired amount of acceleration.;
|
||||||
|
|
||||||
|
void GSAISteeringBehavior::calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
|
if (is_enabled) {
|
||||||
|
call("_calculate_steering", acceleration);
|
||||||
|
}
|
||||||
|
|
||||||
// Base class for all steering behaviors.;
|
else {
|
||||||
//;
|
acceleration.set_zero();
|
||||||
// Steering behaviors calculate the linear and the angular acceleration to be;
|
}
|
||||||
// to the agent that owns them.;
|
|
||||||
//;
|
|
||||||
// The `calculate_steering` function is the entry point for all behaviors.;
|
|
||||||
// Individual steering behaviors encapsulate the steering logic.;
|
|
||||||
// @category - Base types;
|
|
||||||
// If `false`, all calculations return zero amounts of acceleration.;
|
|
||||||
bool is_enabled = true;
|
|
||||||
// The AI agent on which the steering behavior bases its calculations.;
|
|
||||||
GSAISteeringAgent *agent;
|
|
||||||
// Sets the `acceleration` with the behavior's desired amount of acceleration.;
|
|
||||||
|
|
||||||
void GSAISteeringBehavior::calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
|
|
||||||
if (is_enabled) {
|
|
||||||
call("_calculate_steering", acceleration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSAISteeringBehavior::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
||||||
else {
|
acceleration.set_zero();
|
||||||
acceleration.set_zero();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISteeringBehavior::GSAISteeringBehavior() {
|
||||||
|
is_enabled = true;
|
||||||
|
*agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAISteeringBehavior::~GSAISteeringBehavior() {
|
||||||
void GSAISteeringBehavior::_calculate_steering(const GSAITargetAcceleration &acceleration) {
|
|
||||||
acceleration.set_zero();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAISteeringBehavior::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_is_enabled"), &GSAISteeringBehavior::get_is_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_is_enabled", "value"), &GSAISteeringBehavior::set_is_enabled);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_enabled"), "set_is_enabled", "get_is_enabled");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*agent"), &GSAISteeringBehavior::get_ * agent);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*agent", "value"), &GSAISteeringBehavior::set_ * agent);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*agent", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*agent", "get_*agent");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("calculate_steering", "acceleration"), &GSAISteeringBehavior::calculate_steering);
|
||||||
|
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAISteeringBehavior::_calculate_steering);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAISteeringBehavior::GSAISteeringBehavior() {
|
|
||||||
is_enabled = true;
|
|
||||||
*agent;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAISteeringBehavior::~GSAISteeringBehavior() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAISteeringBehavior::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_is_enabled"), &GSAISteeringBehavior::get_is_enabled);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_is_enabled", "value"), &GSAISteeringBehavior::set_is_enabled);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_enabled"), "set_is_enabled", "get_is_enabled");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*agent"), &GSAISteeringBehavior::get_*agent);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*agent", "value"), &GSAISteeringBehavior::set_*agent);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*agent", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*agent", "get_*agent");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("calculate_steering", "acceleration"), &GSAISteeringBehavior::calculate_steering);
|
|
||||||
ClassDB::bind_method(D_METHOD("_calculate_steering", "acceleration"), &GSAISteeringBehavior::_calculate_steering);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
#ifndef GSAISTEERINGBEHAVIOR_H
|
#ifndef GSAISTEERINGBEHAVIOR_H
|
||||||
#define GSAISTEERINGBEHAVIOR_H
|
#define GSAISTEERINGBEHAVIOR_H
|
||||||
|
|
||||||
|
|
||||||
class GSAISteeringBehavior : public Reference {
|
class GSAISteeringBehavior : public Reference {
|
||||||
GDCLASS(GSAISteeringBehavior, Reference);
|
GDCLASS(GSAISteeringBehavior, Reference);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool get_is_enabled() const;
|
||||||
|
void set_is_enabled(const bool val);
|
||||||
|
|
||||||
bool get_is_enabled() const;
|
GSAISteeringAgent get_ *agent();
|
||||||
void set_is_enabled(const bool val);
|
void set_ *agent(const GSAISteeringAgent &val);
|
||||||
|
|
||||||
GSAISteeringAgent get_*agent();
|
void calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
void set_*agent(const GSAISteeringAgent &val);
|
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
||||||
|
|
||||||
void calculate_steering(const GSAITargetAcceleration &acceleration);
|
GSAISteeringBehavior();
|
||||||
void _calculate_steering(const GSAITargetAcceleration &acceleration);
|
~GSAISteeringBehavior();
|
||||||
|
|
||||||
GSAISteeringBehavior();
|
protected:
|
||||||
~GSAISteeringBehavior();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Base class for all steering behaviors.
|
||||||
static void _bind_methods();
|
//
|
||||||
|
// Steering behaviors calculate the linear and the angular acceleration to be
|
||||||
// Base class for all steering behaviors.
|
// to the agent that owns them.
|
||||||
//
|
//
|
||||||
// Steering behaviors calculate the linear and the angular acceleration to be
|
// The `calculate_steering` function is the entry point for all behaviors.
|
||||||
// to the agent that owns them.
|
// Individual steering behaviors encapsulate the steering logic.
|
||||||
//
|
// @category - Base types
|
||||||
// The `calculate_steering` function is the entry point for all behaviors.
|
// If `false`, all calculations return zero amounts of acceleration.
|
||||||
// Individual steering behaviors encapsulate the steering logic.
|
bool is_enabled = true;
|
||||||
// @category - Base types
|
// The AI agent on which the steering behavior bases its calculations.
|
||||||
// If `false`, all calculations return zero amounts of acceleration.
|
GSAISteeringAgent *agent;
|
||||||
bool is_enabled = true;
|
// Sets the `acceleration` with the behavior's desired amount of acceleration.
|
||||||
// The AI agent on which the steering behavior bases its calculations.
|
|
||||||
GSAISteeringAgent *agent;
|
|
||||||
// Sets the `acceleration` with the behavior's desired amount of acceleration.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,89 +1,77 @@
|
|||||||
|
|
||||||
#include "gsai_target_acceleration.h"
|
#include "gsai_target_acceleration.h"
|
||||||
|
|
||||||
|
|
||||||
Vector3 GSAITargetAcceleration::get_linear() {
|
Vector3 GSAITargetAcceleration::get_linear() {
|
||||||
return linear;
|
return linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAITargetAcceleration::set_linear(const Vector3 &val) {
|
void GSAITargetAcceleration::set_linear(const Vector3 &val) {
|
||||||
linear = val;
|
linear = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float GSAITargetAcceleration::get_angular() const {
|
float GSAITargetAcceleration::get_angular() const {
|
||||||
return angular;
|
return angular;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAITargetAcceleration::set_angular(const float val) {
|
void GSAITargetAcceleration::set_angular(const float val) {
|
||||||
angular = val;
|
angular = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A desired linear and angular amount of acceleration requested by the steering;
|
||||||
|
// system.;
|
||||||
|
// @category - Base types;
|
||||||
|
// Linear acceleration;
|
||||||
|
Vector3 linear = Vector3.ZERO;
|
||||||
|
// Angular acceleration;
|
||||||
|
float angular = 0.0;
|
||||||
|
// Sets the linear and angular components to 0.;
|
||||||
|
|
||||||
|
void GSAITargetAcceleration::set_zero() {
|
||||||
// A desired linear and angular amount of acceleration requested by the steering;
|
linear.x = 0.0;
|
||||||
// system.;
|
linear.y = 0.0;
|
||||||
// @category - Base types;
|
linear.z = 0.0;
|
||||||
// Linear acceleration;
|
angular = 0.0;
|
||||||
Vector3 linear = Vector3.ZERO;
|
|
||||||
// Angular acceleration;
|
|
||||||
float angular = 0.0;
|
|
||||||
// Sets the linear and angular components to 0.;
|
|
||||||
|
|
||||||
void GSAITargetAcceleration::set_zero() {
|
|
||||||
linear.x = 0.0;
|
|
||||||
linear.y = 0.0;
|
|
||||||
linear.z = 0.0;
|
|
||||||
angular = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds `accel`'s components, multiplied by `scalar`, to this one.;
|
// Adds `accel`'s components, multiplied by `scalar`, to this one.;
|
||||||
|
|
||||||
void GSAITargetAcceleration::add_scaled_accel(const GSAITargetAcceleration &accel, const float scalar) {
|
void GSAITargetAcceleration::add_scaled_accel(const GSAITargetAcceleration &accel, const float scalar) {
|
||||||
linear += accel.linear * scalar;
|
linear += accel.linear * scalar;
|
||||||
angular += accel.angular * scalar;
|
angular += accel.angular * scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the squared magnitude of the linear and angular components.;
|
// Returns the squared magnitude of the linear and angular components.;
|
||||||
|
|
||||||
float GSAITargetAcceleration::get_magnitude_squared() {
|
float GSAITargetAcceleration::get_magnitude_squared() {
|
||||||
return linear.length_squared() + angular * angular;
|
return linear.length_squared() + angular * angular;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the magnitude of the linear and angular components.;
|
// Returns the magnitude of the linear and angular components.;
|
||||||
|
|
||||||
float GSAITargetAcceleration::get_magnitude() {
|
float GSAITargetAcceleration::get_magnitude() {
|
||||||
return sqrt(get_magnitude_squared());
|
return sqrt(get_magnitude_squared());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAITargetAcceleration::GSAITargetAcceleration() {
|
||||||
|
linear = Vector3.ZERO;
|
||||||
|
angular = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAITargetAcceleration::GSAITargetAcceleration() {
|
GSAITargetAcceleration::~GSAITargetAcceleration() {
|
||||||
linear = Vector3.ZERO;
|
}
|
||||||
angular = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAITargetAcceleration::~GSAITargetAcceleration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAITargetAcceleration::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_linear"), &GSAITargetAcceleration::get_linear);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_linear", "value"), &GSAITargetAcceleration::set_linear);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear"), "set_linear", "get_linear");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_angular"), &GSAITargetAcceleration::get_angular);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_angular", "value"), &GSAITargetAcceleration::set_angular);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular"), "set_angular", "get_angular");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_zero"), &GSAITargetAcceleration::set_zero);
|
|
||||||
ClassDB::bind_method(D_METHOD("add_scaled_accel", "accel", "scalar"), &GSAITargetAcceleration::add_scaled_accel);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_magnitude_squared"), &GSAITargetAcceleration::get_magnitude_squared);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_magnitude"), &GSAITargetAcceleration::get_magnitude);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void GSAITargetAcceleration::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_linear"), &GSAITargetAcceleration::get_linear);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_linear", "value"), &GSAITargetAcceleration::set_linear);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear"), "set_linear", "get_linear");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_angular"), &GSAITargetAcceleration::get_angular);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_angular", "value"), &GSAITargetAcceleration::set_angular);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular"), "set_angular", "get_angular");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_zero"), &GSAITargetAcceleration::set_zero);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_scaled_accel", "accel", "scalar"), &GSAITargetAcceleration::add_scaled_accel);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_magnitude_squared"), &GSAITargetAcceleration::get_magnitude_squared);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_magnitude"), &GSAITargetAcceleration::get_magnitude);
|
||||||
|
}
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
#ifndef GSAITARGETACCELERATION_H
|
#ifndef GSAITARGETACCELERATION_H
|
||||||
#define GSAITARGETACCELERATION_H
|
#define GSAITARGETACCELERATION_H
|
||||||
|
|
||||||
|
|
||||||
class GSAITargetAcceleration : public Reference {
|
class GSAITargetAcceleration : public Reference {
|
||||||
GDCLASS(GSAITargetAcceleration, Reference);
|
GDCLASS(GSAITargetAcceleration, Reference);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Vector3 get_linear();
|
||||||
|
void set_linear(const Vector3 &val);
|
||||||
|
|
||||||
Vector3 get_linear();
|
float get_angular() const;
|
||||||
void set_linear(const Vector3 &val);
|
void set_angular(const float val);
|
||||||
|
|
||||||
float get_angular() const;
|
void set_zero();
|
||||||
void set_angular(const float val);
|
void add_scaled_accel(const GSAITargetAcceleration &accel, const float scalar);
|
||||||
|
float get_magnitude_squared();
|
||||||
|
float get_magnitude();
|
||||||
|
|
||||||
void set_zero();
|
GSAITargetAcceleration();
|
||||||
void add_scaled_accel(const GSAITargetAcceleration &accel, const float scalar);
|
~GSAITargetAcceleration();
|
||||||
float get_magnitude_squared();
|
|
||||||
float get_magnitude();
|
|
||||||
|
|
||||||
GSAITargetAcceleration();
|
protected:
|
||||||
~GSAITargetAcceleration();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// A desired linear and angular amount of acceleration requested by the steering
|
||||||
static void _bind_methods();
|
// system.
|
||||||
|
// @category - Base types
|
||||||
// A desired linear and angular amount of acceleration requested by the steering
|
// Linear acceleration
|
||||||
// system.
|
Vector3 linear = Vector3.ZERO;
|
||||||
// @category - Base types
|
// Angular acceleration
|
||||||
// Linear acceleration
|
float angular = 0.0;
|
||||||
Vector3 linear = Vector3.ZERO;
|
// Sets the linear and angular components to 0.
|
||||||
// Angular acceleration
|
// Adds `accel`'s components, multiplied by `scalar`, to this one.
|
||||||
float angular = 0.0;
|
// Returns the squared magnitude of the linear and angular components.
|
||||||
// Sets the linear and angular components to 0.
|
// Returns the magnitude of the linear and angular components.
|
||||||
// Adds `accel`'s components, multiplied by `scalar`, to this one.
|
|
||||||
// Returns the squared magnitude of the linear and angular components.
|
|
||||||
// Returns the magnitude of the linear and angular components.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,71 +1,63 @@
|
|||||||
|
|
||||||
#include "gsai_utils.h"
|
#include "gsai_utils.h"
|
||||||
|
|
||||||
|
// Math and vector utility functions.;
|
||||||
|
// @Category - Utilities;
|
||||||
|
// Returns the `vector` with its length capped to `limit`.;
|
||||||
|
|
||||||
|
Vector3 GSAIUtils::clampedv3(const Vector3 &vector, const float limit) {
|
||||||
|
float length_squared = vector.length_squared();
|
||||||
|
float limit_squared = limit * limit;
|
||||||
|
|
||||||
// Math and vector utility functions.;
|
if (length_squared > limit_squared) {
|
||||||
// @Category - Utilities;
|
vector *= sqrt(limit_squared / length_squared);
|
||||||
// Returns the `vector` with its length capped to `limit`.;
|
}
|
||||||
|
|
||||||
Vector3 GSAIUtils::clampedv3(const Vector3 &vector, const float limit) {
|
return vector;
|
||||||
float length_squared = vector.length_squared();
|
|
||||||
float limit_squared = limit * limit;
|
|
||||||
|
|
||||||
if (length_squared > limit_squared) {
|
|
||||||
vector *= sqrt(limit_squared / length_squared);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vector;
|
// Returns an angle in radians between the positive X axis and the `vector`.;
|
||||||
|
//;
|
||||||
|
// This assumes orientation for 3D agents that are upright and rotate;
|
||||||
|
// around the Y axis.;
|
||||||
|
|
||||||
|
float GSAIUtils::vector3_to_angle(const Vector3 &vector) {
|
||||||
|
return atan2(vector.x, vector.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an angle in radians between the positive X axis and the `vector`.;
|
// Returns an angle in radians between the positive X axis and the `vector`.;
|
||||||
//;
|
|
||||||
// This assumes orientation for 3D agents that are upright and rotate;
|
|
||||||
// around the Y axis.;
|
|
||||||
|
|
||||||
float GSAIUtils::vector3_to_angle(const Vector3 &vector) {
|
float GSAIUtils::vector2_to_angle(const Vector2 &vector) {
|
||||||
return atan2(vector.x, vector.z);
|
return atan2(vector.x, -vector.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an angle in radians between the positive X axis and the `vector`.;
|
// Returns a directional vector from the given orientation angle.;
|
||||||
|
//;
|
||||||
|
// This assumes orientation for 2D agents or 3D agents that are upright and;
|
||||||
|
// rotate around the Y axis.;
|
||||||
|
|
||||||
float GSAIUtils::vector2_to_angle(const Vector2 &vector) {
|
Vector2 GSAIUtils::angle_to_vector2(const float angle) {
|
||||||
return atan2(vector.x, -vector.y);
|
return Vector2(sin(-angle), cos(angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a directional vector from the given orientation angle.;
|
// Returns a vector2 with `vector`'s x and y components.;
|
||||||
//;
|
|
||||||
// This assumes orientation for 2D agents or 3D agents that are upright and;
|
|
||||||
// rotate around the Y axis.;
|
|
||||||
|
|
||||||
Vector2 GSAIUtils::angle_to_vector2(const float angle) {
|
Vector2 GSAIUtils::to_vector2(const Vector3 &vector) {
|
||||||
return Vector2(sin(-angle), cos(angle));
|
return Vector2(vector.x, vector.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a vector2 with `vector`'s x and y components.;
|
// Returns a vector3 with `vector`'s x and y components and 0 in z.;
|
||||||
|
|
||||||
Vector2 GSAIUtils::to_vector2(const Vector3 &vector) {
|
Vector3 GSAIUtils::to_vector3(const Vector2 &vector) {
|
||||||
return Vector2(vector.x, vector.y);
|
return Vector3(vector.x, vector.y, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a vector3 with `vector`'s x and y components and 0 in z.;
|
GSAIUtils::GSAIUtils() {
|
||||||
|
|
||||||
Vector3 GSAIUtils::to_vector3(const Vector2 &vector) {
|
|
||||||
return Vector3(vector.x, vector.y, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIUtils::~GSAIUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIUtils::GSAIUtils() {
|
static void GSAIUtils::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIUtils::~GSAIUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIUtils::_bind_methods() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,38 +1,35 @@
|
|||||||
#ifndef GSAIUTILS_H
|
#ifndef GSAIUTILS_H
|
||||||
#define GSAIUTILS_H
|
#define GSAIUTILS_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIUtils {
|
class GSAIUtils {
|
||||||
public:
|
public:
|
||||||
|
static Vector3 clampedv3(const Vector3 &vector, const float limit);
|
||||||
|
static float vector3_to_angle(const Vector3 &vector);
|
||||||
|
static float vector2_to_angle(const Vector2 &vector);
|
||||||
|
static Vector2 angle_to_vector2(const float angle);
|
||||||
|
static Vector2 to_vector2(const Vector3 &vector);
|
||||||
|
static Vector3 to_vector3(const Vector2 &vector);
|
||||||
|
|
||||||
static Vector3 clampedv3(const Vector3 &vector, const float limit);
|
GSAIUtils();
|
||||||
static float vector3_to_angle(const Vector3 &vector);
|
~GSAIUtils();
|
||||||
static float vector2_to_angle(const Vector2 &vector);
|
|
||||||
static Vector2 angle_to_vector2(const float angle);
|
|
||||||
static Vector2 to_vector2(const Vector3 &vector);
|
|
||||||
static Vector3 to_vector3(const Vector2 &vector);
|
|
||||||
|
|
||||||
GSAIUtils();
|
protected:
|
||||||
~GSAIUtils();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Math and vector utility functions.
|
||||||
static void _bind_methods();
|
// @Category - Utilities
|
||||||
|
// Returns the `vector` with its length capped to `limit`.
|
||||||
// Math and vector utility functions.
|
// Returns an angle in radians between the positive X axis and the `vector`.
|
||||||
// @Category - Utilities
|
//
|
||||||
// Returns the `vector` with its length capped to `limit`.
|
// This assumes orientation for 3D agents that are upright and rotate
|
||||||
// Returns an angle in radians between the positive X axis and the `vector`.
|
// around the Y axis.
|
||||||
//
|
// Returns an angle in radians between the positive X axis and the `vector`.
|
||||||
// This assumes orientation for 3D agents that are upright and rotate
|
// Returns a directional vector from the given orientation angle.
|
||||||
// around the Y axis.
|
//
|
||||||
// Returns an angle in radians between the positive X axis and the `vector`.
|
// This assumes orientation for 2D agents or 3D agents that are upright and
|
||||||
// Returns a directional vector from the given orientation angle.
|
// rotate around the Y axis.
|
||||||
//
|
// Returns a vector2 with `vector`'s x and y components.
|
||||||
// This assumes orientation for 2D agents or 3D agents that are upright and
|
// Returns a vector3 with `vector`'s x and y components and 0 in z.
|
||||||
// rotate around the Y axis.
|
|
||||||
// Returns a vector2 with `vector`'s x and y components.
|
|
||||||
// Returns a vector3 with `vector`'s x and y components and 0 in z.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,50 +1,39 @@
|
|||||||
|
|
||||||
#include "gsai_infinite_proximity.h"
|
#include "gsai_infinite_proximity.h"
|
||||||
|
|
||||||
|
// Determines any agent that is in the specified list as being neighbors with the;
|
||||||
|
// owner agent, regardless of distance.;
|
||||||
|
// @category - Proximities;
|
||||||
|
// Returns a number of neighbors based on a `callback` function.;
|
||||||
|
//;
|
||||||
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array and;
|
||||||
|
// adds one to the count if its `callback` returns true.;
|
||||||
|
// @tags - virtual;
|
||||||
|
|
||||||
|
int GSAIInfiniteProximity::_find_neighbors(const FuncRef &callback) {
|
||||||
|
int neighbor_count = 0;
|
||||||
|
int agent_count = agents.size();
|
||||||
|
|
||||||
// Determines any agent that is in the specified list as being neighbors with the;
|
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
||||||
// owner agent, regardless of distance.;
|
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
||||||
// @category - Proximities;
|
|
||||||
// Returns a number of neighbors based on a `callback` function.;
|
|
||||||
//;
|
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array and;
|
|
||||||
// adds one to the count if its `callback` returns true.;
|
|
||||||
// @tags - virtual;
|
|
||||||
|
|
||||||
int GSAIInfiniteProximity::_find_neighbors(const FuncRef &callback) {
|
if (current_agent != agent) {
|
||||||
int neighbor_count = 0;
|
if (callback.call_func(current_agent)) {
|
||||||
int agent_count = agents.size();
|
neighbor_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
return neighbor_count;
|
||||||
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
}
|
||||||
|
|
||||||
if (current_agent != agent) {
|
|
||||||
|
|
||||||
if (callback.call_func(current_agent)) {
|
|
||||||
neighbor_count += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIInfiniteProximity::GSAIInfiniteProximity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIInfiniteProximity::~GSAIInfiniteProximity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return neighbor_count;
|
static void GSAIInfiniteProximity::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("_find_neighbors", "callback"), &GSAIInfiniteProximity::_find_neighbors);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIInfiniteProximity::GSAIInfiniteProximity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIInfiniteProximity::~GSAIInfiniteProximity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIInfiniteProximity::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("_find_neighbors", "callback"), &GSAIInfiniteProximity::_find_neighbors);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,29 +1,26 @@
|
|||||||
#ifndef GSAIINFINITEPROXIMITY_H
|
#ifndef GSAIINFINITEPROXIMITY_H
|
||||||
#define GSAIINFINITEPROXIMITY_H
|
#define GSAIINFINITEPROXIMITY_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIInfiniteProximity : public GSAIProximity {
|
class GSAIInfiniteProximity : public GSAIProximity {
|
||||||
GDCLASS(GSAIInfiniteProximity, GSAIProximity);
|
GDCLASS(GSAIInfiniteProximity, GSAIProximity);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int _find_neighbors(const FuncRef &callback);
|
||||||
|
|
||||||
int _find_neighbors(const FuncRef &callback);
|
GSAIInfiniteProximity();
|
||||||
|
~GSAIInfiniteProximity();
|
||||||
|
|
||||||
GSAIInfiniteProximity();
|
protected:
|
||||||
~GSAIInfiniteProximity();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Determines any agent that is in the specified list as being neighbors with the
|
||||||
static void _bind_methods();
|
// owner agent, regardless of distance.
|
||||||
|
// @category - Proximities
|
||||||
// Determines any agent that is in the specified list as being neighbors with the
|
// Returns a number of neighbors based on a `callback` function.
|
||||||
// owner agent, regardless of distance.
|
//
|
||||||
// @category - Proximities
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array and
|
||||||
// Returns a number of neighbors based on a `callback` function.
|
// adds one to the count if its `callback` returns true.
|
||||||
//
|
// @tags - virtual
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array and
|
|
||||||
// adds one to the count if its `callback` returns true.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,74 +1,62 @@
|
|||||||
|
|
||||||
#include "gsai_proximity.h"
|
#include "gsai_proximity.h"
|
||||||
|
|
||||||
|
GSAISteeringAgent GSAIProximity::get_ *agent() {
|
||||||
GSAISteeringAgent GSAIProximity::get_*agent() {
|
return *agent;
|
||||||
return *agent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIProximity::set_*agent(const GSAISteeringAgent &val) {
|
void GSAIProximity::set_ *agent(const GSAISteeringAgent &val) {
|
||||||
*agent = val;
|
*agent = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Array GSAIProximity::get_agents() {
|
Array GSAIProximity::get_agents() {
|
||||||
return agents;
|
return agents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIProximity::set_agents(const Array &val) {
|
void GSAIProximity::set_agents(const Array &val) {
|
||||||
agents = val;
|
agents = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Base container type that stores data to find the neighbors of an agent.;
|
||||||
|
// @category - Proximities;
|
||||||
|
// @tags - abstract;
|
||||||
|
// The owning agent whose neighbors are found in the group;
|
||||||
|
GSAISteeringAgent *agent;
|
||||||
|
// The agents who are part of this group and could be potential neighbors;
|
||||||
|
Array agents = Array();
|
||||||
|
|
||||||
|
int GSAIProximity::find_neighbors(const FuncRef &_callback) {
|
||||||
// Base container type that stores data to find the neighbors of an agent.;
|
return call("_find_neighbors", _callback);
|
||||||
// @category - Proximities;
|
|
||||||
// @tags - abstract;
|
|
||||||
// The owning agent whose neighbors are found in the group;
|
|
||||||
GSAISteeringAgent *agent;
|
|
||||||
// The agents who are part of this group and could be potential neighbors;
|
|
||||||
Array agents = Array();
|
|
||||||
|
|
||||||
int GSAIProximity::find_neighbors(const FuncRef &_callback) {
|
|
||||||
return call("_find_neighbors", _callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a number of neighbors based on a `callback` function.;
|
// Returns a number of neighbors based on a `callback` function.;
|
||||||
//;
|
//;
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array and;
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array and;
|
||||||
// adds one to the count if its `callback` returns true.;
|
// adds one to the count if its `callback` returns true.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
int GSAIProximity::_find_neighbors(const FuncRef &_callback) {
|
int GSAIProximity::_find_neighbors(const FuncRef &_callback) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIProximity::GSAIProximity() {
|
||||||
|
*agent;
|
||||||
|
agents = Array();
|
||||||
}
|
}
|
||||||
|
|
||||||
GSAIProximity::GSAIProximity() {
|
GSAIProximity::~GSAIProximity() {
|
||||||
*agent;
|
}
|
||||||
agents = Array();
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIProximity::~GSAIProximity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIProximity::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*agent"), &GSAIProximity::get_*agent);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*agent", "value"), &GSAIProximity::set_*agent);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*agent", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*agent", "get_*agent");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_agents"), &GSAIProximity::get_agents);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_agents", "value"), &GSAIProximity::set_agents);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "agents"), "set_agents", "get_agents");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("find_neighbors", "_callback"), &GSAIProximity::find_neighbors);
|
|
||||||
ClassDB::bind_method(D_METHOD("_find_neighbors", "_callback"), &GSAIProximity::_find_neighbors);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void GSAIProximity::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*agent"), &GSAIProximity::get_ * agent);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*agent", "value"), &GSAIProximity::set_ * agent);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*agent", PROPERTY_HINT_RESOURCE_TYPE, "GSAISteeringAgent"), "set_*agent", "get_*agent");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_agents"), &GSAIProximity::get_agents);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_agents", "value"), &GSAIProximity::set_agents);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "agents"), "set_agents", "get_agents");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("find_neighbors", "_callback"), &GSAIProximity::find_neighbors);
|
||||||
|
ClassDB::bind_method(D_METHOD("_find_neighbors", "_callback"), &GSAIProximity::_find_neighbors);
|
||||||
|
}
|
||||||
|
@ -1,40 +1,37 @@
|
|||||||
#ifndef GSAIPROXIMITY_H
|
#ifndef GSAIPROXIMITY_H
|
||||||
#define GSAIPROXIMITY_H
|
#define GSAIPROXIMITY_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIProximity : public Reference {
|
class GSAIProximity : public Reference {
|
||||||
GDCLASS(GSAIProximity, Reference);
|
GDCLASS(GSAIProximity, Reference);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GSAISteeringAgent get_ *agent();
|
||||||
|
void set_ *agent(const GSAISteeringAgent &val);
|
||||||
|
|
||||||
GSAISteeringAgent get_*agent();
|
Array get_agents();
|
||||||
void set_*agent(const GSAISteeringAgent &val);
|
void set_agents(const Array &val);
|
||||||
|
|
||||||
Array get_agents();
|
int find_neighbors(const FuncRef &_callback);
|
||||||
void set_agents(const Array &val);
|
int _find_neighbors(const FuncRef &_callback);
|
||||||
|
|
||||||
int find_neighbors(const FuncRef &_callback);
|
GSAIProximity();
|
||||||
int _find_neighbors(const FuncRef &_callback);
|
~GSAIProximity();
|
||||||
|
|
||||||
GSAIProximity();
|
protected:
|
||||||
~GSAIProximity();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Base container type that stores data to find the neighbors of an agent.
|
||||||
static void _bind_methods();
|
// @category - Proximities
|
||||||
|
// @tags - abstract
|
||||||
// Base container type that stores data to find the neighbors of an agent.
|
// The owning agent whose neighbors are found in the group
|
||||||
// @category - Proximities
|
GSAISteeringAgent *agent;
|
||||||
// @tags - abstract
|
// The agents who are part of this group and could be potential neighbors
|
||||||
// The owning agent whose neighbors are found in the group
|
Array agents = Array();
|
||||||
GSAISteeringAgent *agent;
|
// Returns a number of neighbors based on a `callback` function.
|
||||||
// The agents who are part of this group and could be potential neighbors
|
//
|
||||||
Array agents = Array();
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array and
|
||||||
// Returns a number of neighbors based on a `callback` function.
|
// adds one to the count if its `callback` returns true.
|
||||||
//
|
// @tags - virtual
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array and
|
|
||||||
// adds one to the count if its `callback` returns true.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,149 +1,124 @@
|
|||||||
|
|
||||||
#include "gsai_radius_proximity.h"
|
#include "gsai_radius_proximity.h"
|
||||||
|
|
||||||
|
|
||||||
float GSAIRadiusProximity::get_radius() const {
|
float GSAIRadiusProximity::get_radius() const {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRadiusProximity::set_radius(const float val) {
|
void GSAIRadiusProximity::set_radius(const float val) {
|
||||||
radius = val;
|
radius = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GSAIRadiusProximity::get__last_frame() const {
|
int GSAIRadiusProximity::get__last_frame() const {
|
||||||
return _last_frame;
|
return _last_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRadiusProximity::set__last_frame(const int val) {
|
void GSAIRadiusProximity::set__last_frame(const int val) {
|
||||||
_last_frame = val;
|
_last_frame = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneTree GSAIRadiusProximity::get_ *_scene_tree() {
|
||||||
SceneTree GSAIRadiusProximity::get_*_scene_tree() {
|
return *_scene_tree;
|
||||||
return *_scene_tree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSAIRadiusProximity::set_*_scene_tree(const SceneTree &val) {
|
void GSAIRadiusProximity::set_ *_scene_tree(const SceneTree &val) {
|
||||||
*_scene_tree = val;
|
*_scene_tree = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determines any agent that is in the specified list as being neighbors with the owner agent if;
|
||||||
|
// they lie within the specified radius.;
|
||||||
|
// @category - Proximities;
|
||||||
|
// The radius around the owning agent to find neighbors in;
|
||||||
|
float radius = 0.0;
|
||||||
|
int _last_frame = 0;
|
||||||
|
SceneTree *_scene_tree;
|
||||||
|
|
||||||
|
void GSAIRadiusProximity::_init() {
|
||||||
// Determines any agent that is in the specified list as being neighbors with the owner agent if;
|
_scene_tree = Engine.get_main_loop();
|
||||||
// they lie within the specified radius.;
|
|
||||||
// @category - Proximities;
|
|
||||||
// The radius around the owning agent to find neighbors in;
|
|
||||||
float radius = 0.0;
|
|
||||||
int _last_frame = 0;
|
|
||||||
SceneTree *_scene_tree;
|
|
||||||
|
|
||||||
void GSAIRadiusProximity::_init() {
|
|
||||||
_scene_tree = Engine.get_main_loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a number of neighbors based on a `callback` function.;
|
// Returns a number of neighbors based on a `callback` function.;
|
||||||
//;
|
//;
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within;
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within;
|
||||||
// the radius around the owning agent and adds one to the count if its `callback` returns true.;
|
// the radius around the owning agent and adds one to the count if its `callback` returns true.;
|
||||||
// @tags - virtual;
|
// @tags - virtual;
|
||||||
|
|
||||||
int GSAIRadiusProximity::_find_neighbors(const FuncRef &callback) {
|
int GSAIRadiusProximity::_find_neighbors(const FuncRef &callback) {
|
||||||
int agent_count = agents.size();
|
int agent_count = agents.size();
|
||||||
int neighbor_count = 0;
|
int neighbor_count = 0;
|
||||||
int current_frame = ;
|
int current_frame = ;
|
||||||
|
|
||||||
if (_scene_tree) {
|
if (_scene_tree) {
|
||||||
current_frame = _scene_tree.get_frame();
|
current_frame = _scene_tree.get_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
current_frame = -_last_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_frame != _last_frame) {
|
||||||
|
_last_frame = current_frame;
|
||||||
|
Vector3 owner_position = agent.position;
|
||||||
|
|
||||||
|
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
||||||
|
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
||||||
|
|
||||||
|
if (current_agent != agent) {
|
||||||
|
float distance_squared = owner_position.distance_squared_to(current_agent.position);
|
||||||
|
float range_to = radius + current_agent.bounding_radius;
|
||||||
|
|
||||||
|
if (distance_squared < range_to * range_to) {
|
||||||
|
if (callback.call_func(current_agent)) {
|
||||||
|
current_agent.is_tagged = true;
|
||||||
|
neighbor_count += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_agent.is_tagged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
||||||
|
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
||||||
|
|
||||||
|
if (current_agent != agent && current_agent.is_tagged) {
|
||||||
|
if (callback.call_func(current_agent)) {
|
||||||
|
neighbor_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbor_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIRadiusProximity::GSAIRadiusProximity() {
|
||||||
else {
|
radius = 0.0;
|
||||||
current_frame = -_last_frame;
|
_last_frame = 0;
|
||||||
|
*_scene_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSAIRadiusProximity::~GSAIRadiusProximity() {
|
||||||
if (current_frame != _last_frame) {
|
|
||||||
_last_frame = current_frame;
|
|
||||||
Vector3 owner_position = agent.position;
|
|
||||||
|
|
||||||
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
|
||||||
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
|
||||||
|
|
||||||
if (current_agent != agent) {
|
|
||||||
float distance_squared = owner_position.distance_squared_to(current_agent.position);
|
|
||||||
float range_to = radius + current_agent.bounding_radius;
|
|
||||||
|
|
||||||
if (distance_squared < range_to * range_to) {
|
|
||||||
|
|
||||||
if (callback.call_func(current_agent)) {
|
|
||||||
current_agent.is_tagged = true;
|
|
||||||
neighbor_count += 1;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSAIRadiusProximity::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_radius"), &GSAIRadiusProximity::get_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_radius", "value"), &GSAIRadiusProximity::set_radius);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get__last_frame"), &GSAIRadiusProximity::get__last_frame);
|
||||||
|
ClassDB::bind_method(D_METHOD("set__last_frame", "value"), &GSAIRadiusProximity::set__last_frame);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "_last_frame"), "set__last_frame", "get__last_frame");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_*_scene_tree"), &GSAIRadiusProximity::get_ * _scene_tree);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_*_scene_tree", "value"), &GSAIRadiusProximity::set_ * _scene_tree);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*_scene_tree", PROPERTY_HINT_RESOURCE_TYPE, "SceneTree"), "set_*_scene_tree", "get_*_scene_tree");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_init"), &GSAIRadiusProximity::_init);
|
||||||
|
ClassDB::bind_method(D_METHOD("_find_neighbors", "callback"), &GSAIRadiusProximity::_find_neighbors);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
current_agent.is_tagged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
|
|
||||||
for (int i = 0; i < agent_count; ++i) { //i in range(agent_count)
|
|
||||||
GSAISteeringAgent *current_agent = agents[i] as GSAISteeringAgent;
|
|
||||||
|
|
||||||
if (current_agent != agent && current_agent.is_tagged) {
|
|
||||||
|
|
||||||
if (callback.call_func(current_agent)) {
|
|
||||||
neighbor_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return neighbor_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRadiusProximity::GSAIRadiusProximity() {
|
|
||||||
radius = 0.0;
|
|
||||||
_last_frame = 0;
|
|
||||||
*_scene_tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSAIRadiusProximity::~GSAIRadiusProximity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void GSAIRadiusProximity::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_radius"), &GSAIRadiusProximity::get_radius);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_radius", "value"), &GSAIRadiusProximity::set_radius);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get__last_frame"), &GSAIRadiusProximity::get__last_frame);
|
|
||||||
ClassDB::bind_method(D_METHOD("set__last_frame", "value"), &GSAIRadiusProximity::set__last_frame);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_last_frame"), "set__last_frame", "get__last_frame");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_*_scene_tree"), &GSAIRadiusProximity::get_*_scene_tree);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_*_scene_tree", "value"), &GSAIRadiusProximity::set_*_scene_tree);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "*_scene_tree", PROPERTY_HINT_RESOURCE_TYPE, "SceneTree"), "set_*_scene_tree", "get_*_scene_tree");
|
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_init"), &GSAIRadiusProximity::_init);
|
|
||||||
ClassDB::bind_method(D_METHOD("_find_neighbors", "callback"), &GSAIRadiusProximity::_find_neighbors);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,43 +1,40 @@
|
|||||||
#ifndef GSAIRADIUSPROXIMITY_H
|
#ifndef GSAIRADIUSPROXIMITY_H
|
||||||
#define GSAIRADIUSPROXIMITY_H
|
#define GSAIRADIUSPROXIMITY_H
|
||||||
|
|
||||||
|
|
||||||
class GSAIRadiusProximity : public GSAIProximity {
|
class GSAIRadiusProximity : public GSAIProximity {
|
||||||
GDCLASS(GSAIRadiusProximity, GSAIProximity);
|
GDCLASS(GSAIRadiusProximity, GSAIProximity);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float get_radius() const;
|
||||||
|
void set_radius(const float val);
|
||||||
|
|
||||||
float get_radius() const;
|
int get__last_frame() const;
|
||||||
void set_radius(const float val);
|
void set__last_frame(const int val);
|
||||||
|
|
||||||
int get__last_frame() const;
|
SceneTree get_ *_scene_tree();
|
||||||
void set__last_frame(const int val);
|
void set_ *_scene_tree(const SceneTree &val);
|
||||||
|
|
||||||
SceneTree get_*_scene_tree();
|
void _init();
|
||||||
void set_*_scene_tree(const SceneTree &val);
|
int _find_neighbors(const FuncRef &callback);
|
||||||
|
|
||||||
void _init();
|
GSAIRadiusProximity();
|
||||||
int _find_neighbors(const FuncRef &callback);
|
~GSAIRadiusProximity();
|
||||||
|
|
||||||
GSAIRadiusProximity();
|
protected:
|
||||||
~GSAIRadiusProximity();
|
static void _bind_methods();
|
||||||
|
|
||||||
protected:
|
// Determines any agent that is in the specified list as being neighbors with the owner agent if
|
||||||
static void _bind_methods();
|
// they lie within the specified radius.
|
||||||
|
// @category - Proximities
|
||||||
// Determines any agent that is in the specified list as being neighbors with the owner agent if
|
// The radius around the owning agent to find neighbors in
|
||||||
// they lie within the specified radius.
|
float radius = 0.0;
|
||||||
// @category - Proximities
|
int _last_frame = 0;
|
||||||
// The radius around the owning agent to find neighbors in
|
SceneTree *_scene_tree;
|
||||||
float radius = 0.0;
|
// Returns a number of neighbors based on a `callback` function.
|
||||||
int _last_frame = 0;
|
//
|
||||||
SceneTree *_scene_tree;
|
// `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within
|
||||||
// Returns a number of neighbors based on a `callback` function.
|
// the radius around the owning agent and adds one to the count if its `callback` returns true.
|
||||||
//
|
// @tags - virtual
|
||||||
// `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within
|
|
||||||
// the radius around the owning agent and adds one to the count if its `callback` returns true.
|
|
||||||
// @tags - virtual
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user