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;