Also cleaned up agents and added them to the build.

This commit is contained in:
Relintai 2023-01-14 13:36:30 +01:00
parent 967918fbe0
commit 3be6c6282c
13 changed files with 489 additions and 610 deletions

View File

@ -34,6 +34,12 @@ sources = [
"behaviors/gsai_pursue.cpp",
"behaviors/gsai_seek.cpp",
"behaviors/gsai_separation.cpp",
"agents/gsai_kinematic_body_2d_agent.cpp",
"agents/gsai_kinematic_body_3d_agent.cpp",
"agents/gsai_rigid_body_2d_agent.cpp",
"agents/gsai_rigid_body_3d_agent.cpp",
"agents/gsai_specialized_agent.cpp",
]

View File

@ -1,12 +1,39 @@
#include "gsai_kinematic_body_2d_agent.h"
KinematicBody2D GSAIKinematicBody2DAgent::get_ *body() {
return *body;
#include "core/math/math_funcs.h"
#include "scene/2d/physics_body_2d.h"
#include "scene/main/scene_tree.h"
#include "../gsai_target_acceleration.h"
#include "../gsai_utils.h"
KinematicBody2D *GSAIKinematicBody2DAgent::get_body() {
return Object::cast_to<KinematicBody2D>(ObjectDB::get_instance(_body_ref));
}
void GSAIKinematicBody2DAgent::set_ *body(const KinematicBody2D &val) {
*body = val;
void GSAIKinematicBody2DAgent::set_body(KinematicBody2D *value) {
if (!value) {
_body_ref = 0;
_physics_process_disconnect();
return;
}
_body_ref = value->get_instance_id();
_last_position = value->get_global_position();
last_orientation = value->get_rotation();
position = GSAIUtils::to_vector3(_last_position);
orientation = last_orientation;
if (!value->is_inside_tree()) {
value->connect("ready", this, "_physics_process_connect", varray(), CONNECT_ONESHOT);
} else {
_physics_process_connect();
}
}
void GSAIKinematicBody2DAgent::set_body_bind(Node *p_body) {
set_body(Object::cast_to<KinematicBody2D>(p_body));
}
int GSAIKinematicBody2DAgent::get_movement_type() const {
@ -17,184 +44,134 @@ void GSAIKinematicBody2DAgent::set_movement_type(const int val) {
movement_type = val;
}
Vector2 GSAIKinematicBody2DAgent::get__last_position() {
return _last_position;
}
void GSAIKinematicBody2DAgent::set__last_position(const Vector2 &val) {
_last_position = val;
}
Ref<WeakRef> GSAIKinematicBody2DAgent::get__body_ref() {
return _body_ref;
}
void GSAIKinematicBody2DAgent::set__body_ref(const Ref<WeakRef> &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() {
// warning-ignore:return_value_discarded;
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
}
// Moves the agent's `body` by target `acceleration`.;
// @tags - virtual;
void GSAIKinematicBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
void GSAIKinematicBody2DAgent::_apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta) {
applied_steering = true;
if (movement_type == MovementType.COLLIDE) {
_apply_collide_steering(acceleration.linear, delta);
KinematicBody2D *body = get_body();
if (!body || !body->is_inside_tree()) {
return;
}
else if (movement_type == MovementType.SLIDE) {
_apply_sliding_steering(acceleration.linear, delta);
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_paused()) {
return;
}
else {
_apply_position_steering(acceleration.linear, delta);
if (movement_type == COLLIDE) {
_apply_collide_steering(body, acceleration->get_linear(), delta);
} else if (movement_type == SLIDE) {
_apply_sliding_steering(body, acceleration->get_linear(), delta);
} else {
_apply_position_steering(body, acceleration->get_linear(), delta);
}
_apply_orientation_steering(acceleration.angular, delta);
_apply_orientation_steering(body, acceleration->get_angular(), delta);
}
void GSAIKinematicBody2DAgent::_apply_sliding_steering(const Vector3 &accel, const float delta) {
KinematicBody2D *_body = _body_ref.get_ref();
if (!_body) {
return;
}
if (!_body.is_inside_tree() || _body.get_tree().paused) {
return;
}
Vector2 velocity = GSAIUtils.to_vector2(linear_velocity + accel * delta).limit_length(linear_speed_max);
void GSAIKinematicBody2DAgent::_apply_sliding_steering(KinematicBody2D *body, const Vector3 &accel, const float delta) {
Vector2 velocity = GSAIUtils::to_vector2(linear_velocity + accel * delta).limit_length(linear_speed_max);
if (apply_linear_drag) {
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag_percentage);
velocity = velocity.linear_interpolate(Vector2(), linear_drag_percentage);
}
velocity = _body.move_and_slide(velocity);
velocity = body->move_and_slide(velocity);
if (calculate_velocities) {
linear_velocity = GSAIUtils.to_vector3(velocity);
linear_velocity = GSAIUtils::to_vector3(velocity);
}
}
void GSAIKinematicBody2DAgent::_apply_collide_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);
void GSAIKinematicBody2DAgent::_apply_collide_steering(KinematicBody2D *body, const Vector3 &accel, const float delta) {
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 = velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
// warning-ignore:return_value_discarded;
_body.move_and_collide(GSAIUtils.to_vector2(velocity) * delta);
KinematicBody2D::Collision col;
body->move_and_collide(GSAIUtils::to_vector2(velocity) * delta, true, col);
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);
void GSAIKinematicBody2DAgent::_apply_position_steering(KinematicBody2D *body, const Vector3 &accel, const float delta) {
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 = velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
_body.global_position += GSAIUtils.to_vector2(velocity) * delta;
Vector2 global_position = body->get_global_position();
global_position += GSAIUtils::to_vector2(velocity) * delta;
body->set_global_position(global_position);
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);
void GSAIKinematicBody2DAgent::_apply_orientation_steering(KinematicBody2D *body, const float angular_acceleration, const float delta) {
float velocity = CLAMP(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max);
if (apply_angular_drag) {
velocity = lerp(velocity, 0, angular_drag_percentage);
velocity = Math::lerp(velocity, 0, angular_drag_percentage);
}
_body.rotation += velocity * delta;
body->set_rotation(body->get_rotation() + velocity * delta);
if (calculate_velocities) {
angular_velocity = velocity;
}
}
void GSAIKinematicBody2DAgent::_set_body(const KinematicBody2D &value) {
bool had_body = false;
void GSAIKinematicBody2DAgent::_physics_process_connect() {
SceneTree *st = SceneTree::get_singleton();
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");
if (st) {
if (!st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->connect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
else {
_body_ready();
void GSAIKinematicBody2DAgent::_physics_process_disconnect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->disconnect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
void GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame() {
KinematicBody2D *_body = _body_ref.get_ref();
KinematicBody2D *body = get_body();
if (!_body) {
if (!body) {
call_deferred("_physics_process_disconnect");
return;
}
Vector2 current_position = _body.global_position;
float current_orientation = _body.rotation;
position = GSAIUtils.to_vector3(current_position);
if (!body->is_inside_tree()) {
return;
}
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_paused()) {
return;
}
Vector2 current_position = body->get_global_position();
float current_orientation = body->get_rotation();
position = GSAIUtils::to_vector3(current_position);
orientation = current_orientation;
if (calculate_velocities) {
@ -203,16 +180,16 @@ void GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame() {
}
else {
linear_velocity = GSAIUtils.clampedv3(GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max);
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);
linear_velocity = linear_velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
angular_velocity = clamp(last_orientation - current_orientation, -angular_speed_max, angular_speed_max);
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);
angular_velocity = Math::lerp(angular_velocity, 0, angular_drag_percentage);
}
_last_position = current_position;
@ -220,41 +197,26 @@ void GSAIKinematicBody2DAgent::_on_SceneTree_physics_frame() {
}
}
}
}
GSAIKinematicBody2DAgent::GSAIKinematicBody2DAgent() {
*body;
movement_type = MovementType.SLIDE;
_last_position = ;
_body_ref;
movement_type = SLIDE;
_body_ref = 0;
}
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::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_body"), &GSAIKinematicBody2DAgent::get_body);
ClassDB::bind_method(D_METHOD("set_body", "value"), &GSAIKinematicBody2DAgent::set_body_bind);
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("_physics_process_connect"), &GSAIKinematicBody2DAgent::_physics_process_connect);
ClassDB::bind_method(D_METHOD("_physics_process_disconnect"), &GSAIKinematicBody2DAgent::_physics_process_disconnect);
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);
}

View File

@ -1,36 +1,38 @@
#ifndef GSAI_KINEMATIC_BODY_2D_AGENT_H
#define GSAI_KINEMATIC_BODY_2D_AGENT_H
#include "gsai_specialized_agent.h"
class KinematicBody2D;
class GSAITargetAcceleration;
class GSAIKinematicBody2DAgent : public GSAISpecializedAgent {
GDCLASS(GSAIKinematicBody2DAgent, GSAISpecializedAgent);
public:
KinematicBody2D get_ *body();
void set_ *body(const KinematicBody2D &val);
KinematicBody2D *get_body();
void set_body(KinematicBody2D *p_body);
void set_body_bind(Node *p_body);
int get_movement_type() const;
void set_movement_type(const int val);
Vector2 get__last_position();
void set__last_position(const Vector2 &val);
Ref<WeakRef> get__body_ref();
void set__body_ref(const Ref<WeakRef> &val);
enum MovementType {
SLIDE,
COLLIDE,
POSITION
};
void _body_ready();
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
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 _physics_process_connect();
void _physics_process_disconnect();
void _apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta);
void _apply_sliding_steering(KinematicBody2D *body, const Vector3 &accel, const float delta);
void _apply_collide_steering(KinematicBody2D *body, const Vector3 &accel, const float delta);
void _apply_position_steering(KinematicBody2D *body, const Vector3 &accel, const float delta);
void _apply_orientation_steering(KinematicBody2D *body, const float angular_acceleration, const float delta);
void _on_SceneTree_physics_frame();
GSAIKinematicBody2DAgent();
@ -45,17 +47,15 @@ protected:
// 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
// The type of movement the body executes
int movement_type;
Vector2 _last_position;
ObjectID _body_ref;
// Moves the agent's `body` by target `acceleration`.
// @tags - virtual
};
// 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

View File

@ -1,12 +1,37 @@
#include "gsai_kinematic_body_3d_agent.h"
KinematicBody GSAIKinematicBody3DAgent::get_ *body() {
return *body;
#include "scene/3d/physics_body.h"
#include "../gsai_target_acceleration.h"
#include "../gsai_utils.h"
KinematicBody *GSAIKinematicBody3DAgent::get_body() {
return Object::cast_to<KinematicBody>(ObjectDB::get_instance(_body_ref));
}
void GSAIKinematicBody3DAgent::set_ *body(const KinematicBody &val) {
*body = val;
void GSAIKinematicBody3DAgent::set_body(KinematicBody *value) {
if (!value) {
_body_ref = 0;
_physics_process_disconnect();
return;
}
_body_ref = value->get_instance_id();
_last_position = value->get_transform().origin;
last_orientation = value->get_rotation().y;
position = _last_position;
orientation = last_orientation;
if (!value->is_inside_tree()) {
value->connect("ready", this, "_physics_process_connect", varray(), CONNECT_ONESHOT);
} else {
_physics_process_connect();
}
}
void GSAIKinematicBody3DAgent::set_body_bind(Node *p_body) {
set_body(Object::cast_to<KinematicBody>(p_body));
}
int GSAIKinematicBody3DAgent::get_movement_type() const {
@ -17,202 +42,144 @@ void GSAIKinematicBody3DAgent::set_movement_type(const int val) {
movement_type = val;
}
Vector3 GSAIKinematicBody3DAgent::get__last_position() {
return _last_position;
void GSAIKinematicBody3DAgent::_physics_process_connect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (!st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->connect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
void GSAIKinematicBody3DAgent::set__last_position(const Vector3 &val) {
_last_position = val;
void GSAIKinematicBody3DAgent::_physics_process_disconnect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->disconnect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
Ref<WeakRef> GSAIKinematicBody3DAgent::get__body_ref() {
return _body_ref;
}
void GSAIKinematicBody3DAgent::set__body_ref(const Ref<WeakRef> &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() {
// warning-ignore:return_value_discarded;
body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame");
}
// Moves the agent's `body` by target `acceleration`.;
// @tags - virtual;
void GSAIKinematicBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float delta) {
void GSAIKinematicBody3DAgent::_apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta) {
applied_steering = true;
if (movement_type == MovementType.COLLIDE) {
_apply_collide_steering(acceleration.linear, delta);
}
KinematicBody *body = get_body();
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();
if (!_body) {
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);
if (movement_type == COLLIDE) {
_apply_collide_steering(body, acceleration->get_linear(), delta);
} else if (movement_type == SLIDE) {
_apply_sliding_steering(body, acceleration->get_linear(), delta);
} else {
_apply_position_steering(body, acceleration->get_linear(), delta);
}
velocity = _body.move_and_slide(velocity);
_apply_orientation_steering(body, acceleration->get_angular(), delta);
}
void GSAIKinematicBody3DAgent::_apply_sliding_steering(KinematicBody *body, const Vector3 &accel, const float delta) {
Vector3 velocity = GSAIUtils::clampedv3(linear_velocity + accel * delta, linear_speed_max);
if (apply_linear_drag) {
velocity = velocity.linear_interpolate(Vector3(), 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();
if (!_body) {
return;
}
Vector3 velocity = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max);
void GSAIKinematicBody3DAgent::_apply_collide_steering(KinematicBody *body, const Vector3 &accel, const float delta) {
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 = velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
// warning-ignore:return_value_discarded;
_body.move_and_collide(velocity * delta);
KinematicBody::Collision coll;
body->move_and_collide(velocity * delta, true, coll);
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);
void GSAIKinematicBody3DAgent::_apply_position_steering(KinematicBody *body, const Vector3 &accel, const float delta) {
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 = velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
_body.global_transform.origin += velocity * delta;
body->get_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);
void GSAIKinematicBody3DAgent::_apply_orientation_steering(KinematicBody *body, const float angular_acceleration, const float delta) {
float velocity = CLAMP(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max);
if (apply_angular_drag) {
velocity = lerp(velocity, 0, angular_drag_percentage);
velocity = Math::lerp(velocity, 0, angular_drag_percentage);
}
_body.rotation.y += velocity * delta;
Vector3 rotation = body->get_rotation();
rotation.y += velocity * delta;
body->set_rotation(rotation);
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();
KinematicBody *body = get_body();
if (!_body) {
if (!body) {
call_deferred("_physics_process_disconnect");
return;
}
if (!_body.is_inside_tree() || _body.get_tree().paused) {
if (!body->is_inside_tree()) {
return;
}
Vector3 current_position = _body.transform.origin;
float current_orientation = _body.rotation.y;
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_paused()) {
return;
}
Vector3 current_position = body->get_transform().origin;
float current_orientation = body->get_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);
} 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);
linear_velocity = linear_velocity.linear_interpolate(Vector3(), linear_drag_percentage);
}
angular_velocity = clamp(last_orientation - current_orientation, -angular_speed_max, angular_speed_max);
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);
angular_velocity = Math::lerp(angular_velocity, 0, angular_drag_percentage);
}
_last_position = current_position;
@ -220,41 +187,26 @@ void GSAIKinematicBody3DAgent::_on_SceneTree_physics_frame() {
}
}
}
}
GSAIKinematicBody3DAgent::GSAIKinematicBody3DAgent() {
*body;
movement_type = 0;
_last_position = ;
_body_ref;
_body_ref = 0;
}
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");
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_bind);
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("_physics_process_connect"), &GSAIKinematicBody3DAgent::_physics_process_connect);
ClassDB::bind_method(D_METHOD("_physics_process_disconnect"), &GSAIKinematicBody3DAgent::_physics_process_disconnect);
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);
}

View File

@ -1,36 +1,38 @@
#ifndef GSAI_KINEMATIC_BODY_3D_AGENT_H
#define GSAI_KINEMATIC_BODY_3D_AGENT_H
#include "gsai_specialized_agent.h"
class KinematicBody;
class GSAITargetAcceleration;
class GSAIKinematicBody3DAgent : public GSAISpecializedAgent {
GDCLASS(GSAIKinematicBody3DAgent, GSAISpecializedAgent);
public:
KinematicBody get_ *body();
void set_ *body(const KinematicBody &val);
KinematicBody *get_body();
void set_body(KinematicBody *p_body);
void set_body_bind(Node *p_body);
int get_movement_type() const;
void set_movement_type(const int val);
Vector3 get__last_position();
void set__last_position(const Vector3 &val);
Ref<WeakRef> get__body_ref();
void set__body_ref(const Ref<WeakRef> &val);
enum MovementType {
SLIDE,
COLLIDE,
POSITION
};
void _body_ready();
void _apply_steering(const GSAITargetAcceleration &acceleration, const float delta);
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 _physics_process_connect();
void _physics_process_disconnect();
void _apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta);
void _apply_sliding_steering(KinematicBody *body, const Vector3 &accel, const float delta);
void _apply_collide_steering(KinematicBody *body, const Vector3 &accel, const float delta);
void _apply_position_steering(KinematicBody *body, const Vector3 &accel, const float delta);
void _apply_orientation_steering(KinematicBody *body, const float angular_acceleration, const float delta);
void _on_SceneTree_physics_frame();
GSAIKinematicBody3DAgent();
@ -45,17 +47,15 @@ protected:
// 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
// The type of movement the body executes
int movement_type;
Vector3 _last_position;
ObjectID _body_ref;
// Moves the agent's `body` by target `acceleration`.
// @tags - virtual
};
// 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

