Search this blog

13 May, 2008

Give your matrices the right shape

Maths have been around for a while. A bit more than rendering (well to tell the whole truth, matrices are kinda "new", even if the ideas weren't, the formalization is not one of the oldests topics in mathematics, still they're way older than rendering :D). So please, respect them. MAKE YOUR MATRICES COLUMN MAJOR. There's NO other option, you can't choose, it's NOT up to you. If you're happy with that you can store four row vectors in your matrix or four column ones, that's fine, the order in memory is an implementation detail that's up to you. But basis vectors are NOT in the rows, your GetX() should not be the same as GetRow(0), GetTranslation() returns your last COLUMN, not your last row. Well let's not talk about the code I had to debug today, involving a matrix library that had them all (and wrong) GetRow(), GetXAxis(), GetX(), XAxis(), X(), Up() and GetXColumn()!!!

Chris Hecker wrote a fairly detailed article on why maths is done the way it is.

Last but not least, if your matrix is stored per-rows in memory but logically column-major has the nice advantage of being displayed correctly in your debugger, and more importantly, letting you create a 3x4 (affine) matrix with 3 vector4s that's way better than 4 vector3 (of a per-row row-major or of a per-column column-major*) as most of the times your vector3, to be SIMD friendly, will be vector4 anyway (due to alignment), and also the shaders love to use a float4[3] constant array much more than a float3[4]...

P.S. Cross-product does follow the RIGHT HAND RULE

* note: of course those two are in fact EXACTLY the same, and that's why OpenGL is column-major in a per-column order, so it's 100% compatible with all crazy libraries that are per-row in memory and logically row-major...

1 comment:

Ale said...

Thanks, really interesting!