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;
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;