-
-
Notifications
You must be signed in to change notification settings - Fork 120
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
Improve simulation stability when object are far from world origin #84
Conversation
After merging #83 cubes example with origin set to (10000, 10000) still explodes, but after 10 seconds instead of 4. explosion.mp4I've tried increasing AABBS like so:
I've waited for a few minutes and so no explosion, and so I think the problem is caused by missed collision pair after some amount of substeps, since the broad phase is run only once. Do you have any clues regarding this explosive behavior? |
I'm still getting explosions with AABBs expanded further like that, although I'm not getting the issue when the cubes are initially stacked (we might have different OSs though, I'm on Windows). In your case I'm guessing all the cubes were marked as sleeping, so they weren't simulated and couldn't explode even if the issue is still there. If I keep moving the cubes frequently, I still get explosions: 2023-07-18.12-50-58.mp4I don't know what's causing the explosive behaviour, but I think a couple things are implemented slightly incorrectly.
These are probably not directly related, since disabling friction didn't seem to help when I tried a while ago, and the other changes cause mixed results. Using f64 seems to help a lot, so I suppose it could be another precision issue somewhere. |
As for this PR, it's definitely a massive improvement when using high masses, small dt or a world origin that is far away. Overall, I l like the It might also make sense to change it to |
It should be public for people who want to implement their own constraints. |
Yeah fair, it should be public as long as it's clear what it's used for and why. |
I tried removing |
It would need to be outside of I would maybe change the cubes example back to what it was, since the origin is unnecessary for the actual example. Could eventually add a separate example with a very far away origin and/or high mass ratios though. Also FYI, you can convert a |
During integration and constraint solving, position gets incremented by very small amounts, especially at high substep count. When the objects are far from origin, small increments to position are rounded to zero. To mitigate that, I've added
AccumulatedTranslation
component, which gets incremented instead ofPosition
. Then, at the end of each substep, a system updates the actual position.This change seems to be the magic bullet for "far from origin" kinds of problems. But it's not perfect yet.
Here's the cubes example with origin set to (10000, 10000). When using
f32
, the next float after10000
is10000.0009766
, which gives precision of roughly1e-3
.Here's the before:
before.mp4
Here's the after:
after.mp4
As you can see, it starts very promising, but then explodes. I don't know what causes that, but If I change substeps from 12 to 6 (not part of PR), it doesn't explode:
after_6_substeps.mp4
Also, I've changed contacts to be queried in local space, since that's what parry does internally, only then to transform it back to world space (and back to local in
PenetrationConstraint
). This improves precision.Additionally, I've found a few places where values of different orders of magnitude were subtracted (for example when computing relative motion of contact points): I've reordered operands to try and keep relative magnitudes close.
Future work
In the future, perhaps it would be beneficial to update actual position not on every substep, but on every step instead. This way, even on very large substep counts (where dt is very tiny) everything should work fine.