There are many instances when you will need to interpolate rotations between different captured motion data files. Common cases are the blending or stitching of different motions or creating a looping motion for actions like walking or running.
As I've stated in previous chapters, the success of blending or looping depends a great deal on the compatibility of the motion data. The points where the data files are to be blended need to be similar in their pose and have a similar timing of motion. If this is true, half the work is already done.
Quaternions
Rotations in captured motion data files are usually represented by Euler angles combined with a predefined order of rotations. This is not the best format to use when interpolating between two rotations because in order to reach the final orientation, three ordered rotations about separate axes have to occur. There are 12 combinations by which the final orientation can be reached, resulting in different representations of the 3 × 3 rotation matrix. Furthermore, Euler angles have the problem commonly known as gimbal lock, whereby a degree of freedom is lost due to parametric singularity. This happens when two axes become aligned, resulting in the loss of the ability to rotate about one of them.
Interpolating translations using Cartesian coordinates works mainly because translations are commutative, which means that to arrive at a certain location in space the order of translations is not important; thus, there are no dependencies between the transformations. Rotations represented by Euler angles are noncommutative, which means that their order cannot be changed and still yield the same final orientation. It also means that the transformations depend on each other.
Interpolation between orientations is best done by using
quaternions, which, as their name implies (from Latin), are sets of four numbers, one of which represents a scalar part and three that represent a vector part. A quaternion
q can be represented by the following equation:
where the coefficients
a,
b,
c, and
d are real numbers, and
i,
j, and
k are the axes. As in complex numbers of the form
where
i2 = −1, for quaternions, each of
i2,
j2, and
k2 are also equal to −1. Thus, quaternions are extensions of complex numbers that satisfy the following identities:
The condensed notation for a quaternion is
where
s is the scalar part and
v is the vector part, so that
Quaternion multiplication can be expressed as follows:
Quaternion multiplication is noncommutative, so
q1q2 is not the same as
q2q1. The magnitude of a quaternion can be determined by the following equation:
where
is the conjugate of the quaternion, defined as
A unit quaternion has a magnitude of 1, so from
Equation (5.68) we can determine that
where
q is a unit quaternion. Unit quaternions are used to represent rotations and can be portrayed as a sphere of radius equal to one unit. The vector originates at the sphere's center, and all the rotations occur along its surface. Interpolating using quaternions guarantees that all intermediate orientations will also fall along the surface of the sphere. For a unit quaternion, it is given that
The inverse of a quaternion is defined as
but for a unit quaternion it can be reduced to
A unit vector
p can be represented in quaternion notation as one without a scalar part, also called a
pure quaternion:
The rotation of
p can be computed by the following equation:
where
P′ is also a pure quaternion. This rotation can also be achieved by applying the following matrix:
Before we start looking at the interpolation process, we need to establish that a rotation of
θ about a unit vector
p can be performed by using the following unit quaternion:
which means that separate rotations about the
x,
y, and
z axes can be represented as
respectively. We can now convert our Euler angles from the captured motion data file into quaternion space by simply multiplying the quaternions in the proper order. For example, a rotation in
XYZ order would be given by using
Equation (5.67) to perform the following multiplication:
Converting a rotation matrix to a quaternion is a simple process. Let us assume we have a 4 × 4 transformation matrix of the form
We obtain the
trace, which is the sum of its diagonal elements
r11,
r22, and
r33 so that
To find the converted quaternion
q(
W,
X,
Y,
Z), we start by finding the value of the scalar
W using
Equation (5.81):
The vector elements are calculated as follows:
Once we are in quaternion space, we can proceed with the interpolation. The most commonly used interpolation method for quaternions is called
spherical linear interpolation, or
slerp. Because of its spherical nature, this method guarantees that any intermediate quaternions will also be unit quaternions. Slerp computes the angle
θ between both quaternions as vectors in two-dimensional space, using their scalar product. If we have two quaternions
q1 and
q2, we can find
θ as follows:
To calculate quaternion
q′ in between
q1 and
q2 using slerp, we use a parametric variable
u with interval from 0 to 1 and the following equation:
If θ is equal to 0, the slerp will run into computational problems due to division by zero. If this is the case, instead of using slerp, we just use linear interpolation. Other problems with slerp occur when θ is equal to multiples of π/2. Those problems can be avoided by changing either one of q1 or q2 to an approximation. For example, we can use q2 and q3, an adjacent keyframe, to generate a third quaternion q4 that is as close to q2 as possible without falling in the problem area; then we could proceed with the original interpolation using q1 and q4 instead of q1 and q2.
We now must convert
q′ (
W,
X,
Y,
Z) back into a rotation matrix
R of the form shown in
Equation (5.80). We use the matrix in
Equation (5.76), which now becomes
We can finally decompose R into Euler angles if we need to using the method explained in the section “Switching the Order of Rotations.”