From 4f8d761be632a9d342655aa88a0745465b2177b8 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Thu, 30 Sep 2021 11:05:30 -0700 Subject: Fix physics glitch with TileMap moving platforms Added a parameter in test_body_motion to exclude attached objects from collision, used to avoid collision with all TileMap tiles with moving platform motion instead of just the one tile the character touches. Same changes made in 3D for consistency, and handling potential similar cases. --- servers/physics_2d/space_2d_sw.cpp | 9 +++++++++ servers/physics_3d/space_3d_sw.cpp | 10 ++++++++++ servers/physics_server_2d.cpp | 24 ++++++++++++++++++++++++ servers/physics_server_2d.h | 4 ++++ servers/physics_server_3d.cpp | 24 ++++++++++++++++++++++++ servers/physics_server_3d.h | 4 ++++ 6 files changed, 75 insertions(+) (limited to 'servers') diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 5e25d7f7c4..dd0780b5ff 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -615,6 +615,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } int shape_idx = intersection_query_subindex_results[i]; @@ -747,6 +750,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } int col_shape_idx = intersection_query_subindex_results[i]; Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx); @@ -896,6 +902,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const PhysicsServer2D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } int shape_idx = intersection_query_subindex_results[i]; diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index f5f497e167..c88747c017 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -704,6 +704,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } int shape_idx = intersection_query_subindex_results[i]; @@ -795,6 +798,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } int shape_idx = intersection_query_subindex_results[i]; @@ -916,6 +922,10 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const PhysicsServer3D::Motion if (p_parameters.exclude_bodies.has(col_obj->get_self())) { continue; } + if (p_parameters.exclude_objects.has(col_obj->get_instance_id())) { + continue; + } + int shape_idx = intersection_query_subindex_results[i]; rcd.object = col_obj; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index ad53f9ed20..fe2970912a 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -430,6 +430,26 @@ void PhysicsTestMotionParameters2D::set_exclude_bodies(const Vector &p_excl } } +Array PhysicsTestMotionParameters2D::get_exclude_objects() const { + Array exclude; + exclude.resize(parameters.exclude_objects.size()); + + int object_index = 0; + for (ObjectID object_id : parameters.exclude_objects) { + exclude[object_index++] = object_id; + } + + return exclude; +} + +void PhysicsTestMotionParameters2D::set_exclude_objects(const Array &p_exclude) { + for (int i = 0; i < p_exclude.size(); ++i) { + ObjectID object_id = p_exclude[i]; + ERR_CONTINUE(object_id.is_null()); + parameters.exclude_objects.insert(object_id); + } +} + void PhysicsTestMotionParameters2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_from"), &PhysicsTestMotionParameters2D::get_from); ClassDB::bind_method(D_METHOD("set_from"), &PhysicsTestMotionParameters2D::set_from); @@ -446,11 +466,15 @@ void PhysicsTestMotionParameters2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_exclude_bodies"), &PhysicsTestMotionParameters2D::get_exclude_bodies); ClassDB::bind_method(D_METHOD("set_exclude_bodies"), &PhysicsTestMotionParameters2D::set_exclude_bodies); + ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters2D::get_exclude_objects); + ClassDB::bind_method(D_METHOD("set_exclude_objects"), &PhysicsTestMotionParameters2D::set_exclude_objects); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "from"), "set_from", "get_from"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies"), "set_exclude_bodies", "get_exclude_bodies"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); } /////////////////////////////// diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 1028be05b7..26e1411111 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -472,6 +472,7 @@ public: real_t margin = 0.08; bool collide_separation_ray = false; Set exclude_bodies; + Set exclude_objects; MotionParameters() {} @@ -609,6 +610,9 @@ public: Vector get_exclude_bodies() const; void set_exclude_bodies(const Vector &p_exclude); + + Array get_exclude_objects() const; + void set_exclude_objects(const Array &p_exclude); }; class PhysicsTestMotionResult2D : public RefCounted { diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 1b47eba134..d66a8bfe0d 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -380,6 +380,26 @@ void PhysicsTestMotionParameters3D::set_exclude_bodies(const Vector &p_excl } } +Array PhysicsTestMotionParameters3D::get_exclude_objects() const { + Array exclude; + exclude.resize(parameters.exclude_objects.size()); + + int object_index = 0; + for (ObjectID object_id : parameters.exclude_objects) { + exclude[object_index++] = object_id; + } + + return exclude; +} + +void PhysicsTestMotionParameters3D::set_exclude_objects(const Array &p_exclude) { + for (int i = 0; i < p_exclude.size(); ++i) { + ObjectID object_id = p_exclude[i]; + ERR_CONTINUE(object_id.is_null()); + parameters.exclude_objects.insert(object_id); + } +} + void PhysicsTestMotionParameters3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_from"), &PhysicsTestMotionParameters3D::get_from); ClassDB::bind_method(D_METHOD("set_from"), &PhysicsTestMotionParameters3D::set_from); @@ -399,12 +419,16 @@ void PhysicsTestMotionParameters3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_exclude_bodies"), &PhysicsTestMotionParameters3D::get_exclude_bodies); ClassDB::bind_method(D_METHOD("set_exclude_bodies"), &PhysicsTestMotionParameters3D::set_exclude_bodies); + ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters3D::get_exclude_objects); + ClassDB::bind_method(D_METHOD("set_exclude_objects"), &PhysicsTestMotionParameters3D::set_exclude_objects); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "from"), "set_from", "get_from"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_collisions"), "set_max_collisions", "get_max_collisions"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies"), "set_exclude_bodies", "get_exclude_bodies"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); } /////////////////////////////// diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 3d884de095..c609afc11e 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -491,6 +491,7 @@ public: int max_collisions = 1; bool collide_separation_ray = false; Set exclude_bodies; + Set exclude_objects; MotionParameters() {} @@ -805,6 +806,9 @@ public: Vector get_exclude_bodies() const; void set_exclude_bodies(const Vector &p_exclude); + + Array get_exclude_objects() const; + void set_exclude_objects(const Array &p_exclude); }; class PhysicsTestMotionResult3D : public RefCounted { -- cgit v1.2.3