Game Development Reference
In-Depth Information
Excerpt from src/contacts.cpp
// We need to work out the inertia of each object in the direction
// of the contact normal, due to angular inertia only.
for (unsigned i = 0;i<2;i++) {
if (body[i]) {
Matrix3 inverseInertiaTensor;
body[i]->getInverseInertiaTensorWorld(&inverseInertiaTensor);
// Use the same procedure as for calculating frictionless
// velocity change to work out the angular inertia.
Vector3 angularInertiaWorld =
relativeContactPosition[i] % contactNormal;
angularInertiaWorld =
inverseInertiaTensor.transform(angularInertiaWorld);
angularInertiaWorld =
angularInertiaWorld % relativeContactPosition[i];
angularInertia[i] = angularInertiaWorld * contactNormal;
// The linear component is simply the inverse mass.
linearInertia[i] = body[i]->getInverseMass();
// Keep track of the total inertia from all components.
totalInertia += linearInertia[i] + angularInertia[i];
}
}
At the end of this loop we have the four values (two for single-body collisions)
that tell us the proportion of the penetration to be resolved by each component of
eachrigidbody.Theactualamounteachobjectneedstomoveisfoundby
real inverseInertia = 1 / totalInertia;
linearMove[0] = penetration * linearInertia[0] * inverseInertia;
linearMove[1] = -penetration * linearInertia[1] * inverseInertia;
angularMove[0] = penetration * angularInertia[0] * inverseInertia;
angularMove[1] = -penetration * angularInertia[1] * inverseInertia;
The penetration value is negative for the second object in the collision for the same
reason we changed the sign of the impulse for velocity resolution: the movement is
given from the first object's point of view.
Applying the Movement
Applying the linear motion is simple. The linear move value gives the amount of
motion required, and the contact normal tells us the direction in which the movement
should take place:
Search Nedrilad ::

Custom Search