PDA

View Full Version : Basic Matrix question


Unfadable
09-27-2005, 03:55 PM
Sorry if this question seems simple, but I'm finding all kinds of conflicting info on the net.

My understanding of D3D matrices are that the basis vectors are in the columns of the matrix and for OpenGL the basis vectors go into rows of the matrices.

And also, D3D matrices are stored in row-major format meaning that row elements are next to each other in memory. Row-major doesn't suggest anything about the basis vectors.

Right-handed vs left-handedness is represented in a matrix by the direction it rotates points/vectors (counter-clockwise vs clockwise).

Reedbeta
09-27-2005, 10:48 PM
In both OpenGL and D3D matrices, the basis vectors go into the columns of the matrix.

However, OpenGL expects matrices in column-major order, while D3D expects them in row-major order (and, as far as I know, most programmers' matrix classes are usually in row-major order). Thus, row-major matrices must be transposed to send them to OpenGL.

A 3x3 matrix is not right-handed or left-handed in itself, but if its determinant is > 0 then it is orientation-preserving, meaning it takes a right-handed basis to a right-handed one, and the same for left-handed bases. If the determinant is < 0, it is orientation-reversing, so it takes a right-handed basis to a left-handed one (and vice versa).

Unfadable
09-28-2005, 06:56 AM
Hey thanks for the reply. I'm still a condused:.

In an earlier post about extracting view direction you said
"If you are using OpenGL, the viewing direction is the negative of the 3rd row of the viewing matrix. (This is assuming your viewing transform uses only translations and rotations, not anything weird...)"

How come the view direction is not the 3rd column? Isn't the view direction just the z basis vector?

Btw, I don't know anything about OpenGL. I believe the DirectX LookAt function puts the view direction into the column.

.oisyn
09-28-2005, 08:10 AM
In both OpenGL and D3D matrices, the basis vectors go into the columns of the matrix.

However, OpenGL expects matrices in column-major order, while D3D expects them in row-major order (and, as far as I know, most programmers' matrix classes are usually in row-major order). Thus, row-major matrices must be transposed to send them to OpenGL.

This is not correct. D3D uses row-vectors, which basically means that a 4d vector is a 1 (row) x 4 (colums) matrix. In order to transform a 1x4 vector V with a 4x4 matrix M, you need to do V*M. Also, a transformation of M1 followed by a transformation of M2 yields the matrix M1 * M2. Base vectors in the matrix are columns rows

OpenGL uses colum-vectors, e.g. a vector is a 4x1 matrix. Tranformation is done by doing M * V, and accumulated transformations are done with M2 * M1. Base vectors in the matrix are rows columns.

Therefore, a d3d matrix is transposed with respect to an OpenGL matrix in the mathematical sense. BUT, since d3d stores it's matrices row-major, while OpenGL stores it column-major, both types of matrices have the same memory layout (the reason for OpenGL using a column-major order is that the basevectors are therefore stored sequentially in memory)

.edit: nasty typo's fixed

SigKILL
09-28-2005, 08:16 AM
If 'basis' vectors means the basis for the 3x3 rotational component of the matrix, then in D3D the basis is put in the rows, and in OGL it is put in the columns. This can easily be checked since transforming a vertex v by a matrix A in D3D means multiplying the vector from the left (i.e. v*A), while in OGL you multiply from the right (i.e. A*v). Since ogl is column major, and d3d is row major this leads in practice to D3D and OGL matrices very often to have the same layout in memory (you should probably be careful when working with projection matrices etc).

To get the viewing direction from an OGL matrix use the inverse of the third column (not row)..

Edit: Yeah, D3D row vectors, OGL column vectors..

-si

Unfadable
09-28-2005, 08:56 AM
Hey guys,

I'm almost understanding, plz bear w/me. And hopefully you guys understand why I'm confused :P

By basis vectors, I mean up, right, and view orthonormal vectors. Is there another meaning?

.oisyn and SigKILL thanks for the replies. From what I understand .oisyn is saying d3d base vectors are in columns and SigKill is saying d3d base vectors are in the rows. Did I misinterpret this?

- Is this correct?
D3D_________
R.x U.x V.x 0
R.y U.y V.y 0
R.z U.z V.z 0
T.x T.y T.z 1

OpenGL________
R.x R.y R.z T.x
U.x U.y U.z T.y
V.x V.y V.z T.z
0 0 0 1

SigKILL
09-28-2005, 09:07 AM
Almost:

D3D_____
R.X R.Y R.Z 0
U.X U.Y U.Z 0
V.X V.Y V.Z 0
T.x T.y T.z 1

OpenGL________
R.x U.x V.x T.x
R.y U.y V.y T.y
R.z U.z V.z T.z
0 0 0 1

Where R,U and V are the basis vectors, and T is the translation...
It is so easy to check this: having v in model-space you should get something in world-space by doing v*A in D3D and A*v in OGL.

-si

Unfadable
09-28-2005, 09:25 AM
I found this implementation of D3DXMatrixLookAtLH, where ZAxis is the vector from look at point to eye, xAxis is ZAxis.Cross(upVector), etc


pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);

pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);

pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);


The ZAxis is placed into the columns. So this is transposed to form an inverse rotation?

Reedbeta
09-28-2005, 10:07 AM
The camera view direction is the (negative of) the third row of the 3x3 modelview matrix, not the third column. This is because the modelview matrix takes world space to eye space; therefore, its inverse (= transpose of the 3x3 part, if only rotations/translations are used) takes eye space to world space, and so the world space basis vector can be extracted from the third column of this matrix. It's negative because in OpenGL, the eye looks down the -Z axis in eye space.

SigKILL
09-28-2005, 10:37 AM
"The camera view direction is the (negative of) the third row of the 3x3 modelview matrix, not the third column."

Urgh, my bad. I'm just really tired today. It should of course be the third column of the inverse. This is of course the third row when only rotations and translations are used...

-Si

P.S. I'm really looking forward to becoming a member instead of a "new member". I joined over a year ago...

SigKILL
09-28-2005, 10:41 AM
This is not correct. D3D uses row-vectors, which basically means that a 4d vector is a 1 (row) x 4 (colums) matrix. In order to transform a 1x4 vector V with a 4x4 matrix M, you need to do V*M. Also, a transformation of M1 followed by a transformation of M2 yields the matrix M1 * M2. Base vectors in the matrix are columns

OpenGL uses colum-vectors, e.g. a vector is a 4x1 matrix. Tranformation is done by doing M * V, and accumulated transformations are done with M2 * M1. Base vectors in the matrix are rows.


There might be confusion because we seem to define basis vectors differently.I'm thinking of a given vector in some "model space", the basis is the "model space" basis given relative to the "world space", and the transformation goes from "model space" to "world space". It might seem that you're thinking the other way around. Your way makes things look ugly when scaling etc. is involved IMO...

-Si

P.S. Member yet?

Unfadable
09-28-2005, 11:15 AM
Cool, well I think I understand this now. Thanks everyone for their input.

But please, anyone, feel free to add more to the subject if you'd like.

Unfadable

.oisyn
09-28-2005, 12:46 PM
Hey guys,
.oisyn and SigKILL thanks for the replies. From what I understand .oisyn is saying d3d base vectors are in columns and SigKill is saying d3d base vectors are in the rows. Did I misinterpret this?

No, you interpreted it correctly, I flipped the meaning of column and row in my head when writing down the base vector orientations. SigKILL is correct, D3D has it's base vectors in the rows, OGL in the columns (otherwise my post wouldn't be consistent as I claim that OGL had chosen for row-major matrices because of the contiguous memory layout for the base vectors, which wouldn't be the case if the base vectors were in the rows ;))

NomadRock
09-28-2005, 01:36 PM
SigKill, your new member status is totally based on your post count. To date you have posted 20 times. Being more active across the board as you are in this thread will ensure you very quickly rise in rank. Obviously spamming is discouraged though =p

SigKILL
09-29-2005, 05:01 AM
I was hoping I would become a 'member' when I reached 20 posts.. I was wrong..

-si