Game Development Reference
In-Depth Information
body[i]->position += contactNormal * linearMove[i];
The angular motion is a little more difficult. We know the amount of linear move-
ment we are looking for; we need to calculate the change in the orientation quaternion
thatwillgiveittous.
We do this in three stages. First we calculate the rotation needed to move the con-
tact point by one unit. Second, we multiply this by the number of units needed (i.e.,
the angularMove value). Finally we apply the rotation to the orientation quaternion.
We can calculate the direction in which the object needs to rotate, using the same
assumption that the rotation is caused by some kind of impulse (even though velocity
does not change, only position and orientation). If an impulse were exerted at the
contact point, the change in rotation would be
θ
I 1 u
I 1 (q rel ×
=
=
g )
where q rel is the relative position of the contact point, u is the impulsive torque gen-
erated by the impulse, and g is the impulse in the direction of the contact normal, as
before. In code, this is
Vector3 inverseInertiaTensor;
body->getInverseInertiaTensorWorld(&inverseInertiaTensor);
Vector3 impulsiveTorque = relativeContactPosition % contactNormal;
Vector3 impulsePerMove =
inverseInertiaTensor.transform(impulsiveTorque);
This tells us the impulsive torque needed to get one unit of motion. We are not
really interested in impulses, however. (Because we already know the total distance
that needs to be moved, and we can directly change the object, we don't need to worry
about how forces get translated into motion.)
To find the rotation needed to get one unit of movement we simply multiply
through by the inertia:
Vector3 rotationPerMove = impulsePerMove * 1/angularInertia;
The rotationPerMove vector now tells us the rotation we need to get one unit of move-
ment. And we know the total movement we want is angularMove , so we know the total
rotation to apply is
Vector3 rotation = rotationPerMove * angularMove;