Game Development Reference
Airplane.fSpeed = Airplane.vVelocity.Magnitude();
// get the Euler angles for our information
u = MakeEulerAnglesFromQ(Airplane.qOrientation);
Airplane.vEulerAngles.x = u.x; // roll
Airplane.vEulerAngles.y = u.y; // pitch
Airplane.vEulerAngles.z = u.z; // yaw
The very first thing that StepSimulation does is call CalcAirplaneLoads to calculate
the loads acting on the airplane at the current instant in time. StepSimulation then
goes on to calculate the linear acceleration of the airplane based on current loads. Next,
the function goes on to integrate, using Euler's method, once to calculate the airplane's
linear velocity and then a second time to calculate the airplane's position. As we've
commented in the code, if you were simulating a particle this is all you would have to
do; however, since this is not a particle, you need to handle angular motion.
The first step in handling angular motion is to calculate the new angular velocity at this
time step, using Euler integration, based on the previously calculated moments acting
on the airplane and its mass properties. We do this in body coordinates using the fol‐
lowing equation of angular motion but rewritten to solve for d ω:
∑ M cg = d H cg /dt = I (d ω /dt) + ( ω × ( I ω ))
The next step is to integrate again to update the airplane's orientation, which is expressed
as a quaternion. Here, you need to use the differential equation relating an orientation
quaternion to angular velocity that we showed you in Chapter 11 :
d q /dt = (1/2) ω q
Next, to enforce the constraint that this orientation quaternion be a unit quaternion,
the function goes ahead and normalizes the orientation quaternion.
Since the linear velocity was previously calculated in global coordinates (the fixed co‐
ordinate system), and since CalcAirplaneLoads needs the velocity in the body-fixed
(rotating) coordinates system, the function goes ahead and rotates the velocity vector,
storing the body-fixed vector in the vVelocityBody member of the RigidBody structure.
This is done here as a matter of convenience and uses the quaternion rotation function
QVRotate to rotate the vector based on the airplane's current orientation. Notice here
that we use the conjugate of the orientation quaternion since we're now rotating from
global coordinates to body coordinates.