Jump to content
  • Advertisement
Sign in to follow this  
Android07

Trouble with Matrix4x4 class

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to write a class for a 4x4 Matrix to use for transformations. I also have a Vector3 class and have written a method to multiply a vector by a matrix. I know that technically I need a 4D matrix of x,y,z,1. This all works fine for rotation and scaling, however when I move onto translation it doesn't seem to work, if I translate the vector 1,0,0 by 1,1,1 the result is 2,0,0. I have seen some places say that the translation should be in the bottom row others say the right column. Which should it be? Previously I used opengl to store calculate the matrix and then stored in a float array so I never had to worry about all this. Can someone help me with this, or point me to somewhere that can? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Android07
I'm trying to write a class for a 4x4 Matrix to use for transformations. I also have a Vector3 class and have written a method to multiply a vector by a matrix. I know that technically I need a 4D matrix of x,y,z,1. This all works fine for rotation and scaling, however when I move onto translation it doesn't seem to work, if I translate the vector 1,0,0 by 1,1,1 the result is 2,0,0. I have seen some places say that the translation should be in the bottom row others say the right column. Which should it be?
Previously I used opengl to store calculate the matrix and then stored in a float array so I never had to worry about all this.
Can someone help me with this, or point me to somewhere that can?

Thanks.
If you're using row-vector notation, you'll want to store the translation in the bottom row of your matrix; if you're using column-vector notation, you'll want to store it in the right-most column. Neither convention is better than the other, so just use whichever you're most comfortable with (if you're using OpenGL, you might go with column-vector notation, just to be consistent with the OpenGL documentation).

Other than that, I couldn't say why your translation is coming out wrong. You may need to post some code.

Share this post


Link to post
Share on other sites
Keep in mind this from the opengl.org FAQ:

"9.005 Are OpenGL matrices column-major or row-major?

For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix.

Column-major versus row-major is purely a notational convention. Note that post-multiplying with column-major matrices produces the same result as pre-multiplying with row-major matrices. The OpenGL Specification and the OpenGL Reference Manual both use column-major notation. You can use any notation, as long as it's clearly stated.

Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community. Column-major notation suggests that matrices are not laid out in memory as a programmer would expect."


I just went through the ordeal of getting all forwards and backwards worked out of some matrix code a couple weeks ago. I'm at work and don't have the code with me but I'll post the details tonight.

EDIT: Ok, here is what I ended up with. The matrix is layed out in memory like m00, m01, m02, m03, m10, m11... so reading the numbers as row-column, each row is contiguous and can be accessed as a vector. The first row is the x axis, the last row is the translation. (I think this is what row-major notation means)

For a matrix-vector multiply, the result x is m00*v.x + m10*v.y + m20*v.z + m30. Result y is m01*v.x + m11*v.y + m21*v.z + m31. In other words, the dot product of vector with the column. In more other words, the matrix elements you're multiplying with are NOT contiguous.

For a matrix-matrix multiply, you basically get dest.row0 = a.multvec(b.row0), and similar for the other 3 rows. Or
dest.m00 = a.m00 * b.m00 + a.m10 * b.m01 + a.m20 * b.m02 + a.m30 * b.m03,
dest.m01 = a.m01 * b.m00 + a.m11 * b.m01 + a.m21 * b.m02 + a.m31 * b.m03,
...
dest.m10 = a.m00 * b.m10 + a.m10 * b.m11 + a.m20 * b.m12 + a.m30 * b.m13,
dest.m11 = a.m01 * b.m10 + a.m11 * b.m11 + a.m21 * b.m12 + a.m31 * b.m13,
and so on. I believe that is a pre-multiply. Basically it has the same effect as if 'a' is the OpenGL current matrix, and 'b' is what you would send to glMultMatrix.

An easy test to verify which way you're going is use your own matrix code to do a multiply, glLoadMatrix the result, and render some polygons. Then glLoadMatrix one and glMultMatrix the other, and render the same polygons again.

The matrix-vector multiply is a bit trickier since there's nothing really to compare against. But it makes sense when you look at the matrix-matrix multiply. You're basically putting each axis of b "inside" the coordinate system of a. So just take the first output row and replace the elements of b with the single vector.

[Edited by - DekuTree64 on July 18, 2008 10:05:21 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!