View File

@ -1,142 +1,123 @@
#include "gsai_rigid_body_2d_agent.h"
RigidBody2D GSAIRigidBody2DAgent::get_ *body() {
return *body;
#include "scene/2d/physics_body_2d.h"
#include "../gsai_target_acceleration.h"
#include "../gsai_utils.h"
RigidBody2D *GSAIRigidBody2DAgent::get_body() {
return Object::cast_to<RigidBody2D>(ObjectDB::get_instance(_body_ref));
}
void GSAIRigidBody2DAgent::set_ *body(const RigidBody2D &val) {
*body = val;
void GSAIRigidBody2DAgent::set_body(RigidBody2D *value) {
if (!value) {
_body_ref = 0;
_physics_process_disconnect();
return;
}
_body_ref = value->get_instance_id();
_last_position = value->get_global_position();
last_orientation = value->get_rotation();
position = GSAIUtils::to_vector3(_last_position);
orientation = last_orientation;
if (!value->is_inside_tree()) {
value->connect("ready", this, "_physics_process_connect", varray(), CONNECT_ONESHOT);
} else {
_physics_process_connect();
}
}
Vector2 GSAIRigidBody2DAgent::get__last_position() {
return _last_position;
void GSAIRigidBody2DAgent::set_body_bind(Node *p_body) {
set_body(Object::cast_to<RigidBody2D>(p_body));
}
void GSAIRigidBody2DAgent::set__last_position(const Vector2 &val) {
_last_position = val;
void GSAIRigidBody2DAgent::_physics_process_connect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (!st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->connect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
Ref<WeakRef> GSAIRigidBody2DAgent::get__body_ref() {
return _body_ref;
void GSAIRigidBody2DAgent::_physics_process_disconnect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->disconnect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
void GSAIRigidBody2DAgent::set__body_ref(const Ref<WeakRef> &val) {
_body_ref = val;
}
void GSAIRigidBody2DAgent::_apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta) {
RigidBody2D *body = get_body();
// 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() {
// warning-ignore:return_value_discarded;
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
}
// Moves the agent's `body` by target `acceleration`.;
// @tags - virtual;
void GSAIRigidBody2DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
RigidBody2D *_body = _body_ref.get_ref();
if (not _body) {
if (!body) {
return;
}
applied_steering = true;
_body.apply_central_impulse(GSAIUtils.to_vector2(acceleration.linear));
_body.apply_torque_impulse(acceleration.angular);
body->apply_central_impulse(GSAIUtils::to_vector2(acceleration->get_linear()));
body->apply_torque_impulse(acceleration->get_angular());
if (calculate_velocities) {
linear_velocity = GSAIUtils.to_vector3(_body.linear_velocity);
angular_velocity = _body.angular_velocity;
}
}
void GSAIRigidBody2DAgent::_set_body(const RigidBody2D &value) {
bool had_body = false;
if (body) {
had_body = true;
}
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();
}
linear_velocity = GSAIUtils::to_vector3(body->get_linear_velocity());
angular_velocity = body->get_angular_velocity();
}
}
void GSAIRigidBody2DAgent::_on_SceneTree_frame() {
RigidBody2D *_body = _body_ref.get_ref();
RigidBody2D *body = get_body();
if (!_body) {
if (!body) {
call_deferred("_physics_process_disconnect");
return;
}
if (!_body.is_inside_tree() || _body.get_tree().paused) {
if (!body->is_inside_tree()) {
return;
}
Vector2 current_position = _body.global_position;
float current_orientation = _body.rotation;
position = GSAIUtils.to_vector3(current_position);
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_paused()) {
return;
}
Vector2 current_position = body->get_global_position();
float current_orientation = body->get_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;
} else {
linear_velocity = GSAIUtils::to_vector3(body->get_linear_velocity());
angular_velocity = body->get_angular_velocity();
}
}
}
}
GSAIRigidBody2DAgent::GSAIRigidBody2DAgent() {
*body;
_last_position = ;
_body_ref;
_body_ref = 0;
}
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");
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_bind);
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("_physics_process_connect"), &GSAIRigidBody2DAgent::_physics_process_connect);
ClassDB::bind_method(D_METHOD("_physics_process_disconnect"), &GSAIRigidBody2DAgent::_physics_process_disconnect);
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);
}

