Hello. I've been working on using quaternions to represent rotations in my scene graph, and I'm a little confused. I started out with the Quaternions tutorial on GameTutorials.com, and I've also read quite a bit of this:
Euclidean Space - Maths - Quaternions. However, I still have a couple of questions about using quaternions, and I'm hoping someone can answer them. Here they are:
1. A quaternion represents one rotation about one axis, right? If this holds true, then if I wanted a 45 degree rotation about the x axis, then a 30 degree rotation about the y axis, then a 90 degree rotation about the z axis, would qFinal below contain the correct rotation?
qRotX.Set(45.0f, 1.0, 0.0f, 0.0f);
qRotY.Set(30.0f, 0.0, 1.0f, 0.0f);
qRotZ.Set(90.0f, 1.0, 0.0f, 0.0f);
qFinal = qRotX * qRotY * qRotZ;
Can I concatenate rotations like that? It seems at the moment that I can't. I have a simple model of a box in my scene graph, and when I multiply together a quaternion for rotation about the X axis, and a quaternion for rotation about the Y axis, the model skews and distorts. It's fine if I have one rotation or the other, but not both together. Plus, if I use the Rotate member of my scene graph, which multiplies a quaternion with a small step in rotation by the scene graph's main quaternion, the skews and distortions become worse as time progresses. I've gone through the quaternion code a couple of times, looking for incorrect statements, but I haven't found any.
Basically, I'd just like a way of scaling, rotating and translating a given object, without distorting it. Am I going about this the right way?
2. I thought a decent way of using quaternions would be for controlling the camera. The Player object holds it's own position and orientation (in the form of a CVector3 class and a CQuaternion class respectively) because the global camera can be comandeered by other objects. The code below is highly unoptimized (uses a rotation matrix, etc.), but it shows what I'm trying to do:
...
CQuaternion qRotX, qRotY, qFinal;
qRotX.Set(-m_vOrientation.m_fX, CVector3(1.0f, 0.0f, 0.0f));
qRotY.Set(-m_vOrientation.m_fY, CVector3(1.0f, 0.0f, 0.0f));
qFinal = qRotX * qRotY;
// Reset the view vector...
CVector3 m_vView;
m_vView.m_fZ = -1.0f;
// Apply the rotation created above to the view
// vector, then add the translation vector to it...
m_vView = m_vView * qFinal.GetRotationMatrix();
m_vView += m_vTranslation;
g_pApp->GetGlobalCamera()->SetTranslation(m_vTranslation);
g_pApp->GetGlobalCamera()->SetView(m_vView);
...
Basically, I create a new view vector every frame by rotating the vector (0, 0, -1) by two quaternions. This unit vector is then added to the player's position to give a proper view vector. However, this is causing some problems. It has reversed my movement with the arrow keys (ie. up moves you backward, down moves you forward), and when I move the mouse left and right, the rotation suddenly increases exponetially. Is there a better way to represent the player's movement and looking than this? If there is, can someone point me to a page that would explain it?
Thanks in advance for any replies...
EDIT: Did some digging around, and it seems that the quaternion multiplication code on Euclidean Space is incorrect. I found
this tutorial at CProgramming.com, implemented the method outlined there, and bingo, no distortion on quaternions that are multiplied together. The camera problem seems to be sorted too, but that will require some more testing to be sure. Anyway, consider both issues above resolved...
[Edited by - iNsAn1tY on October 2, 2004 12:26:42 PM]