I'm interested in converting this to use quaternions so that I don't have to worry about reorthogonalising my three local axis vectors every frame by taking vector cross products, etc... but I can't see how I'd do it. Surely to ensure that the object continues to rotate about its local yaw, pitch and roll axes, I'll need to keep using my three vectors and also my rotation matrices like I have above?

Thanks for your help!

sorry dude, looks like its not happening.

i've been researching this myself.

see these recent threads...

http://www.gamedev.net/topic/640230-how-to-re-orthogonalise-vectors/

http://www.gamedev.net/topic/640889-pixel-perfect-local-rotations-and-quats-vs-mats/

in a nutshell, quats accumulate error less quickly, but still get whacked after a while.

even rolling your own long double or long long fixed point implementation of mats or quats will eventually get whacked due to cumulative incremental local rotation precision errors. but depending on how long the game runs, long long fixed point might do it without getting too whacked by the end.

i've decided to stick with mats and gram shmitt for the moment, and hope that induced drift can be lived with.

note that selection of axes when normalizing will determine where the drift shows up and which turns will be accurate.

if you preserve the forward vector and adjust the other two, roll will work, and yaw and pitch will drift.

if you preserve up, yaw should work pixel perfect, and pitch and roll will drift.

if you preserve right, pitch will work, and yaw and roll will drift.

in the past i've preserved forward, and lived with drifting pitch at high screen resolutions.

but its probably better to preserve up or right (your preference), so either yaw or pitch drifts a bit, but not both.

there this whole rats nest mess of what type of data structure to store orientation in, and how to rotate that orientation about local axes.

the graphics engine uses mats. orientation can be stored a number of ways (mat; quat; vector & roll; Eulers; fwd,up,right [i,j,k] vectors; etc). turning uses mat mul, quat mul, or rotation about arbitrary axis, and i think double or triple skew is another possible method. movement use direction vector. AI (mine at least) uses Euler angles.

rotation about an arbitrary axis may be a possibility. first time i got 3 degree rotational freedom working, i used fwd,up,right vectors, rotation about arbitrary axis formula, and gramm-shmitt. but given that i was using gram-shmitt there, a float implementation of arb axis still wouldn't cut it.

so, given this rats nest, i've decided for the moment to use mats for orientation. mat mul turns them easily (orientation = local_rotation * orientation), you can use gramm-shmitt to keep them orthogonal: normalize(&orientation). the graphics engine can use the mat directly (world = scale * orientation * translation). the movement engine can use the 3rd column vector (forward vector) directly (x+=speed*fwd.x, y+=speed*fwd.y, etc). and euler angles can be easily extracted for use by AI, etc. code for extracting eulers from mat is posted in the above mentioned threads.

note also that your turn rate, if very small, will induce error faster.

overhead of normalize() doesn't seem to be an issue in this day and age, even normalizing after every incremental rotation.

**Edited by Norman Barrows, 02 April 2013 - 11:05 AM.**