diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml index 6a3b29183529..4e2bd6774bb2 100644 --- a/doc/classes/Physics2DServer.xml +++ b/doc/classes/Physics2DServer.xml @@ -832,8 +832,6 @@ Constant to set/get the default solver bias for all physics constraints. A solver bias is a factor controlling how much two objects "rebound", after violating a constraint, to avoid leaving them in that state because of numerical imprecision. - - This is the constant for creating line shapes. A line shape is an infinite line with an origin point, and a normal. Thus, it can be used for front/behind checks. diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index d017acf2f926..fdcd90a8359d 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -1297,8 +1297,6 @@ Constant to set/get the default solver bias for all physics constraints. A solver bias is a factor controlling how much two objects "rebound", after violating a constraint, to avoid leaving them in that state because of numerical imprecision. - - diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 7ecc153a94a6..cde11f7fec1a 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -34,6 +34,8 @@ #include "core/project_settings.h" #include "physics_server_sw.h" +#define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05 + _FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; @@ -432,6 +434,8 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_ ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); + real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; + AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); @@ -441,7 +445,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_ rcd.best_len = 0; rcd.best_object = nullptr; rcd.best_shape = 0; - rcd.min_allowed_depth = space->test_motion_min_contact_depth; + rcd.min_allowed_depth = min_contact_depth; for (int i = 0; i < amount; i++) { if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { @@ -753,6 +757,8 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb)); body_aabb = body_aabb.grow(p_margin); + real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; + float motion_length = p_motion.length(); Vector3 motion_normal = p_motion / motion_length; @@ -815,8 +821,9 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve break; } - Vector3 recover_motion; + recovered = true; + Vector3 recover_motion; for (int i = 0; i < cbk.amount; i++) { Vector3 a = sr[i * 2 + 0]; Vector3 b = sr[i * 2 + 1]; @@ -827,9 +834,9 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve // Compute depth on recovered motion. float depth = n.dot(a + recover_motion) - d; - if (depth > 0.0) { + if (depth > min_contact_depth + CMP_EPSILON) { // Only recover if there is penetration. - recover_motion -= n * depth * 0.4; + recover_motion -= n * (depth - min_contact_depth) * 0.4; } } @@ -838,8 +845,6 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve break; } - recovered = true; - body_transform.origin += recover_motion; body_aabb.position += recover_motion; @@ -991,7 +996,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve rcd.best_shape = 0; // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. - rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth); + rcd.min_allowed_depth = MIN(motion_length, min_contact_depth); int from_shape = best_shape != -1 ? best_shape : 0; int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); @@ -1233,9 +1238,6 @@ void SpaceSW::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) { case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break; - case PhysicsServer::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: - test_motion_min_contact_depth = p_value; - break; } } @@ -1257,8 +1259,6 @@ real_t SpaceSW::get_param(PhysicsServer::SpaceParameter p_param) const { return body_angular_velocity_damp_ratio; case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; - case PhysicsServer::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: - return test_motion_min_contact_depth; } return 0; } @@ -1289,7 +1289,6 @@ SpaceSW::SpaceSW() { contact_recycle_radius = 0.01; contact_max_separation = 0.05; contact_max_allowed_penetration = 0.01; - test_motion_min_contact_depth = 0.00001; constraint_bias = 0.01; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1); diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index 6bbd3b9dd29d..6a0f7ed55234 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -94,7 +94,6 @@ class SpaceSW : public RID_Data { real_t contact_max_separation; real_t contact_max_allowed_penetration; real_t constraint_bias; - real_t test_motion_min_contact_depth; enum { diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 8756477350c2..85045d707aa3 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -34,6 +34,9 @@ #include "core/os/os.h" #include "core/pair.h" #include "physics_2d_server_sw.h" + +#define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05 + _FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; @@ -434,6 +437,8 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); + real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; + Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); @@ -444,7 +449,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh rcd.best_len = 0; rcd.best_object = nullptr; rcd.best_shape = 0; - rcd.min_allowed_depth = space->test_motion_min_contact_depth; + rcd.min_allowed_depth = min_contact_depth; for (int i = 0; i < amount; i++) { if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { @@ -757,6 +762,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs]; int excluded_shape_pair_count = 0; + real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; + float motion_length = p_motion.length(); Vector2 motion_normal = p_motion / motion_length; @@ -868,6 +875,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co break; } + recovered = true; + Vector2 recover_motion; for (int i = 0; i < cbk.amount; i++) { Vector2 a = sr[i * 2 + 0]; @@ -879,9 +888,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co // Compute depth on recovered motion. float depth = n.dot(a + recover_motion) - d; - if (depth > 0.0) { + if (depth > min_contact_depth + CMP_EPSILON) { // Only recover if there is penetration. - recover_motion -= n * depth * 0.4; + recover_motion -= n * (depth - min_contact_depth) * 0.4; } } @@ -890,8 +899,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co break; } - recovered = true; - body_transform.elements[2] += recover_motion; body_aabb.position += recover_motion; @@ -1068,7 +1075,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co rcd.best_shape = 0; // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. - rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth); + rcd.min_allowed_depth = MIN(motion_length, min_contact_depth); int from_shape = best_shape != -1 ? best_shape : 0; int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); @@ -1345,9 +1352,6 @@ void Space2DSW::set_param(Physics2DServer::SpaceParameter p_param, real_t p_valu case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break; - case Physics2DServer::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: - test_motion_min_contact_depth = p_value; - break; } } @@ -1367,8 +1371,6 @@ real_t Space2DSW::get_param(Physics2DServer::SpaceParameter p_param) const { return body_time_to_sleep; case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; - case Physics2DServer::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: - return test_motion_min_contact_depth; } return 0; } @@ -1400,7 +1402,6 @@ Space2DSW::Space2DSW() { contact_recycle_radius = 1.0; contact_max_separation = 1.5; contact_max_allowed_penetration = 0.3; - test_motion_min_contact_depth = 0.005; constraint_bias = 0.2; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0); diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index c8a5ea7d7d76..d8f845575097 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -102,7 +102,6 @@ class Space2DSW : public RID_Data { real_t contact_max_separation; real_t contact_max_allowed_penetration; real_t constraint_bias; - real_t test_motion_min_contact_depth; enum { diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index f1a4d346a216..f34cb4c4ca9d 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -657,7 +657,6 @@ void Physics2DServer::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD); BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP); BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); - BIND_ENUM_CONSTANT(SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH); BIND_ENUM_CONSTANT(SHAPE_LINE); BIND_ENUM_CONSTANT(SHAPE_RAY); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 9a17521597b6..bd34a3a02f81 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -261,7 +261,6 @@ class Physics2DServer : public Object { SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD, SPACE_PARAM_BODY_TIME_TO_SLEEP, SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS, - SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH, }; virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 15e94d45be61..3d158bc3d0b9 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -759,7 +759,6 @@ void PhysicsServer::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP); BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO); BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); - BIND_ENUM_CONSTANT(SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH); BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_X); BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Y); diff --git a/servers/physics_server.h b/servers/physics_server.h index ea7a342b0664..ae9b88bbd387 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -250,7 +250,6 @@ class PhysicsServer : public Object { SPACE_PARAM_BODY_TIME_TO_SLEEP, SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO, SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS, - SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH }; virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;