Game Development Reference
In-Depth Information
ContactForce = (Bodies[i].fMass * (-Bodies[i].vAcceleration *
Collisions[j].vCollisionNormal)) *
Collisions[j].vCollisionNormal;
double vt = fabs(Collisions[j].vRelativeVelocity *
Collisions[j].vCollisionTangent);
if(vt > VELOCITYTOLERANCE)
{
// Kinetic:
FrictionForce = (ContactForce.Magnitude() *
FRICTIONCOEFFICIENTGROUND) *
Collisions[j].vCollisionTangent;
} else {
// Static:
FrictionForce = (ContactForce.Magnitude() *
FRICTIONCOEFFICIENTGROUND * 2 *
vt/VELOCITYTOLERANCE) *
Collisions[j].vCollisionTangent;
}
Keep in mind that these forces will create moments if they do not act through the ball's
center of gravity. So, after computing and aggregating these forces, you must also resolve
any moments created and aggregate those using the same formulas we've shown through
this topic. The following lines of code take care of these tasks:
// accumlate contact and friction forces and moments
Bodies[i].vForces += ContactForce;
Bodies[i].vForces += FrictionForce;
ContactForce = QVRotate(~Bodies[i].qOrientation, ContactForce);
FrictionForce = QVRotate(~Bodies[i].qOrientation,
FrictionForce);
pt = Collisions[j].vCollisionPoint - Bodies[i].vPosition;
pt = QVRotate(~Bodies[i].qOrientation, pt);
Bodies[i].vMoments += pt^ContactForce;
Bodies[i].vMoments += pt^FrictionForce;
Rolling resistance arises by virtue of small deformations in the cloth-covered table cre‐
ating a little divot that the ball must overcome as it rolls. This divot shifts the center of
application of the contact force just a little bit in the direction of rolling. That small
offset results in a moment when multiplied by the contact force. The resulting moment
opposes rolling; otherwise, without some other resistance the ball would continue roll‐
ing unrealistically. The following code computes the rolling resistance:
// Do rolling resistance:
if(Bodies[i].vAngularVelocity.Magnitude() > VELOCITYTOLERANCE)
{
FRn = ContactForce.Magnitude() *
Collisions[j].vCollisionNormal;
Collisions[j].vCollisionTangent.Normalize();
Vector m = (Collisions[j].vCollisionTangent
*(ROLLINGRESISTANCECOEFFICIENT *