Quaternion Camera in XNA
XNA unfortunately does not provide a QuaternionCamera class in it's Framework. Nowhere on the Internet could I find a camera class that provides six degrees of freedom without requiring additional coding from the reader. (It may be out there somewhere and my google-fu was weak). I even have a couple books that outline quaternion cameras but stop short of implementing them fully. In the process of attacking this problem in my book, I've made a few camera classes. I'm posting the simplest class here - good for beginners. The final camera class in the book will be more complicated. This class should provide a good jumping-off point for anybody interested, or a simple helper class for those who just want a camera without hassles. In the camera, GetViewMatrix and CreateYawPitchRoll are where the money is. One reason they are statics is to make it easy to test these functions - they don't have to be. Another reason is that I hope it makes them stand out to people familiarizing themselves with the class.
public static Matrix GetViewMatrix(ref Vector3 position, ref Vector3 target,
ref Vector3 up, float yaw, float pitch, float roll)
{
// The right vector can be inferred
Vector3 forward = target - position;
Vector3 right = Vector3.Cross(forward, up);
// This quaternion is the total of all the
// specified rotations
Quaternion yawpitch = CreateFromYawPitchRoll(up, yaw,
right, pitch, forward, roll);
// Calculate the new target position, and the
// new up vector by transforming the quaternion
target = position + Vector3.Transform(forward, yawpitch);
up = Vector3.Transform(up, yawpitch);
return Matrix.CreateLookAt(position, target, up);
}
public static Quaternion CreateFromYawPitchRoll(Vector3 up, float yaw, Vector3 right,
float pitch, Vector3 forward, float roll)
{
// Create a quaternion for each rotation, and multiply them
// together. We normalize them to avoid using the conjugate
Quaternion qyaw = Quaternion.CreateFromAxisAngle(up, (float)yaw);
qyaw.Normalize();
Quaternion qtilt = Quaternion.CreateFromAxisAngle(right, (float)pitch);
qtilt.Normalize();
Quaternion qroll = Quaternion.CreateFromAxisAngle(forward, (float)roll);
qroll.Normalize();
Quaternion yawpitch = qyaw * qtilt * qroll;
yawpitch.Normalize();
return yawpitch;
}
GetViewMatrix shows you how to transform the target and up vectors using a quaternion. CreateFromYawPitchRoll combines three quaternions into a single quaternion defining all the camera rotations. (NOTE: The XNA version of this function uses the world axes as the axes of rotation. This version uses the camera axes supplied by the caller).
Enjoy! Update: Apparently blogger or my web server doesn't like .cs files. I've changed the link to a zip file that appears to work. SimpleQuaternionCamera.zip
