summaryrefslogtreecommitdiff
path: root/servers/physics
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-02-16 13:45:01 -0300
committerJuan Linietsky <reduzio@gmail.com>2019-02-16 13:45:01 -0300
commitee464f56c440ee158fe28f7d3b750280bc63890d (patch)
tree9dccf6d98cf3e09a7a91e462f190f7d1442352f4 /servers/physics
parentc54330c6b0530d0fdc836f7349c4725eb7f309cb (diff)
Add a minimum treshold for acquiring rest contacts to avoid numerical precision issues. Fixes #25074
Diffstat (limited to 'servers/physics')
-rw-r--r--servers/physics/space_sw.cpp8
-rw-r--r--servers/physics/space_sw.h1
2 files changed, 9 insertions, 0 deletions
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index d1e1d1f8a2..250be0cd7a 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -387,6 +387,7 @@ struct _RestCallbackData {
Vector3 best_contact;
Vector3 best_normal;
real_t best_len;
+ real_t min_allowed_depth;
};
static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
@@ -395,6 +396,8 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B,
Vector3 contact_rel = p_point_B - p_point_A;
real_t len = contact_rel.length();
+ if (len < rd->min_allowed_depth)
+ return;
if (len <= rd->best_len)
return;
@@ -418,6 +421,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
rcd.best_len = 0;
rcd.best_object = NULL;
rcd.best_shape = 0;
+ rcd.min_allowed_depth = space->test_motion_min_contact_depth;
for (int i = 0; i < amount; i++) {
@@ -929,6 +933,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
rcd.best_len = 0;
rcd.best_object = NULL;
rcd.best_shape = 0;
+ rcd.min_allowed_depth = test_motion_min_contact_depth;
Transform body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
ShapeSW *body_shape = p_body->get_shape(best_shape);
@@ -1153,6 +1158,7 @@ void SpaceSW::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) {
case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break;
case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio = p_value; break;
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;
}
}
@@ -1168,6 +1174,7 @@ real_t SpaceSW::get_param(PhysicsServer::SpaceParameter p_param) const {
case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: 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;
}
@@ -1203,6 +1210,7 @@ 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 ae6f349e51..3aaa552845 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -96,6 +96,7 @@ private:
real_t contact_max_separation;
real_t contact_max_allowed_penetration;
real_t constraint_bias;
+ real_t test_motion_min_contact_depth;
enum {