Game Development Reference

In-Depth Information

The rigid-body class used in this example is very similar to that used for the airplane

example in
Chapter 15
. Even though the balls are compact and round, and it's tempting

to treat them as particles, you must treat them as 3D rigid bodies in order to capture

rolling and spinning, which are important elements of billiard ball dynamics. The rigid-

body class adopted for this billiards example is as follows.

typedef struct _RigidBody {

float fMass; // Total mass (constant)

Matrix3x3 mInertia; // Mass moment of inertia in body coordinates

Matrix3x3 mInertiaInverse;// Inverse of mass moment of inertia matrix

Vector vPosition; // Position in earth coordinates

Vector vVelocity; // Velocity in earth coordinates

Vector vVelocityBody; // Velocity in body coordinates

Vector vAcceleration; // Acceleration of cg in earth space

Vector vAngularAcceleration; //Angular acceleration in body coordinates

Vector vAngularAccelerationGlobal; // Angular acceleration

// in global coordinates

Vector vAngularVelocity; // Angular velocity in body coordinates

Vector vAngularVelocityGlobal; // Angular velocity in global coordinates

Vector vEulerAngles; // Euler angles in body coordinates

float fSpeed; // Speed (magnitude of the velocity)

Quaternion qOrientation; // Orientation in earth coordinates

Vector vForces; // Total force on body

Vector vMoments; // Total moment (torque) on body

Matrix3x3 mIeInverse; // Inverse of moment of inertia in earth coordinates

float fRadius; // Ball radius

} RigidBody, *pRigidBody;

As you can see, this class looks very similar to the rigid-body classes we've used through‐

out this topic, and in particular that used in the airplane example. All the usual suspects

are here, and the comments in this code sample state what each class member represents.

One particular property you have not seen yet is
fRadius
—this is simply the billiard

ball's radius, which is used when we are checking for collisions and calculating drag

forces.

As we discussed in
Chapter 14
, since there are multiple objects in this simulation that

may collide, we're going to iterate through all the objects, checking for collisions while

storing the collision data. Since there are not that many objects in this simulation, we

don't really need to partition the game space in order to optimize the collision detection

checks (refer to
Chapter 14
). The data we need to store for each collision is included in

the following
Collision
structure:

typedef struct _Collision {

int body1;

int body2;

Vector vCollisionNormal;

Vector vCollisionPoint;

Vector vRelativeVelocity;

Vector vRelativeAcceleration;