Closed miolad closed 3 years ago
Hi! Thank you for the example.
This is an artifact due to the way friction is modeled. We use Coulomb friction, except that the friction cone is approximated by a pyramid. This is a common approximation in game physics engines because it avoids one square root on a tight loop.
This approximation implies that friction is allowed to be slightly stronger in diagonal directions. In order to fix this, we need to switch to a non-approximated cone. This change will have a performance impact (not sure yet if this will be noticeable or not), but I believe this is necessary to ensure a better simulation quality.
How does the typical industry libraries handle this? Box2d and co? Do they behave the same?
@extrawurst This problem does not exist in 2D because there is only one possible friction direction for a given contact in 2D. In 3D, Bullet physics used the approximation for a while, but switched to an actual cone afterwards (but they have an option to switch back to the old behavior). I believe PhysX uses the friction pyramid approximation but they make the problem less noticeable by using the relative velocity as the first friction direction.
@miolad Could you please check that https://github.com/dimforge/rapier/issues/137 fixes your problem?
@miolad Could you please check that #137 fixes your problem?
Sorry for the delay, but yep, this totally fixes it, thank you!
Have you measured how much slower it is?
@miolad Thank you for checking. It doesn't make any meaningful differences performance-wise (see https://www.rapier.rs/benchmarks/ by selecting implicit_friction_cone
on the second drop-down). We are memory-bound as far as the solver is concerned, so I guess that adding a sqrt
(and a bunch of other stuffs) isn't enough to make any difference.
https://user-images.githubusercontent.com/66064386/109793418-e817dc00-7c14-11eb-98be-d2299cf1fa21.mp4
The video shows a top-down, fixed, orthographic view of a dynamic cuboid sliding on a static, bigger cuboid. Every force applied to the dynamic body is always parallel to its longer side and the body is rotated in place via a torque through its center of mass. Every collider has a friction coefficient of 1.5.
In the video, you can first see the body sliding along the horizontal axis of the screen (z axis in world space); everything is as expected. The cuboid is then rotated slightly and the same force is applied again (rotated according to the body's isometry). This time, the body, instead of going "straight ahead", still follows the -/+z axis. This is unexpected and shows that the friction must have a wrong (too big) component along the x axis (vertical in screen space). Finally, the body is rotated once more, so that the movement will be oblique with respect to the screen. In this case you can see that the friction still has a tendency to make the body slide in the horizontal drection.
An analogous behavior is also shown along the screen's vertical axis when the body's longest side forms an acute angle with said vertical direction.
Here is the code I'm using for controlling the dynamic body:
It should be noted, though, that everything works as expected when disabling friction (by setting friction or gravity to zero) and instead faking it with linear and angular damping.
The version or rapier3d used is 0.6.1.