Game Development Reference
In-Depth Information
know that the particle was stationary at the previous frame. In this case the contact
is likely to be a resting contact rather than a colliding contact. Instead of performing
the impulse calculation for a collision, we can apply the impulse that would result in
a zero separating velocity.
This is what would happen for a resting contact: no closing velocity would have
time to build up, so there would be no separating velocity after the contact. In our
case we see that the velocity we do have is likely to be only a by-product of the way we
split time into frames, and we can therefore treat the object as if it had a zero velocity
before the contact. The particle is given a zero velocity. This happens at every frame:
in effect the particle always remains at frame 1 in figure 7.4.
You could also look at this a different way. We are performing a collision with
a zero coefficient of restitution at each frame. These series of micro-collisions keep
the objects apart. For this reason an engine that handles resting contact in this way is
sometimes called a “micro-collision engine.”
Velocity and the Contact Normal
When we have two objects in resting contact, we are interested in their relative velocity
rather than the absolute velocity of either. The two objects might be in resting contact
with each other in one direction, but moving across each other in another direction.
A box might be resting on the ground even though it is skidding across the surface at
the same time. We want the vibrating contacts code to cope with pairs of objects that
are sliding across each other. This means we can't use the absolute velocity of either
object.
To cope with this situation the velocity and acceleration calculations are all per-
formed in the direction of the contact normal only. We first find the velocity in this
direction and test to see whether it could have been solely caused by the component
of the acceleration in the same direction. If so, then the velocity is changed so there is
no separating or closing velocity in this direction. There still may be relative velocity
in any other direction, but it is ignored.
We can add special-case code to the collision processing function in this way:
Excerpt from src/pcontacts.cpp
void ParticleContact::resolveVelocity(real duration)
{
// Find the velocity in the direction of the contact.
real separatingVelocity = calculateSeparatingVelocity();
// Check whether it needs to be resolved.
if (separatingVelocity > 0)
{
// The contact is either separating or stationary - there's
// no impulse required.
return;
}