Wednesday, March 19, 2008

Proper Camera Rotation

In order to have a better look at the weird artefacts on my terrain, I tried to add a mouse & keyboard controlled camera. Matrix.RotationYawPitchRoll doesn't seem to work for me - if I rotate my camera 90 degrees about the Y axis (yaw) looking to my left then try to rotate about the Z axis (roll) so the view spins clockwise it actually rotates around the X axis (pitch) and ends up looking up and down.

(I suppose I should've said on the first post that I'm writing the game in Managed DirectX with C#).

Anyways, I had this problem before when I was good at geometry so I was sure I could do it again. Unfortunately years of boozing have destroyed any remnants of my secondary school geometry and the results of my sin/cos calculations were that I should go get my old computer out of the shed and get the old code. Here it is if anyone has the same problem:

private void Rotate(float yaw, float pitch, float roll)
{
// We'll create 3 matrices for the combined rotation
Matrix yawMatrix = new Matrix ();
Matrix pitchMatrix = new Matrix ();
Matrix rollMatrix = new Matrix ();

_localMatrix.Translate(_position);

// Reset it's orientation vectors to make sure they're all
// sqare against each other and unit length
_look.Normalize();
_right = Vector3.Cross(_up, _look);
_right.Normalize();
_up = Vector3.Cross(_look, _right);
_up.Normalize();

// The pitch rotation will be done about the x axis (right)
pitchMatrix.RotateAxis(_right, pitch);
// The yaw rotation will be done about the y axis (up)
yawMatrix.RotateAxis(_up, yaw);
// The roll rotation will be done about the z axis (look)
rollMatrix.RotateAxis(_look, roll);

// Rotate the local axis about these matrices so we can tell
// how the object is now oriented after rotation

// Rotate the _look and _right about the yaw rotation
_look.TransformCoordinate(yawMatrix);
_right.TransformCoordinate(yawMatrix);

// Rotate the _up and _right about the roll rotation
_up.TransformCoordinate(rollMatrix);
_right.TransformCoordinate(rollMatrix);

// Rotate the _look and _up about the pitch rotation
_look.TransformCoordinate(pitchMatrix);
_up.TransformCoordinate(pitchMatrix);

// Store this in the local matrix for translation when rendering
_localMatrix.M11 = _right.X;
_localMatrix.M12 = _right.Y;
_localMatrix.M13 = _right.Z;

_localMatrix.M21 = _up.X;
_localMatrix.M22 = _up.Y;
_localMatrix.M23 = _up.Z;

_localMatrix.M31 = _look.X;
_localMatrix.M32 = _look.Y;
_localMatrix.M33 = _look.Z;
}

No comments: