summaryrefslogtreecommitdiff
path: root/servers/physics_2d/physics_server_2d_sw.cpp
diff options
context:
space:
mode:
authorMarcel Admiraal <madmiraal@users.noreply.github.com>2020-10-05 14:55:11 +0100
committerMarcel Admiraal <madmiraal@users.noreply.github.com>2021-01-07 09:22:39 +0000
commit7653b8cc1e244fede8055b94e2f3f7c060296844 (patch)
tree52940e59c5b3db7074d6747d34a1d1ebe767b3fd /servers/physics_2d/physics_server_2d_sw.cpp
parent8158d17edf18e3d6ec847d2cb710012361e7b12e (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.cpp32
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;