Game Development Reference
In-Depth Information
{
resolveVelocity(duration);
}
real ParticleContact::calculateSeparatingVelocity() const
{
Vector3 relativeVelocity = particle[0]->getVelocity();
if (particle[1]) relativeVelocity -= particle[1]->getVelocity();
return relativeVelocity * contactNormal;
}
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;
}
// Calculate the new separating velocity.
real newSepVelocity = -separatingVelocity * restitution;
real deltaVelocity = newSepVelocity - separatingVelocity;
// We apply the change in velocity to each object in proportion to
// its inverse mass (i.e., those with lower inverse mass [higher
// actual mass] get less change in velocity).
real totalInverseMass = particle[0]->getInverseMass();
if (particle[1]) totalInverseMass += particle[1]->getInverseMass();
// If all particles have infinite mass, then impulses have no effect.
if (totalInverseMass <= 0) return;
// Calculate the impulse to apply.
real impulse = deltaVelocity / totalInverseMass;
// Find the amount of impulse per unit of inverse mass.
Vector3 impulsePerIMass = contactNormal * impulse;