View File

@ -1,22 +1,24 @@
#ifndef GSAI_RIGID_BODY_2D_AGENT_H
#define GSAI_RIGID_BODY_2D_AGENT_H
#include "gsai_specialized_agent.h"
class RigidBody2D;
class GSAITargetAcceleration;
class GSAIRigidBody2DAgent : public GSAISpecializedAgent {
GDCLASS(GSAIRigidBody2DAgent, GSAISpecializedAgent);
public:
RigidBody2D get_ *body();
void set_ *body(const RigidBody2D &val);
RigidBody2D *get_body();
void set_body(RigidBody2D *p_body);
void set_body_bind(Node *p_body);
Vector2 get__last_position();
void set__last_position(const Vector2 &val);
void _physics_process_connect();
void _physics_process_disconnect();
Ref<WeakRef> get__body_ref();
void set__body_ref(const Ref<WeakRef> &val);
void _apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta);
void _body_ready();
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
void _set_body(const RigidBody2D &value);
void _on_SceneTree_frame();
GSAIRigidBody2DAgent();
@ -30,9 +32,8 @@ protected:
// @category - Specialized agents
// The RigidBody2D to keep track of
// setget _set_body
RigidBody2D *body;
Vector2 _last_position = ;
Ref<WeakRef> _body_ref;
Vector2 _last_position;
ObjectID _body_ref;
// Moves the agent's `body` by target `acceleration`.
// @tags - virtual
};

View File

@ -1,142 +1,122 @@
#include "gsai_rigid_body_3d_agent.h"
RigidBody GSAIRigidBody3DAgent::get_ *body() {
return *body;
#include "scene/3d/physics_body.h"
#include "../gsai_target_acceleration.h"
RigidBody *GSAIRigidBody3DAgent::get_body() {
return Object::cast_to<RigidBody>(ObjectDB::get_instance(_body_ref));
}
void GSAIRigidBody3DAgent::set_ *body(const RigidBody &val) {
*body = val;
void GSAIRigidBody3DAgent::set_body(RigidBody *value) {
if (!value) {
_body_ref = 0;
_physics_process_disconnect();
return;
}
_body_ref = value->get_instance_id();
_last_position = value->get_transform().origin;
last_orientation = value->get_rotation().y;
position = _last_position;
orientation = last_orientation;
if (!value->is_inside_tree()) {
value->connect("ready", this, "_physics_process_connect", varray(), CONNECT_ONESHOT);
} else {
_physics_process_connect();
}
}
Vector3 GSAIRigidBody3DAgent::get__last_position() {
return _last_position;
void GSAIRigidBody3DAgent::set_body_bind(Node *p_body) {
set_body(Object::cast_to<RigidBody>(p_body));
}
void GSAIRigidBody3DAgent::set__last_position(const Vector3 &val) {
_last_position = val;
void GSAIRigidBody3DAgent::_physics_process_connect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (!st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->connect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
Ref<WeakRef> GSAIRigidBody3DAgent::get__body_ref() {
return _body_ref;
void GSAIRigidBody3DAgent::_physics_process_disconnect() {
SceneTree *st = SceneTree::get_singleton();
if (st) {
if (st->is_connected("physics_frame", this, "_on_SceneTree_physics_frame")) {
st->disconnect("physics_frame", this, "_on_SceneTree_physics_frame");
}
}
}
void GSAIRigidBody3DAgent::set__body_ref(const Ref<WeakRef> &val) {
_body_ref = val;
}
void GSAIRigidBody3DAgent::_apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta) {
RigidBody *body = get_body();
// 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() {
// warning-ignore:return_value_discarded;
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame");
}
// Moves the agent's `body` by target `acceleration`.;
// @tags - virtual;
void GSAIRigidBody3DAgent::_apply_steering(const GSAITargetAcceleration &acceleration, const float _delta) {
RigidBody *_body = _body_ref.get_ref();
if (!_body) {
if (!body || !body->is_inside_tree()) {
return;
}
applied_steering = true;
_body.apply_central_impulse(acceleration.linear);
_body.apply_torque_impulse(Vector3.UP * acceleration.angular);
body->apply_central_impulse(acceleration->get_linear());
body->apply_torque_impulse(Vector3(0, 1, 0) * acceleration->get_angular());
if (calculate_velocities) {
linear_velocity = _body.linear_velocity;
angular_velocity = _body.angular_velocity.y;
}
}
void GSAIRigidBody3DAgent::_set_body(const RigidBody &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();
}
linear_velocity = body->get_linear_velocity();
angular_velocity = body->get_angular_velocity().y;
}
}
void GSAIRigidBody3DAgent::_on_SceneTree_frame() {
RigidBody *_body = _body_ref.get_ref();
RigidBody *body = get_body();
if (not _body) {
if (!body) {
call_deferred("_physics_process_disconnect");
return;
}
if (not _body.is_inside_tree() || _body.get_tree().paused) {
if (!body->is_inside_tree()) {
return;
}
Vector3 current_position = _body.transform.origin;
float current_orientation = _body.rotation.y;
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_paused()) {
return;
}
Vector3 current_position = body->get_transform().origin;
float current_orientation = body->get_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;
} else {
linear_velocity = body->get_linear_velocity();
angular_velocity = body->get_angular_velocity().y;
}
}
}
}
GSAIRigidBody3DAgent::GSAIRigidBody3DAgent() {
*body;
_last_position = ;
_body_ref;
_body_ref = 0;
}
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");
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_bind);
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("_physics_process_connect"), &GSAIRigidBody3DAgent::_physics_process_connect);
ClassDB::bind_method(D_METHOD("_physics_process_disconnect"), &GSAIRigidBody3DAgent::_physics_process_disconnect);
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);
}

