haegarr - I just noticed that yes, there is an error in the order. I really don't know why! Anyway, I've corrected it now.
I also looked into what you both said about getting the vectors from the matrix, and it turns out that this works:
up = D3DXVECTOR3(OrientationMatrix._21, OrientationMatrix._22, OrientationMatrix._23); forward = D3DXVECTOR3(OrientationMatrix._31, OrientationMatrix._32, OrientationMatrix._33); right = D3DXVECTOR3(OrientationMatrix._11, OrientationMatrix._12, OrientationMatrix._13);
...so it looks like the individual vectors are stored in the rows. At least I think that's how it is - am I right in saying that, for example, _12 corresponds to row 1, column 2? So it turns out that I don't need to store the vectors like I was doing - they're already there! Of course, that doesn't solve the problem of orthonormalising them, although I messed about a bit with quaternions and I came up with this:
D3DXVECTOR3 up(OrientationMatrix._21, OrientationMatrix._22, OrientationMatrix._23); D3DXVECTOR3 forward(OrientationMatrix._31, OrientationMatrix._32, OrientationMatrix._33); D3DXVECTOR3 right(OrientationMatrix._11, OrientationMatrix._12, OrientationMatrix._13); D3DXQUATERNION quatYaw, quatPitch, quatRoll; //Quaternions to hold local rotation info D3DXQuaternionRotationAxis(&quatYaw, &up, OrientationDelta.x); //Build a yaw rotation axis D3DXQuaternionRotationAxis(&quatPitch, &right, OrientationDelta.y); //Build a pitch rotation axis D3DXQuaternionRotationAxis(&quatRoll, &forward, OrientationDelta.z); //Build a roll rotation axis OrientationQuat *= quatYaw*quatPitch*quatRoll; D3DXQuaternionNormalize(&OrientationQuat, &OrientationQuat); D3DXMatrixRotationQuaternion(&OrientationMatrix, &OrientationQuat);
Is this the sort of thing that I'm after? I removed the current orthogonalising routine I've got (cross products, etc...) and put in the D3DXQuaternionNormalize() part.