glMultMatrixf(GLfloat *m );

Well, I didn’t think you had been harsh and I also not intended to be it. So let’s forget that.

I never saw any guy that would write a translation matrix different than this:
1, 0, 0, tx
0, 1, 0, ty
0, 0, 1, tz
0, 0, 0, 1

I’m creative so I could think of that:

0, 1, 0, 0
tx, 0, 1, 1
1, tz, 0, 0
0, 0, 0, ty

I’m quite laughin a bit now…
But, to get to what I mean. There is kind of STANDARD REPRESENTATAION OF A MATRIX, AND STANDARD OPERATIONS APPLYING TO THAT REPRESENTATION. If not, any book would contain different ways of drawing matrices. I bet you will never find any other representation of that column based (the first one of cause) translation matrix.

Now if you lay the opengl pattern over it:

0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15

You can find the memory offsets of the elements when you want to put your drawn matrix into memory. I wouldn’t understand if anybody drifted off from that easy line.

And in case, I don’t mean to offend you. It’s just that my theoretical question go in the background with this discussion… And I’m an ignorant!

Originally posted by Punchey:
[b]Michael Steinberg, I did not intend to come across harsh. I apologize. But I will still contend that it doesn’t matter how you write it on paper because you can read it differently regardless of how you write it. If you write it like 123… you can read it from left to right, if you write it like 1 5 9 … you can read it from top to bottom. Believe me, I’ve gone around and around with this and, as far as OpenGL is concerned, you can write it however you want, the trick is in how you read it. And you can’t ensure that another person is reading it correctly unless you make explicit which array elements correspond to which vectors.

Elixer, I think the whole transpose thing completely depends on how you preffer to do your camera operations. I’m using Nutty’s matrix strucure mentioned above for my camera AND for my world objects and have not had any thing like the problem you described that I would have. I am using gluLookAt and all I have to do to orient the camera properly is to reverse my front vector. This way, all I have to worry about is the location, direction, etc. of my camera in world space which is the easiest and most intuitive way to do it, IMHO. Let me know if this works for you.[/b]

You can label the elements of the matrix anyway you want provided the layout in memory is column major which is what OpenGL and your matrix struct uses. That was what the previous discussion was about, some people had got the layout in memory wrong, they used rowmajor matrices. You can’t write it anyway you want on paper and expect people to understand it. A translation matrix is always:

1 0 0 tx
0 1 0 ty
0 0 1 tz
0 0 0 1

If it’s not it’s transposed. I think this is what you meant but I thought I’d make sure. Secondly you are inverting (part of) the camera transform before putting it on the matrix stack, you said you are reverse the direction vector of your cameras transform, and provided you don’t do any rolls (which you aren’t if you’re using gluLookAt) this is the same thing as transposing before applying it. Either you transpose or you reverse every modification to the transform (negate translation vectors and rotation angles etc). It all bogs down to the same thing, to get the effect of a camera you apply the inverse (transpose if it’s orthogonal, which it should be) of the cameras transform. The reason you do this is because moving the camera forwards is the same thing as moving the rest of the world backwards.

Originally posted by Michael Steinberg:
[b]Okay, I thought about that transpose stuff, and actually think that my code is correct, if I read the rows instead of the columns, I actually read the matrix in the transpose form…

Another question pops out. There was a cube which was positioned at the orgin. I wanted to rotate it around it’s local axes (what is the plural of “axis” after all?). So I made it exactly as with the camera’s transform matrix. I keep my own matrix. Now it seemed logical to me that if I wanted to rotate around it’s local axes, I would have to get them from the current transla…errr transform matrix. When I used them to create a rotation matrix, the cube behaved strange (I would now get the columns instead of the rows, but I don’t believe it will work then). Now when I simply rotated around the worlspaces axes (or axises or…) it worked beatifully. Why that?[/b]

Think about it, if you apply the transposed rotations it’ll still look correct but with rotation angles reversed and translations going in the wrong direction. Try it with the columns and a camera and some other static objects and see what happens.

That’s okay. I just know that if you say
<pre>
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
</pre>

I can read that as the top row being the first four elements of the array, or I can read it as the left most column being the first four elements of the array, or I can read it as the top row being the order in which the elements are interpreted by opengl but the rows are… for those who don’t really know what they’re doing, it’s very difficult to tell what you’re trying to say when you just list a bunch of numbers. And to make any sense of a number grid, you have to be very familiar with the traditional layout of a matrix used for 3D stuff.
Anyway, in my previous post, I forgot to mention that the best thing about being able to use the same matrix for objects and cameras without having to do any sort of transposing is the ability to simply jump around from object to object using each as the camera. For example, let’s say you have a bunch of soldiers in a map and you want to be able to jump around and see through each of their eyes. All you have to do is switch your pointer (or copy the contents) to that object’s matrix and BAM! You’re suddenly looking from that object’s perspective. If you used a different camera matrix format, then you’d need to do some conversion before being able to do this. But using this technique, it’s a simple matter of changing a pointer:
<pre>
matrix soldier1, soldier2, *camera;

camera=&soldier1;
gluLookAt((float*)&camera…)
/* render scene /
camera=&soldier2;
gluLookAt(…
/
render scene */
<pre>

You get the idea. Anyway, it’s really nice when all your matrices are interchangeable!

Okay, I wasn’t doing any rolling, but now I tried it and I see what you mean. You’re right I was reversing the front vector and I knew that. But I didn’t do any rolling so I didn’t notice that. Still, if you’re not rolling, then it still might be a good way to go. If not, I suppose you could overload the = operator for your camera class to do the matrix assignments for your camera. But it’d be a shame to have to copy all 16 elements each frame if you’re viewing through another object. But once you have the data loaded properly into your camera matrix, do you still just use the standard glRotate and glTranslate routines on it?

I don’t bother with gluLookAt, I use loadmatrix, or multmatrix, because I am working in 6DOF, and as Harsman said, you don’t have 6DOF (no rolls).

But in any case, you can still attach the camera with your method, or by using multmatrix (or loadmatrix for that matter), it just depends on what your code is doing.

Oh, also Punchey said: “But it’d be a shame to have to copy all 16 elements each frame if you’re viewing through another object”

You do this no matter what, using lookat or mult/load matrix.
And you can still use glrotate/translate before or after the calls to multmatrix, again, it depends on what effect you want. But then you also can get that gimbal (sp?) lock, so I use quaternions for rotations, to avoid that.

[This message has been edited by Elixer (edited 01-24-2001).]

Hmmm… I hate to do this, but, I beg to differ. As I just said, I tried doing rolls and I can roll using gluLookAt, it’s just that it seems to be rolling backwards. gluLookAt should, indeed, represent a roll because it makes use of your up vector. Anyway, can someone detail for me how to transpose a matrix? And after you have a matrix that’s been transposed, how can you mess with it from there? For example, if I’m using the matrix from an object, can I just transpose it and then continue to modify it using glRotate etc.? Or do I have to transpose it back, then glRotate it, THEN transpose it back again to use it for display?

If you are modifying the objects matrix directly, then you do need to use your own matrix routines. Then, you transpose the matrix if your are going to use it for a camera view. The only time I transpose the matrix is if I am going to attach a camera to it. Otherwise, it would be backwards in the world.
I use quaternions for rotations, then I convert the quaternions to a matrix, then if I want to attach camera to that object, I do a transpose to the matrix, and then I loadmatrix with the objects matrix. If I don’t want to use the object as a camera, I do the same, but I don’t transpose the object matrix.

Here is some code:
(this is inverse, n=a copy of matrix m)
m[0 ] = n[0 ]; m[1 ] = n[4 ];
m[2 ] = n[8 ]; m[4 ] = n[1 ];
m[5 ] = n[5 ]; m[6 ] = n[9 ];
m[8 ] = n[2 ]; m[9 ] = n[6 ];
m[10] = n[10];
m[12] *= -1.0f;
m[13] *= -1.0f;
m[14] *= -1.0f;

(this is transpose, again, n=copy of m)
m[0 ] = n[0 ]; m[1 ] = n[4 ];
m[2 ] = n[8 ]; m[3 ] = n[12];
m[4 ] = n[1 ]; m[5 ] = n[5 ];
m[6 ] = n[9 ]; m[7 ] = n[13];
m[8 ] = n[2 ]; m[9 ] = n[6 ];
m[10] = n[10]; m[11] = n[14];
m[12] = n[3 ]; m[13] = n[7 ];
m[14] = n[11]; m[15] = n[15];

So then you do:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
MCopy(&iCameraMatrix, &cameraMatrix);
MInverse(&iCameraMatrix);
VCopy(&iCameraPosition, MGetTranslation(&iCameraMatrix));
glLoadMatrixf(iCameraMatrix.m);
glTranslatef(iCameraPosition.v[X], iCameraPosition.v[Y], iCameraPosition.v[Z]);

drawobjects();

[This message has been edited by Elixer (edited 01-24-2001).]

Originally posted by Punchey:
Hmmm… I hate to do this, but, I beg to differ. As I just said, I tried doing rolls and I can roll using gluLookAt, it’s just that it seems to be rolling backwards. gluLookAt should, indeed, represent a roll because it makes use of your up vector. Anyway, can someone detail for me how to transpose a matrix? And after you have a matrix that’s been transposed, how can you mess with it from there? For example, if I’m using the matrix from an object, can I just transpose it and then continue to modify it using glRotate etc.? Or do I have to transpose it back, then glRotate it, THEN transpose it back again to use it for display?

Sure you can do rolls, you can treat your camera just like a normal matrix but then every operation you apply to ir will be reversed, translations will go the wrong way and rotations will rotate CW instead of CCW etc. I also spotted an error in my previous post by the way, the transpose only equals the inverse if the vectors of the matrix are both orthogonal and unitlength, i.e. the matrix is orthonormal. All rotation matrices are orthonormal and transforms are provided they don’t contain translation or scaling. So to inverse a transform without scaling you could transpose the upper left 3x3 sub-matrix and negate the translation vector. That should be pretty quick.

What does it mean that a matrix is orthogonal?

An orthogonal matrix is simply a matrix whose inverse is equal to its transpose. Or if that sounds like circular logic, more exactly, for a square matrix A with components a(ij), if Sum over i of a(ij)*a(ik)=d(jk) , for all j,k where d is the Kronecker delta, then that matrix is orthogonal.

[This message has been edited by DFrey (edited 01-26-2001).]

Okay, which matrices happen to have the same inverse as transpose?
Thanks

The only transformation matrices that are orthogonal are rotational transformations, reflection transformations, and combinations thereof.

Where to find the inverse of the left transformation matrices is rather easy…

Originally posted by Michael Steinberg:
What does it mean that a matrix is orthogonal?

It means that all the vectors are at right angles to eachother. If they’re also of length one then the matrix multiplied by it’s transpose will give you the Identity matrix.

If they’re also of length one then the matrix multiplied by it’s transpose will give you the Identity matrix.

Well, that follows simply because for any orthogonal matrix A, A^-1=A’. Since MM^-1=I for any non-singular matrix M, AA’=AA^-1=I. This has nothing to do with the length of the column or row vectors per se.

How to calculate M/1?

Originally posted by DFrey:
[b] [quote]If they’re also of length one then the matrix multiplied by it’s transpose will give you the Identity matrix.

Well, that follows simply because for any orthogonal matrix A, A^-1=A’. Since MM^-1=I for any non-singular matrix M, AA’=AA^-1=I. This has nothing to do with the length of the column or row vectors per se.

[/b][/QUOTE]

Yeah I know, I just wanted to give a definition that was easier to visualize. If a matrix is orthogonal that is defined to mean what you say but if you haven’t read any linear algebra you might assume orthogonal means “all vectors are orthogonal”. I just wanted to clarify in laymans terms, sorry if it came out somewhat uncorrect mathematically.

I have studied both Michael and Elixer’s code in these posts. I think you are talking about the same thing, maybe you are mixed up.

Elixer’s matrix is exactly the same with Michael’s, except the form of matrix. Elixer’s matrix is in a D3D like form, and Michael’s is in a OpenGL form. In D3D, if you have a vector, it is like (x, y, z), and in OpenGL, it is (x, y z)’. You see, one is the transpose of the other. So in D3D, if you transform v with a matrix M, it is vM, and in OpenGL, it is Mv. Anyway, although Elixer write his matrix in a D3D form, the item layout is correct, you will get the right answer under OpenGL.
I am confused about these two diffrent forms of matrix before.

Originally posted by Michael Steinberg:
How to calculate M/1?

The inverse? It’s kind of complicated, especially since there doesn’t have to exist an inverse. I think there’s source in the matrix and quaternion FAQ, do a web search on that. That FAQ should not be trusted completely though, it has a tendency to say quaternions are great for everything and that all other alternatives suck.