View File

@ -1,22 +1,24 @@
#ifndef GSAI_RIGID_BODY_3D_AGENT_H
#define GSAI_RIGID_BODY_3D_AGENT_H
#include "gsai_specialized_agent.h"
class RigidBody;
class GSAITargetAcceleration;
class GSAIRigidBody3DAgent : public GSAISpecializedAgent {
GDCLASS(GSAIRigidBody3DAgent, GSAISpecializedAgent);
public:
RigidBody get_ *body();
void set_ *body(const RigidBody &val);
RigidBody *get_body();
void set_body(RigidBody *p_body);
void set_body_bind(Node *p_body);
Vector3 get__last_position();
void set__last_position(const Vector3 &val);
void _physics_process_connect();
void _physics_process_disconnect();
Ref<WeakRef> get__body_ref();
void set__body_ref(const Ref<WeakRef> &val);
void _apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta);
void _body_ready();
void _apply_steering(const GSAITargetAcceleration &acceleration, const float _delta);
void _set_body(const RigidBody &value);
void _on_SceneTree_frame();
GSAIRigidBody3DAgent();
@ -30,9 +32,8 @@ protected:
// @category - Specialized agents
// The RigidBody to keep track of
// setget _set_body
RigidBody *body;
Vector3 _last_position = ;
Ref<WeakRef> _body_ref;
Vector3 _last_position;
ObjectID _body_ref;
// Moves the agent's `body` by target `acceleration`.
// @tags - virtual
};

