Using 3D Rotation Matrices in Practice

By confuted
So, now that you more or less know how to rotate a point in any arbitrary manner in three dimensions, generating matrices along the way, it's time to learn what you should do with each of these matrices. This tutorial will cover just that: the world matrix, and the camera matrix.



First, a quick review of what you should know from reading other tutorials. A point will go through multiple transformations before it finally makes it to the screen. The point will start out in model space. Model space is just that - the space in which the model was created. Then, once the model has been rotated and translated to the appropriate spot in the world, the point will be in world space. When all of the points are in world space, your Quake 4 level will be all laid out and full of monsters, but there is one more step that the points have to take in three dimensional space before they will be ready to be converted to two dimensional space and displayed on the screen. The points need to all be transformed into camera space, also known as view space. In a 3D game, instead of the camera moving around the world, the world moves around the camera, and the camera always stays at the origin. So, when you rotate the camera, you are really rotating the world backwards. When you move the camera, you're translating the world around you. A matrix will be built to represent this, and after this camera matrix transforms the world space points, they will be in camera space. It is then a fairly simple matter to convert them to screen space and display them on the screen. Many APIs will do this stuff for you, but that's what is going on in the background and you'll need to understand it.

The first thing that needs to happen to a point in model space is that it needs to be rotated while it is still in model space. Then, it will need to be translated (moved) into world space. It may also need to be scaled. This can all be done with one matrix. After you generate the matrix, it can be used to transform every point in a model into world space. You'll need to make a new one of these matrices for each model, though. This will be the "world matrix" and will be set many times each frame.

The next thing that happens to a point is rotating and moving according to the camera's position and orientation. This can be a stumbling point for a lot of people. The first thing to remember is that the view matrix need be set only once per frame. All points will be transformed by it. Depending on what you need your camera to do, there are several different ways of generating it. Check your API documentation - chances are fairly strong that there will be a built-in way of generating a camera matrix by just passing a function a few vectors. Otherwise, there are numerous tutorials online for different methods of building this matrix.

To convert a 3d point to a 2d point may seem to be a non-trivial matter. You are, in essence, attempting to project a three dimensional point onto the correct spot of a two dimensional plane. For points farther in the distance, you'll want to create a perspective illusion, and make all points converge to one point in the center of the screen. After all the math I've hit you with, you're probably preparing yourself for something even more complex. Wrong. The hard math doesn't come until the next tutorial. Just do this:

Screen_X = (viewSpace_X / viewSpace_Z)+(SCREEN_WIDTH/2)
Screen_Y = (viewSpace_Y / viewSpace_Z)+(SCREEN_HEIGHT/2)

Yeah, it's actually that easy.

For a FPS, it's probably safe to do transformations with Euler angles when going from model space into world space. Chances are good that the monsters in your game will only be rotating about their Y-axis, in which case you're 100% safe with Euler angles. However, the camera will not be restricted like this. The camera will rotate on two, or possibly three axes, and thus will be subject to gimbal lock if you use Euler angles. So, for the camera, either use an axis-angle representation, or quaternions - the mind-blowing, really cool subject of the next tutorial.
Previous: Rotation About an Arbitrary Axis
Next: Using Quaternions
Back to Graphics tutorials index