# Organise your Matrices

In previous articles we used some matrices to modify the rendering of a triangle. Rotations, scales, translations, We also learned to use a projection matrix to render the depth effect into the clipspace projection. And we saw that we would upload the matrix as a vertex constant, and use it with the “m44” AGAL opcode.

Matrices operation aren’t distributives, meaning if you scale first, then rotate, it’s not the same thing than if you rotate then scale. So you will have to organize your matrices in a certain order to get things done smooth and easy. Follow the guide.

## From cameras to matrices

First of all, download the following code example. It’s made out of 3 classes :

- The article example bootstrap
- A simple Cube class, that will just create a colored cube vertex and index buffer, and store a matrix for its position.
- An ArcballCamera class that you can use and share for your experiments. Very usefull to get a quick way of “browsing” your scene around the origin point.

## The Cube class

Just a quick word about the Cube class, since you should be able to do it by yourself now : It is not “clean” and “optimised” at all, and I did it only to make the main code more readable.

The Cube class doesn’t even have a “render” function. When you instantiate a Cube, it will create its vertexBuffer and indexBuffer, and upload the simplest data ever. This cube is made out of 8 vertices which is why the color are merging on the corner and that you don’t get a plain color per face. The Cube also create the simple “3 lines” shader you need to have some rendering, and upload it. That’s it.

## The ArcBallCamera class

The ArcBallCamera is a camera that rotates around the origin point. When I tried to build it at first, I though I had to look for geometry formula, about placing a point onto a 3D sphere or something. Actually, it’s a lot simpler.

Your matrices modify the “world”, not the camera

It sounds stupid to say it, but it is something you have to keep in mind. For instance, if you want to have your camera slowly going away from your scene, you will have to i**ncrease** it’s z position, because you are actually “pushing” the world away from your clipspace.

Keep that in mind, and remember that matrices operations are not distributives. To make your arcball camera, the operation are actually very simple : rotate the world, then push it away. That’s it !

Both “method” should work, but it’s actually really simple to use the second one, for the same result : rotate the “world”, then “push” it away.

The rest of the class is pretty simple : on EnterFrame event, the class applies some rotation then some translation to a Matrix 3D according to mouse position and mouseWheel actions.

## The ModelViewProjection matrix

OK, so we have a matrix that is our camera, and we have one for the projection, and we have one for the cube, great, but now ?

The final matrix used for the rendering is often named the modelViewProjection matrix. for a very simple reason : you have to append your every matrices in the following order :

- The Model Matrix : your model being the mesh you are currently drawing
- The View Matrix : the view being your “camera” somehow
- The Projection Matrix : being the “lense” in some 3D Engine, the projection always come last as far as I know.

Following this order will give you very intelligible results.

Head up toward the OrganizeYourMatrices class. Notice that when the context is created, I instantiate a single cube, a camera, and the projection matrix we will use later. Go one to the render function.

## Rendering several cubes with only one

To both illustrates how following the previous matrices order will give you the wanted result and that you can draw several times the same vertexBuffer, I will keep my single cube and render four of them around the origin.

// render second cube
cube.moveTo(1.1, -1.1, 0);
renderCube();
// render third cube
cube.moveTo(-1.1, 1.1, 0);
renderCube();
// render fourth cube
cube.moveTo(1.1, 1.1, 0);
renderCube(); |

// render second cube
cube.moveTo(1.1, -1.1, 0);
renderCube();
// render third cube
cube.moveTo(-1.1, 1.1, 0);
renderCube();
// render fourth cube
cube.moveTo(1.1, 1.1, 0);
renderCube();

The following code isn’t the cleanest one I made but at least it is easy to understand. The only cube we have can be “moved” to 4 differents positions, and drawn onto the screen using the renderCube method. Go ahead, that is were the magic will happen.

/**
* Render the cube according to it's current parameters ( = modelMatrix)
*/
private function renderCube():void {
modelViewProjection = new Matrix3D();
modelViewProjection.append(cube.modelMatrix); // MODEL
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION !
// program
context.setProgram(cube.program);
// vertices
context.setVertexBufferAt(0, cube.vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3); // x, y, z
context.setVertexBufferAt(1, cube.vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3); // r, g, b
//constants
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, modelViewProjection, true);
// render
context.drawTriangles(cube.indexBuffer);
} |

/**
* Render the cube according to it's current parameters ( = modelMatrix)
*/
private function renderCube():void {
modelViewProjection = new Matrix3D();
modelViewProjection.append(cube.modelMatrix); // MODEL
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION !
// program
context.setProgram(cube.program);
// vertices
context.setVertexBufferAt(0, cube.vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3); // x, y, z
context.setVertexBufferAt(1, cube.vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3); // r, g, b
//constants
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, modelViewProjection, true);
// render
context.drawTriangles(cube.indexBuffer);
}

Each time I want to draw the cube, I first start by recreating a modelViewProjection matrix. I could have instantiate it somewhere else, and only reset the matrix using *modelViewProjection.identity(), *that would have been better, but anyway, it’s the same.

First, append the modelMatrix of the cube. This matrix contains the translation parameters we made using *cube.moveTo(x, y, z)*. Append the camera’s matrix, and finish with the projection.

The rest of the renderCube method is just classic Stage3D stuff : declaring your current program, and buffers, and drawing triangles.

The reason you can call several times (in this case, 4) the drawTriangles function and still get the complete scene is because the drawTriangle function only renders your mesh into the backbuffer. So the last thing you need to do on your rendering method is to *present* the backbuffer onto the screen.

Now you should get something like this

## Append and Prepend

There is some case where it is difficult to use this order because of implementations details. Hopefully, there is a way to add a transformation at the top of the operations stack : prepend.

Prepend comes in different flavors : prepend a matrix, prependTranslation, prependRotation and so on.

to understand what prepend does, just look at the 2 following codes : they both do the exact same thing.

modelViewProjection = new Matrix3D();
modelViewProjection.append(cube.modelMatrix); // MODEL
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION ! |

modelViewProjection = new Matrix3D();
modelViewProjection.append(cube.modelMatrix); // MODEL
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION !

modelViewProjection = new Matrix3D();
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION !
modelViewProjection.prepend(cube.modelMatrix); // PREPEND MODEL |

modelViewProjection = new Matrix3D();
modelViewProjection.append(camera.matrix); // VIEW...
modelViewProjection.append(projectionMatrix); // PROJECTION !
modelViewProjection.prepend(cube.modelMatrix); // PREPEND MODEL

That’s all for today, I hope you enjoyed this, as always, and that will be useful for you. Don’t hesitate to use, modify or share the ArcBallCamera class since it’s a very simple snippet of code.

As always, feedback is appreciated !