Skip to content

Commit

Permalink
Merge pull request #70160 from Geekotron/ccd-regression-fix-70154
Browse files Browse the repository at this point in the history
Fix regression 70154 caused by my prior CCD fix.
  • Loading branch information
akien-mga committed Dec 17, 2022
2 parents 2b05611 + ae55229 commit c903312
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
8 changes: 4 additions & 4 deletions servers/physics_2d/godot_body_pair_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,13 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
Vector2 from = p_xform_A.xform(s[0]);
// Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast.
// This should ensure the calculated new velocity will really cause a bit of overlap instead of just getting us very close.
from -= motion * 0.1;
Vector2 to = from + motion;

Transform2D from_inv = p_xform_B.affine_inverse();

// Start from a little inside the bounding box.
Vector2 local_from = from_inv.xform(from);
// Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast.
// At high speeds, this may mean we're actually casting from well behind the body instead of inside it, which is odd. But it still works out.
Vector2 local_from = from_inv.xform(from - motion * 0.1);
Vector2 local_to = from_inv.xform(to);

Vector2 rpos, rnorm;
Expand All @@ -228,7 +228,7 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
// next frame will hit softly or soft enough.
Vector2 hitpos = p_xform_B.xform(rpos);

real_t newlen = hitpos.distance_to(from);
real_t newlen = hitpos.distance_to(from) + (max - min) * 0.01; // adding 1% of body length to the distance between collision and support point should cause body A's support point to arrive just within B's collider next frame.
p_A->set_linear_velocity(mnormal * (newlen / p_step));

return true;
Expand Down
10 changes: 5 additions & 5 deletions servers/physics_3d/godot_body_pair_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,13 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A,
// convert mnormal into body A's local xform because get_support requires (and returns) local coordinates.
Vector3 s = p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform_inv(mnormal).normalized());
Vector3 from = p_xform_A.xform(s);
// Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast.
// This should ensure the calculated new velocity will really cause a bit of overlap instead of just getting us very close.
from -= motion * 0.1;
Vector3 to = from + motion;

Transform3D from_inv = p_xform_B.affine_inverse();

Vector3 local_from = from_inv.xform(from);
// Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast.
// At high speeds, this may mean we're actually casting from well behind the body instead of inside it, which is odd. But it still works out.
Vector3 local_from = from_inv.xform(from - motion * 0.1);
Vector3 local_to = from_inv.xform(to);

Vector3 rpos, rnorm;
Expand All @@ -214,7 +213,8 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A,
// Shorten the linear velocity so it will collide next frame.
Vector3 hitpos = p_xform_B.xform(rpos);

real_t newlen = hitpos.distance_to(from); // this length (speed) should cause the point we chose slightly behind A's support point to arrive right at B's collider next frame.
real_t newlen = hitpos.distance_to(from) + (max - min) * 0.01; // adding 1% of body length to the distance between collision and support point should cause body A's support point to arrive just within B's collider next frame.

p_A->set_linear_velocity((mnormal * newlen) / p_step);

return true;
Expand Down

0 comments on commit c903312

Please sign in to comment.