diff options
author | Marcel Admiraal <madmiraal@users.noreply.github.com> | 2020-10-05 14:55:11 +0100 |
---|---|---|
committer | Marcel Admiraal <madmiraal@users.noreply.github.com> | 2021-01-07 09:22:39 +0000 |
commit | 7653b8cc1e244fede8055b94e2f3f7c060296844 (patch) | |
tree | 52940e59c5b3db7074d6747d34a1d1ebe767b3fd /servers/physics_2d/physics_server_2d_sw.cpp | |
parent | 8158d17edf18e3d6ec847d2cb710012361e7b12e (diff) |
Fix multiple issues with one-way collisions
For RigidBodies, uses the collision normal determined by relative motion
to determine whether or not a one-way collision has occurred.
For KinematicBodies, performs additional checks to ensure a one-way
collision has occurred, and averages the recovery step over all collision
shapes.
Co-authored-by: Sergej Gureev <sergej.gureev@relex.fi>
Diffstat (limited to 'servers/physics_2d/physics_server_2d_sw.cpp')
-rw-r--r-- | servers/physics_2d/physics_server_2d_sw.cpp | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 85e24ca537..c4e2489bef 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -149,24 +149,19 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & return; } + Vector2 rel_dir = (p_point_A - p_point_B); + real_t rel_length2 = rel_dir.length_squared(); if (cbk->valid_dir != Vector2()) { - if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) { - cbk->invalid_by_dir++; - return; - } - Vector2 rel_dir = (p_point_A - p_point_B).normalized(); - - if (cbk->valid_dir.dot(rel_dir) < Math_SQRT12) { //sqrt(2)/2.0 - 45 degrees - cbk->invalid_by_dir++; - - /* - print_line("A: "+p_point_A); - print_line("B: "+p_point_B); - print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B)))); - print_line("resnorm: "+(p_point_A-p_point_B).normalized()); - print_line("distance: "+rtos(p_point_A.distance_to(p_point_B))); - */ - return; + if (cbk->valid_depth < 10e20) { + if (rel_length2 > cbk->valid_depth * cbk->valid_depth || + (rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) { + cbk->invalid_by_dir++; + return; + } + } else { + if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) { + return; + } } } @@ -182,8 +177,7 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & } } - real_t d = p_point_A.distance_squared_to(p_point_B); - if (d < min_depth) { + if (rel_length2 < min_depth) { return; } cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; |