From c89476ad4127c725f810644dca7736b0edb92289 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Fri, 2 Jul 2021 18:04:39 -0700 Subject: [PATCH] Expose body_test_motion in 3D physics server Results are exposed through PhysicsTestMotionResult, the same way it's done for 2D. Also cleaned a few things in the 2D version. --- doc/classes/PhysicsServer.xml | 17 +++++ doc/classes/PhysicsTestMotionResult.xml | 33 +++++++++ servers/physics_2d/physics_2d_server_sw.h | 4 +- .../physics_2d/physics_2d_server_wrap_mt.h | 4 +- servers/physics_2d_server.cpp | 11 ++- servers/physics_2d_server.h | 20 ++---- servers/physics_server.cpp | 70 +++++++++++++++++++ servers/physics_server.h | 41 ++++++++--- servers/register_server_types.cpp | 1 + 9 files changed, 169 insertions(+), 32 deletions(-) create mode 100644 doc/classes/PhysicsTestMotionResult.xml diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index 78915bd243d3..411ca2d62515 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -815,6 +815,23 @@ Sets a body state (see [enum BodyState] constants). + + + + + + + + + + + + + + + Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. [PhysicsTestMotionResult] can be passed to return additional information in. + + diff --git a/doc/classes/PhysicsTestMotionResult.xml b/doc/classes/PhysicsTestMotionResult.xml new file mode 100644 index 000000000000..107778d73c2e --- /dev/null +++ b/doc/classes/PhysicsTestMotionResult.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 1d64c02dff8c..6ab6459f5b8a 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -246,8 +246,8 @@ class Physics2DServerSW : public Physics2DServer { virtual void body_set_pickable(RID p_body, bool p_pickable); - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true); - virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001); + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true); + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.08); // this function only works on physics process, errors and returns null otherwise virtual Physics2DDirectBodyState *body_get_direct_state(RID p_body); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index d2deed5db66e..f11ed99db29d 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -251,12 +251,12 @@ class Physics2DServerWrapMT : public Physics2DServer { FUNC2(body_set_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { + bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } - int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) { + int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.08) { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index bece24c0e738..de830d9a2ddc 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -438,6 +438,7 @@ void Physics2DShapeQueryResult::_bind_methods() { Vector2 Physics2DTestMotionResult::get_motion() const { return result.motion; } + Vector2 Physics2DTestMotionResult::get_motion_remainder() const { return result.remainder; } @@ -445,15 +446,19 @@ Vector2 Physics2DTestMotionResult::get_motion_remainder() const { Vector2 Physics2DTestMotionResult::get_collision_point() const { return result.collision_point; } + Vector2 Physics2DTestMotionResult::get_collision_normal() const { return result.collision_normal; } + Vector2 Physics2DTestMotionResult::get_collider_velocity() const { return result.collider_velocity; } + ObjectID Physics2DTestMotionResult::get_collider_id() const { return result.collider_id; } + RID Physics2DTestMotionResult::get_collider_rid() const { return result.collider; } @@ -488,12 +493,6 @@ void Physics2DTestMotionResult::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape"); } -Physics2DTestMotionResult::Physics2DTestMotionResult() { - colliding = false; - result.collider_id = 0; - result.collider_shape = 0; -} - /////////////////////////////////////// bool Physics2DServer::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref &p_result) { diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 97c76b7c84fd..1241e6a4e41b 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -491,20 +491,14 @@ class Physics2DServer : public Object { Vector2 collision_point; Vector2 collision_normal; Vector2 collider_velocity; - int collision_local_shape; - ObjectID collider_id; + int collision_local_shape = 0; + ObjectID collider_id = 0; RID collider; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; - - MotionResult() { - collision_local_shape = 0; - collider_shape = 0; - collider_id = 0; - } }; - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { float collision_depth; @@ -518,7 +512,7 @@ class Physics2DServer : public Object { Variant collider_metadata; }; - virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0; + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.08) = 0; /* JOINT API */ @@ -602,7 +596,7 @@ class Physics2DTestMotionResult : public Reference { GDCLASS(Physics2DTestMotionResult, Reference); Physics2DServer::MotionResult result; - bool colliding; + bool colliding = false; friend class Physics2DServer; protected: @@ -622,8 +616,6 @@ class Physics2DTestMotionResult : public Reference { RID get_collider_rid() const; Object *get_collider() const; int get_collider_shape() const; - - Physics2DTestMotionResult(); }; typedef Physics2DServer *(*CreatePhysics2DServerCallback)(); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index f1cf446753dd..a13d61dc69b8 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -381,8 +381,76 @@ void PhysicsShapeQueryResult::_bind_methods() { ClassDB::bind_method(D_METHOD("get_result_object_shape", "idx"), &PhysicsShapeQueryResult::get_result_object_shape); } +/////////////////////////////// + +Vector3 PhysicsTestMotionResult::get_motion() const { + return result.motion; +} + +Vector3 PhysicsTestMotionResult::get_motion_remainder() const { + return result.remainder; +} + +Vector3 PhysicsTestMotionResult::get_collision_point() const { + return result.collision_point; +} + +Vector3 PhysicsTestMotionResult::get_collision_normal() const { + return result.collision_normal; +} + +Vector3 PhysicsTestMotionResult::get_collider_velocity() const { + return result.collider_velocity; +} + +ObjectID PhysicsTestMotionResult::get_collider_id() const { + return result.collider_id; +} + +RID PhysicsTestMotionResult::get_collider_rid() const { + return result.collider; +} + +Object *PhysicsTestMotionResult::get_collider() const { + return ObjectDB::get_instance(result.collider_id); +} + +int PhysicsTestMotionResult::get_collider_shape() const { + return result.collider_shape; +} + +void PhysicsTestMotionResult::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionResult::get_motion); + ClassDB::bind_method(D_METHOD("get_motion_remainder"), &PhysicsTestMotionResult::get_motion_remainder); + ClassDB::bind_method(D_METHOD("get_collision_point"), &PhysicsTestMotionResult::get_collision_point); + ClassDB::bind_method(D_METHOD("get_collision_normal"), &PhysicsTestMotionResult::get_collision_normal); + ClassDB::bind_method(D_METHOD("get_collider_velocity"), &PhysicsTestMotionResult::get_collider_velocity); + ClassDB::bind_method(D_METHOD("get_collider_id"), &PhysicsTestMotionResult::get_collider_id); + ClassDB::bind_method(D_METHOD("get_collider_rid"), &PhysicsTestMotionResult::get_collider_rid); + ClassDB::bind_method(D_METHOD("get_collider"), &PhysicsTestMotionResult::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_shape"), &PhysicsTestMotionResult::get_collider_shape); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion"), "", "get_motion"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_remainder"), "", "get_motion_remainder"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collision_point"), "", "get_collision_point"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collision_normal"), "", "get_collision_normal"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id", PROPERTY_HINT_OBJECT_ID), "", "get_collider_id"); + ADD_PROPERTY(PropertyInfo(Variant::_RID, "collider_rid"), "", "get_collider_rid"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape"); +} + /////////////////////////////////////// +bool PhysicsServer::_body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, const Ref &p_result) { + MotionResult *r = nullptr; + if (p_result.is_valid()) { + r = p_result->get_result_ptr(); + } + return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, r); +} + void PhysicsServer::_bind_methods() { #ifndef _3D_DISABLED @@ -504,6 +572,8 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer::body_set_ray_pickable); ClassDB::bind_method(D_METHOD("body_is_ray_pickable", "body"), &PhysicsServer::body_is_ray_pickable); + ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "result"), &PhysicsServer::_body_test_motion, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer::body_get_direct_state); /* JOINT API */ diff --git a/servers/physics_server.h b/servers/physics_server.h index 290aef35f382..5740c821f7af 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -214,11 +214,15 @@ class PhysicsShapeQueryResult : public Reference { PhysicsShapeQueryResult(); }; +class PhysicsTestMotionResult; + class PhysicsServer : public Object { GDCLASS(PhysicsServer, Object); static PhysicsServer *singleton; + virtual bool _body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, const Ref &p_result = Ref()); + protected: static void _bind_methods(); @@ -479,16 +483,11 @@ class PhysicsServer : public Object { Vector3 collision_point; Vector3 collision_normal; Vector3 collider_velocity; - int collision_local_shape; - ObjectID collider_id; + int collision_local_shape = 0; + ObjectID collider_id = 0; RID collider; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; - MotionResult() { - collision_local_shape = 0; - collider_id = 0; - collider_shape = 0; - } }; virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; @@ -762,6 +761,32 @@ class PhysicsServer : public Object { ~PhysicsServer(); }; +class PhysicsTestMotionResult : public Reference { + GDCLASS(PhysicsTestMotionResult, Reference); + + PhysicsServer::MotionResult result; + bool colliding = false; + friend class PhysicsServer; + +protected: + static void _bind_methods(); + +public: + PhysicsServer::MotionResult *get_result_ptr() const { return const_cast(&result); } + + //bool is_colliding() const; + Vector3 get_motion() const; + Vector3 get_motion_remainder() const; + + Vector3 get_collision_point() const; + Vector3 get_collision_normal() const; + Vector3 get_collider_velocity() const; + ObjectID get_collider_id() const; + RID get_collider_rid() const; + Object *get_collider() const; + int get_collider_shape() const; +}; + typedef PhysicsServer *(*CreatePhysicsServerCallback)(); class PhysicsServerManager { diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 00cfb66cc854..cd4d39cd4bb3 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -183,6 +183,7 @@ void register_server_types() { ClassDB::register_virtual_class(); ClassDB::register_virtual_class(); ClassDB::register_virtual_class(); + ClassDB::register_class(); ScriptDebuggerRemote::resource_usage_func = _debugger_get_resource_usage;