View File

@ -1,5 +1,7 @@
#include "gsai_specialize_dagent.h"
#include "gsai_specialized_agent.h"
#include "../gsai_target_acceleration.h"
bool GSAISpecializedAgent::get_calculate_velocities() const {
return calculate_velocities;
@ -57,42 +59,11 @@ void GSAISpecializedAgent::set_applied_steering(const bool 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) {
call("_apply_steering", _acceleration, _delta);
void GSAISpecializedAgent::apply_steering(const Ref<GSAITargetAcceleration> &acceleration, const float delta) {
call("_apply_steering", acceleration, delta);
}
// Moves the agent's body by target `acceleration`.;
// @tags - virtual;
void GSAISpecializedAgent::_apply_steering(const GSAITargetAcceleration &_acceleration, const float _delta) {
pass;
}
void GSAISpecializedAgent::_apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta) {
}
GSAISpecializedAgent::GSAISpecializedAgent() {
@ -108,7 +79,7 @@ GSAISpecializedAgent::GSAISpecializedAgent() {
GSAISpecializedAgent::~GSAISpecializedAgent() {
}
static void GSAISpecializedAgent::_bind_methods() {
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");
@ -137,6 +108,7 @@ static void GSAISpecializedAgent::_bind_methods() {
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);
BIND_VMETHOD(MethodInfo("_apply_steering", PropertyInfo(Variant::OBJECT, "acceleration", PROPERTY_HINT_RESOURCE_TYPE, "GSAITargetAcceleration"), PropertyInfo(Variant::REAL, "delta")));
ClassDB::bind_method(D_METHOD("apply_steering", "acceleration", "delta"), &GSAISpecializedAgent::apply_steering);
ClassDB::bind_method(D_METHOD("_apply_steering", "acceleration", "delta"), &GSAISpecializedAgent::_apply_steering);
}

View File

@ -1,6 +1,12 @@
#ifndef GSAI_SPECIALIZED_AGENT_H
#define GSAI_SPECIALIZED_AGENT_H
#include "core/object/reference.h"
#include "../gsai_steering_agent.h"
class GSAITargetAcceleration;
class GSAISpecializedAgent : public GSAISteeringAgent {
GDCLASS(GSAISpecializedAgent, GSAISteeringAgent);
@ -26,8 +32,8 @@ public:
bool get_applied_steering() const;
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);
void apply_steering(const Ref<GSAITargetAcceleration> &acceleration, const float delta);
virtual void _apply_steering(Ref<GSAITargetAcceleration> acceleration, float delta);
GSAISpecializedAgent();
~GSAISpecializedAgent();
@ -41,25 +47,25 @@ protected:
// @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;
bool calculate_velocities;
// 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;
bool apply_linear_drag;
// 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;
bool apply_angular_drag;
// 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;
float linear_drag_percentage;
// 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;
float angular_drag_percentage;
float last_orientation;
bool applied_steering;
// Moves the agent's body by target `acceleration`.
// @tags - virtual
};

View File

@ -33,6 +33,12 @@ def get_doc_classes():
"GSAIPursue",
"GSAISeek",
"GSAISeparation",
"GSAIKinematicBody2DAgent",
"GSAIKinematicBody3DAgent",
"GSAIRigidBody2DAgent",
"GSAIRigidBody3DAgent",
"GSAISpecializedAgent",
]
def get_doc_path():

View File

@ -53,6 +53,12 @@ SOFTWARE.
#include "behaviors/gsai_seek.cpp"
#include "behaviors/gsai_separation.cpp"
#include "agents/gsai_kinematic_body_2d_agent.cpp"
#include "agents/gsai_kinematic_body_3d_agent.cpp"
#include "agents/gsai_rigid_body_2d_agent.cpp"
#include "agents/gsai_rigid_body_3d_agent.cpp"
#include "agents/gsai_specialized_agent.cpp"
static GSAIUtils *gs_ai_utils = NULL;
void register_steering_ai_types() {
@ -85,6 +91,12 @@ void register_steering_ai_types() {
ClassDB::register_class<GSAIPursue>();
ClassDB::register_class<GSAISeek>();
ClassDB::register_class<GSAISeparation>();
ClassDB::register_class<GSAIKinematicBody2DAgent>();
ClassDB::register_class<GSAIKinematicBody3DAgent>();
ClassDB::register_class<GSAIRigidBody2DAgent>();
ClassDB::register_class<GSAIRigidBody3DAgent>();
ClassDB::register_class<GSAISpecializedAgent>();
}
void unregister_steering_ai_types() {