dimforge / rapier

2D and 3D physics engines focused on performance.
https://rapier.rs
Apache License 2.0
4.11k stars 251 forks source link

Velocity iteration fidelity control #152

Open emilk opened 3 years ago

emilk commented 3 years ago

Some constructs, like long chains or machinery, requires more solver iterations to converge than other things (e.g. un-jointed bodies). Currently Rapier has a single max_velocity_iterations (that is also, afaict, the minimum).

I suggest adding an optional min_velocity_iterations on a per-body and/or per-joint basis, so that a user can mark certain constructs as requiring more solve iterations than others (and rename max_velocity_iterations to default_velocity_iterations).

The simplest way of implementing this would be be to compute the number of iterations on a per-island basis, so that if any body or joint in an island has a high min_velocity_iterations override, then the whole island gets more iterations. The upside of this is its simplicity, the downside is that you will get CPU spikes. E.g. if a ragdoll is marked as requiring a lot of solve iterations, and it lands on a big pile of boxes, the whole pile of boxes will now start doing more iterations.

A more complicated solution is to do "coupled" iterations, which can save a lot of CPU time. Within each island we would group joints based on the number of iterations they want and compute them that many times, in an interlocking fashion. So for instance, if a ragdoll with min_velocity_iterations=6 lands on a pile of boxes with default number of iterations of 3, then we would have two groups and do rag box rag rag box rag rag box rag, i.e. a semi-even spread.

sebcrozet commented 3 years ago

Having a per-constraint number of velocity iterations sounds like a good idea. For simplicity of implementation, we can start with making this per-joint (which is the most useful case), and figure out later how we make it work per-contact.

Working in an interlocking fashion is interesting. I haven't put any though into it yet, but I wonder how difficult it would be to compute the right "interlocking pattern" when multiple joints with different number of velocity iterations are involved.

Currently Rapier has a single max_velocity_iterations (that is also, afaict, the minimum).

Yes, right now it is both the min and max number of velocity iterations. It is named that way because at some point we may switch to a system where we stop the solver earlier if we reach convergence.