Game Development Reference

In-Depth Information

We remove any velocity that has been built up from acceleration in the previ-

ous rigid-body update.

We artificially decrease the coefficient of restitution for collisions involving

very low speeds.

Independently each of these can solve the vibration problem for some simulations

but will still show problems in others. Together they are about as good as we can get.

15.2.1

R
EMOVING
A
CCELERATED
V
ELOCITY

To remove the velocity due to the previous frame's acceleration, we need to keep track

of the acceleration at each rigid-body update. We can do this with a new data member

for the rigid body,
accelerationAtUpdate
, which stores the calculated linear accelera-

tion. The rigid-body update routine is then modified to keep a record in this variable

of the acceleration generated by all forces and gravity:

Excerpt from src/body.cpp

// Calculate linear acceleration from force inputs.

lastFrameAcceleration = acceleration;

lastFrameAcceleration.addScaledVector(forceAccum, inverseMass);

We could extend this to keep a record of both linear and angular acceleration.

This would make it more accurate, but since most reaction forces are generated by

the gravity (which is always linear), the extra calculations don't normally give any vis-

ible benefit. In fact some developers choose to ignore any force except gravity when

calculating the velocity added in the last frame. This makes the calculation simpler

still, as we can read the acceleration due to gravity from the
acceleration
data mem-

ber directly.

When we calculate the desired change in velocity for a contact, we subtract the

acceleration-induced velocity, in the direction of the contact normal:

v

=−

v
acc
−

(
1

+

c)(v
s
−

v
acc
)

The desired change in velocity is modified from

deltaVelocity = -(1+restitution) * contactVelocity;

to

real velocityFromAcc = body[0]->accelerationAtUpdate * contactNormal;

if (body[1])

{

velocityFromAcc -= body[1]->accelerationAtUpdate * contactNormal;