Game Development Reference

In-Depth Information

As you can see, upon entering
CalcObjectForces
the code enters a loop that cycles

through all the billiard ball objects, computing the forces acting on each. The first force

computed is simple aerodynamic drag. Both linear and angular drag are computed. We

compute the magnitude of the linear drag by multiplying the linear drag coefficient by

1/2ρ
V
2
r
2π
r
, where ρ is the density of air,
V
is the ball's linear speed, and
r
is the ball's

radius. We compute the magnitude of the angular drag moment by multiplying the

angular drag coefficient by ωρ4
r
2π, where ω is angular speed. Since drag retards motion,

the linear drag and angular drag vectors are simply the opposite of the linear and angular

velocity vectors, respectively. Normalizing those vectors and then multiplying by the

respective drag magnitudes yields the linear and angular drag force and moment vec‐

tors.

The next set of forces calculated in
CalcObjectForces
is the contact forces between the

table top and each ball. There are three contact forces. One is the vertical force that

keeps the balls from falling through the table, another is the friction force that arises as

the balls slide along the table, and the third is rolling resistance. These forces arise only

if the ball is in contact with the table. We'll address how to determine whether a ball is

in contact with the table later in this chapter. For now, we'll assume there's contact and

show you how to compute the contact forces.

To compute the vertical force required to keep the ball from falling through the table,

we must first compute the ball's linear acceleration, which is equal to the sum of forces

(excluding contact forces) acting on the ball divided by the ball's mass. Next, we take

the negative dot product of that acceleration and the vector perpendicular to the table

surface and multiply the result by the ball's mass. This yields the magnitude of the contact

force, and to get the vector we multiply that magnitude by the unit vector perpendicular

to the table's surface. The following two lines of code perform these calculations:

Bodies[i].vAcceleration = Bodies[i].vForces / Bodies[i].fMass;

ContactForce = (Bodies[i].fMass * (-Bodies[i].vAcceleration *

Collisions[j].vCollisionNormal)) *

Collisions[j].vCollisionNormal;

The
vCollisionNormal
vector is determined by
CheckGroundPlaneContacts
, which

we'll cover later. As with collisions,
CheckGroundPlaneContacts
fills in a data structure

containing the point of contact, relative velocity between the ball and table at the point

of contact, and the contact normal and tangent vectors, among other data.

To compute the sliding friction force, we must first determine the tangential component

of the relative velocity between the ball and table. If the ball is sliding or slipping as it

rolls, then the relative tangential velocity will be greater than 0. If the ball is rolling

without sliding, then the relative velocity will be 0. In either case, there will be a friction

force; in the former case, we'll use the kinetic friction coefficient, and in the latter we'll

use the static friction coefficient. Friction force is computed in the same way we showed

you in
Chapter 3
. The following lines of code perform all these calculations: