• 14
• 12
• 9
• 10
• 13

# Help Transformations.

This topic is 4858 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Im just getting started and im kinda lost about transformations. Well more than a little lost. So i made a little program that draws some 3d shapes and then lets you move the camera around the world. however im not 100% sure i understand what is going on First i want to know if a matrix pushed into the stack is multpied into all other matrices on top of it. Second im kind of lost about thinking about drawing the world around the camera and not the camera in the world thing.

##### Share on other sites
glPushMatrix does not change the current matrix, it simply saves it onto the stack. glPopMatrix however will, as it loads the matrix that is on top of the stack. So...

glPushMatrix(); -> matrix stack is now A

glPushMatrix(); -> matrix stack is now A,B

glPopMatrix(); -> takes 'B' off stack, matrix is now 'B', stack is now A

glPopMatrix(); -> takes 'A' off stack, matrix is A, stack is empty.

so matrix is now A..

so,

glPopMatrix() would cause an error here, since the stack is empty.

OK. camera.

You need to know matrix maths, especially a 4x4 geometry transformation matrix... Which treats all vertex positions as x,y,z,1... The 1 is special, and allows translation as well as rotation... But moving on...

When you setup your scene, first thing you do, naturally, is set the camera, push the matrix to save it, set your lights, etc. Then go through each object, mult'matrixing, or glRotate, etc, pushing and popping the matrix before each object and after each object.

Setting the camera is the tricky part.

The way to understand what the camera matrix should be can be demonstrated by a simple example:

Say, you have a gun model, and you want this gun model to always appear in the players view. So the centre of the model will always be exactly the same as the camera position, the roation the same, etc.
So in this case, the camera matrix will be the same as the gun's matrix. Make sure this makes sense...

So, given that, we want it to appear as if the gun has no translation, no rotation.. Is exactly at the centre of the screen. So when it's drawn, the modelview matrix will be an identity matrix (vertices don't change when multiplied).
Make sure that makes sense too.

So.

C = Camera matrix
G = Gun matrix

MV = modelview

So.

Ideally,

MV = C * G.

we want MV to be identity.

so,

C * G = I.

if C = G, (as in this case, gun being the same)
then this clearly can't possibly work...

It's like saying a*a=1

However, (1/a) * a = 1
is true (ignore a=0 [smile])

so, by that logic, for this to work, the matrix loaded in as the camera matrix, must be (1/C), which in matrix terms, means the inverse of the matrix must be loaded.

getting an inverse isn't easy however.

There is a cheat.
glLookAt() effectivly takes in values which can be used to create a simple matrix (vectors for each axis, position, etc), it will then invert it, and use glMultMatrix(...) to apply it.

So.

If that all made sense, you are 10m closer to understanding how to use matrices properly in OpenGL. (there are lots and lots of ways to do this, but I have to say I'm not a fan of using glRotate, glTranslate, etc)

In my sig there is an app that will demonstrate some of what I've said... You may find it interesting to look over. It's not wonderful code, and I don't suggest you treat it as such, but hopfully it will convey the ideas well enough.

##### Share on other sites
The standard "camera" matrix is:

[ Sx Sy Sz -Px ][ Ux Uy Uz -Py ][ Fx Fy Fz -Pz ][  0  0  0  1 ]

Where S, U, F and P are the side, up, front and position vectors respectively, that define the camera frame.

Pretty simple really, and is what gluLookAt does.

Quote:
 getting an inverse isn't easy however.

Is for an orthonormal transformation matrix. Take the standard "frame" representation:

[ Sx Ux Fx Px ][ Sy Uy Fy Py ][ Sz Uz Fz Pz ][ 0  0  0  1 ]

Note that the "camera" matrix is just the inverse of this. All that you have to do is transpose the upper left 3x3, and negate the position.

##### Share on other sites
I happened upon this post and just wanted to say that you guys rule. That helped me a lot also.

##### Share on other sites
Quote:
 All that you have to do is transpose the upper left 3x3, and negate the position.

Not quite, the position becomes the negative multiplied by the transpose 3x3 portion of the matrix.

Still, using an inverse from the start is good practise for when you start mucking around with weird projection, shear and other strange matrices. Which is inevitable [wink]

in the app in my sig,
in matrix.h, partialInvert() does that transpose trick. You could also invert the length of the each of the 3 vectors in the 3x3 part to help out with basic matrix scaling too..
But a full inverse is still better ;)

So the P vector you mention for position is only true when the 3x3 submatrix is identity.. Otherwise it's not the actual camera position.

For example, if you do the following:

gluLookAt(0,-1,0,0,0,0,0,0,1);

float mat[16];

glGetFloatv(GL_MODELVIEW_MATRIX,mat);

That effectivly puts the camera position at [0,-1,0], the position in mat is [0,0,-1], which is different as the 3x3 submatrix is not identity, it is:

1 0 0
0 0 -1
0 1 0

[0,-1,0]*transpose(that matrix) = 0,0,-1

##### Share on other sites
Quote:
Original post by RipTorn
Quote:
 All that you have to do is transpose the upper left 3x3, and negate the position.

Not quite, the position becomes the negative multiplied by the transpose 3x3 portion of the matrix.

Good point, I totally forgot about that.

Accounting for my mistake, the matrix then becomes:

[ Sx Sy Sz -P.S ][ Ux Uy Uz -P.U ][ Fx Fy Fz -P.F ][ 0  0  0   1  ]

That looks more familiar.

Shear matrices aren't too bad... Although granted I've not much experience with them.