diff --git a/modules/steering_ai/SCsub b/modules/steering_ai/SCsub index aeed6ae26..8dae0788f 100644 --- a/modules/steering_ai/SCsub +++ b/modules/steering_ai/SCsub @@ -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", ] diff --git a/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.cpp b/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.cpp index da563bd20..1a1dee1e3 100644 --- a/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.cpp +++ b/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.cpp @@ -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(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(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 GSAIKinematicBody2DAgent::get__body_ref() { - return _body_ref; -} - -void GSAIKinematicBody2DAgent::set__body_ref(const 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 _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 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"), "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); } diff --git a/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.h b/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.h index 0fd76a562..3dcb297c7 100644 --- a/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.h +++ b/modules/steering_ai/agents/gsai_kinematic_body_2d_agent.h @@ -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 get__body_ref(); - void set__body_ref(const Ref &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 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 _body_ref; -// Moves the agent's `body` by target `acceleration`. -// @tags - virtual -} -; #endif diff --git a/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.cpp b/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.cpp index ccf0ae734..625d34518 100644 --- a/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.cpp +++ b/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.cpp @@ -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(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(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 GSAIKinematicBody3DAgent::get__body_ref() { - return _body_ref; -} - -void GSAIKinematicBody3DAgent::set__body_ref(const 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 _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 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"), "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); } diff --git a/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.h b/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.h index 899b86a22..20f41eef8 100644 --- a/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.h +++ b/modules/steering_ai/agents/gsai_kinematic_body_3d_agent.h @@ -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 get__body_ref(); - void set__body_ref(const Ref &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 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 _body_ref; -// Moves the agent's `body` by target `acceleration`. -// @tags - virtual -} -; #endif diff --git a/modules/steering_ai/agents/gsai_rigid_body_2d_agent.cpp b/modules/steering_ai/agents/gsai_rigid_body_2d_agent.cpp index d5179d1f3..288207b3f 100644 --- a/modules/steering_ai/agents/gsai_rigid_body_2d_agent.cpp +++ b/modules/steering_ai/agents/gsai_rigid_body_2d_agent.cpp @@ -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(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(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 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 &val) { - _body_ref = val; -} +void GSAIRigidBody2DAgent::_apply_steering(Ref 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 _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"), "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); } diff --git a/modules/steering_ai/agents/gsai_rigid_body_2d_agent.h b/modules/steering_ai/agents/gsai_rigid_body_2d_agent.h index 11969a32e..2517032e0 100644 --- a/modules/steering_ai/agents/gsai_rigid_body_2d_agent.h +++ b/modules/steering_ai/agents/gsai_rigid_body_2d_agent.h @@ -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 get__body_ref(); - void set__body_ref(const Ref &val); + void _apply_steering(Ref 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 _body_ref; + Vector2 _last_position; + ObjectID _body_ref; // Moves the agent's `body` by target `acceleration`. // @tags - virtual }; diff --git a/modules/steering_ai/agents/gsai_rigid_body_3d_agent.cpp b/modules/steering_ai/agents/gsai_rigid_body_3d_agent.cpp index 59b28a9de..e2dfae918 100644 --- a/modules/steering_ai/agents/gsai_rigid_body_3d_agent.cpp +++ b/modules/steering_ai/agents/gsai_rigid_body_3d_agent.cpp @@ -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(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(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 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 &val) { - _body_ref = val; -} +void GSAIRigidBody3DAgent::_apply_steering(Ref 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 _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"), "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); } diff --git a/modules/steering_ai/agents/gsai_rigid_body_3d_agent.h b/modules/steering_ai/agents/gsai_rigid_body_3d_agent.h index ce2988515..207a374d8 100644 --- a/modules/steering_ai/agents/gsai_rigid_body_3d_agent.h +++ b/modules/steering_ai/agents/gsai_rigid_body_3d_agent.h @@ -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 get__body_ref(); - void set__body_ref(const Ref &val); + void _apply_steering(Ref 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 _body_ref; + Vector3 _last_position; + ObjectID _body_ref; // Moves the agent's `body` by target `acceleration`. // @tags - virtual }; diff --git a/modules/steering_ai/agents/gsai_specialized_agent.cpp b/modules/steering_ai/agents/gsai_specialized_agent.cpp index dbd97603c..37092be1a 100644 --- a/modules/steering_ai/agents/gsai_specialized_agent.cpp +++ b/modules/steering_ai/agents/gsai_specialized_agent.cpp @@ -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 &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 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); } diff --git a/modules/steering_ai/agents/gsai_specialized_agent.h b/modules/steering_ai/agents/gsai_specialized_agent.h index f68cde820..e47b037fd 100644 --- a/modules/steering_ai/agents/gsai_specialized_agent.h +++ b/modules/steering_ai/agents/gsai_specialized_agent.h @@ -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 &acceleration, const float delta); + virtual void _apply_steering(Ref 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 }; diff --git a/modules/steering_ai/config.py b/modules/steering_ai/config.py index 6481b0b0b..5510ae6a4 100644 --- a/modules/steering_ai/config.py +++ b/modules/steering_ai/config.py @@ -33,6 +33,12 @@ def get_doc_classes(): "GSAIPursue", "GSAISeek", "GSAISeparation", + + "GSAIKinematicBody2DAgent", + "GSAIKinematicBody3DAgent", + "GSAIRigidBody2DAgent", + "GSAIRigidBody3DAgent", + "GSAISpecializedAgent", ] def get_doc_path(): diff --git a/modules/steering_ai/register_types.cpp b/modules/steering_ai/register_types.cpp index b0d2e36a4..f0b374feb 100644 --- a/modules/steering_ai/register_types.cpp +++ b/modules/steering_ai/register_types.cpp @@ -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(); ClassDB::register_class(); ClassDB::register_class(); + + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); } void unregister_steering_ai_types() {