Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make move_and_slide collision detection more accurate #50063

Merged

Conversation

pouleyKetchoupp
Copy link
Contributor

@pouleyKetchoupp pouleyKetchoupp commented Jul 1, 2021

This PR refines what was done in #49901 for move_and_slide and improves character collision detection in godot physics in general.

Fixes #50062
Fixes #18433 (with both Bullet and Godot Physics)

Credits to @fabriceci for investigating move and slide issues and helping with finding the proper way to solve them, as well as extensive testing.

More accurate unsafe motion calculation
-Safe and unsafe motion are calculated by dichotomy with a limited number of steps. It's good for performance, but on long motions that either collide near the beginning or near the end, the result can be very imprecise.
-Now a factor 0.25 or 0.75 is used to converge faster when this case happens, which allows longer motions to get more accurate collision detection.
-Makes snap collision more precise, and helps with cases where diagonal collision on the border of a platform can lead to the character being stuck.

Additional improvements to move_and_slide
-Handle slide canceling in move_and_collide with 0 velocity instead of not applying it.
-Better handling of snap with custom logic to cancel sliding.
-Remove small jittering when using stop on slope, by canceling the motion completely when the resulting motion is less than margin instead of always projecting to the up direction (in both body motion and snap).

The same regression tests as for #49901 have been run to make sure things are still working well in other cases.


Move and slide test project made by @fabriceci:
https://github.com/fabriceci/move_and_slide
-Select Classic C++ mode to test standard move_and_slide function
-Classic gdscript is the gdscript conversion of move_and_slide (now updated with this PR)
-Other modes are specific tests for other changes being evaluated


Regression tests

2D Physics tests from Godot demos:
https://github.com/godotengine/godot-demo-projects/tree/master/2d/physics_tests
Functional Tests/Character - Slopes: no regression with KinematicBody2D moving on slopes.
Functional Tests/Character - Tilemap: no regression with KinematicBody2D jumping through one-way collision tiles.
Functional Tests/One Way Collision: no regression with one-way collision at different angles (current state: #42574 (review))

2D test with MRP from #45259:
No regression.

2D test with MRP from #46134:
No regression.

2D test with MRP from #21595:
No regression when moving on slopes. Slightly better stability on flat ground.

2D test with MRP from #31097:
No regression.

2D test with MRP from #45004:
No regression.

3D test with #35945 (comment):
No regression. The issue actually doesn't occur anymore with a safe margin of 0.01, so the change from #40377 to make 0.001 the default value is probably not needed anymore (to be investigated).

3D test with MRP from #33833:
No regression.

More accurate unsafe motion calculation
* Safe and unsafe motion are calculated by dichotomy with a limited
number of steps. It's good for performance, but on long motions that
either collide near the beginning or near the end, the result can be
very imprecise.
* Now a factor 0.25 or 0.75 is used to converge faster when this case
happens, which allows longer motions to get more accurate collision
detection.
* Makes snap collision more precise, and helps with cases where diagonal collision on the border of a platform can lead to the character being stuck.

Additional improvements to move_and_slide:
* Handle slide canceling in move_and_collide with 0 velocity instead of
not applying it.
* Better handling of snap with custom logic to cancel sliding.
* Remove small jittering when using stop on slope, by canceling the
motion completely when the resulting motion is less than margin instead
of always projecting to the up direction (in both body motion and snap).

Co-authored-by: fabriceci <[email protected]>
@pouleyKetchoupp pouleyKetchoupp added this to the 4.0 milestone Jul 1, 2021
@pouleyKetchoupp pouleyKetchoupp requested a review from a team July 1, 2021 23:22
@pouleyKetchoupp pouleyKetchoupp requested review from a team as code owners July 1, 2021 23:22
@akien-mga akien-mga merged commit bc6ea71 into godotengine:master Jul 13, 2021
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants