Game Development Reference
In-Depth Information
D3DXQuaternionSlerp(&middle, &end, &start, 0.66f);
D3DXMATRIX result;
D3DXMatrixRotationQuaternion(&result, &middle);
The two boundary quaternions, start and end , are initialized in the same way as
you saw earlier. The target orientation quaternion, middle , is calculated with the
DirectX method D3DXQuaternionSlerp . This creates a quaternion 66 percent of
the way between our start and end quaternions.
I might not quite have convinced you yet, but only because I used a trivial rotation
that was easy to display. Anyone can interpolate a rotation around a single axis.
Quaternions can represent a rotation about a completely arbitrary axis, like (x=3.5,
y=
2.1, z=0.04), and they can be much more useful than Euler angles.
Compressing Quaternions? Don
'
t Bother!
When I was on Thief: Deadly Shadows, I was sharing an office with a friend of mine who was tasked
with the job of compressing streams of quaternions. He was trying to save a few precious megabytes
on our animations for the main character. His first few attempts were close, but some of the animations
were completely wacko. The character
s legs would lift up past his ears in a manner only suitable for a
circus performer. The problem was a loss in precision in the quaternion stream, and when we thought
about it and truly understood what a normalized quaternion was, it made perfect sense. A normalized
quaternion is a fourth-dimensional vector whose origin sits at (0,0,0,0) and whose endpoint always sits
on the surface of a fourth-dimensional hypersphere. Since a well-formed unit quaternion has a length of
1.0f, any loss of accuracy because of compression will trash the unit length and ruin the precision of the
quaternion. So what did we do? We used Euler angles for storing and compression and converted them
to quaternions during runtime. Euler angles can lose precision like crazy and still work just fine.
Sometimes, the old-school solution is what you need.
'
The Quaternion Class
The D3DXQUATERNION structure can be wrapped in a useful C++ wrapper class:
class Quaternion : public D3DXQUATERNION
{
public:
// Modifiers
void Normalize() { D3DXQuaternionNormalize(this, this); };
void Slerp(const Quaternion &begin, const Quaternion &end, float cooef)
{
// performs spherical linear interpolation between begin & end
// NOTE: set cooef between 0.0f-1.0f
D3DXQuaternionSlerp(this, &begin, &end, cooef);
}
 
Search WWH ::




Custom Search