There are a number of advantages to keeping your accumulated orientation in a matrix rather than as Euler angles, however there are some that will throw there hands in the air with horror! “but think of the drift” they will say, and right enough if you rotate back and forth by exactly the same time interval a few hundred times, there’s every chance you won’t be exactly where you started. That said its likely a tiny error and for all practical purposes especially in a game you simply won’t notice it…

So why do it, anyway? For a start you neatly side step gimbal lock and it also simplifies local and global rotations no end.

Commonly when building a matrix to render a 3d shape you’ll start from translation matrix and multiply that with the rotation matrices (from Euler angles), however with this technique we preserve our rotation matrix and each frame multiply it with incremental matrices.

if (IsKeyDown(KEY_A)) { rot = MatrixMultiply(MatrixRotateZ(0.04), rot); }

This for example rotates our matrix locally around the objects Z axis

if (IsKeyDown(KEY_A)) { rot = MatrixMultiply(rot, MatrixRotateZ(0.04)); }

Doing the rotation the other way round rotates the object around the global Z axis.

As you can see its important to remember that matrix operations are non-commutative, which just means that A*B and B*A do not give the same result.

When we want to render our model, we start off with a translation matrix (to position our model) and then multiply that with our ongoing rotation matrix.

Another thing to note is the 0.04 value used for the increment matrix, if you’re not using a fixed frame rate then you should multiply this by a delta value, however if you’re using a fixed frame rate you could cache the 6 rotation increment matrices (+ and – increment for each axis) which might possibly save you a tiny bit of time.

In the example code to accompany this post you can use the following keys to rotate the model

- A & D Rotate around the Z axis
- E & Q for the Y axis
- W & S for the X axis

Holding down the shift key will rotate around the global (or world) axes instead of the objects local axes

You can get the source here

Enjoy!