Game Development Reference
simulations, having the same number of iterations as there are contacts can often
work fine. I tend to use double the number of contacts as a rule of thumb, but more is
needed for complex, interconnected sets of contacts. You could also give the algorithm
no iteration limit and see how it performs. This is a good approach to debugging when
difficult situations arise.
You may have noticed that I've ignored interpenetration so far. We could combine
interpenetration resolution with collision resolution. A better solution, in practice, is
to separate the two into distinct phases. First we resolve the collisions, in order, using
the previous algorithm. Second we resolve the interpenetrations.
Separating the two resolution steps allows us to use a different order for resolv-
ing interpenetration than for velocity. Once again we want to get the most realistic
results. We can do this by resolving the contacts in order of severity, as before. If we
combine the two stages, we're tied to a suboptimal order for one or the other kind of
The interpenetration resolution follows the same algorithm as for collision reso-
lution. As before, we need to recalculate all the interpenetration depths between each
iteration. Recall that interpenetration depths are provided by the collision detector.
We don't want to perform collision detection again after each iteration, as it is far too
time consuming. To update the interpenetration depth we keep track of how much
we moved the two objects at the previous iteration. The objects in each contact are
then examined. If either object was moved in the last frame, then its interpenetration
depth is updated by finding the component of the move in the direction of the contact
Putting this all together we get the contact resolver function:
Excerpt from include/cyclone/pcontacts.h
* The contact resolution routine for particle contacts. One
* resolver instance can be shared for the whole simulation.
* Holds the number of iterations allowed.
* This is a performance tracking value - we keep a record
* of the actual number of iterations used.