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;