|See what's going on with flipcode!|
Quaternions & Representing Object Orientation
Question submitted by (21 June 1999)
|Return to The Archives|
I am trying to specify the orientation for all geometry to follow - I am
using OpenGL. I keep failing to do so satisfactorily, using the OpenGL
calls, matricies or quaternions. In particular I'd like to be able to
avoid "Gimbal Lock".
Can you give a good idea of which method one should use and how we should be specifying the orientation or the change of orientation?
Quaternions should not have had the problem you're describing. You might
want to look there a little more closely. They're the ideal way to go
for many people. So if you need them, stick with them.
Very commonly, when people have gimbal lock problems they have them because they require the ability to maintain roll/pitch/yaw orientation parameters (Quaternions supply this with no gimbal lock issues.)
If you're more comfortable with matrices and don't require the roll/pitch/yaw parameters you can still avoid the gimbal-lock quite successfully.
You can accomplish this by maintaining an incremental matrix. Simply store a cumulative matrix (the resulting matrix at the end of each frame of animation) and use this as the basis for the next frame. At that time you simply concatenate just the relative rotations for the new frame with the existing matrix. This will give you a continuous rotation in any direction with no gimbal lock problems.
From this matrix, you can still obtain the direction vector (which is usually extremely helpful) by pulling out the Z-Vector of the 3x3 portion of your matrix.
From experience, I can say that this works for the popular first-person-shooter interfaces and outer-space style interfaces (full freedom on rotation in any direction.)
If you decide to go this route, I can offer one word of caution: You will need to periodically "fix" your cumulative matrix (assuming you're maintaining an orthogonal matrix.) With many operations, your matrix can sometimes become non-orthogonal. This can be done quite simply with a few cross products.
Response provided by Paul Nettle
This article was originally an entry in flipCode's Fountain of Knowledge, an open Question and Answer column that no longer exists.