Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did Doom3 switch column and row major matrices?

Tags:

c++

opengl

I've been making the valiant attempt to grok the doom 3 source code. One of the things I've stumbled across is the matrix class used throughout the rest of the solution. It's fairly simple code to follow, but there was a decision made that I haven't been able to comprehend. They decided to mix Column and Major row majors for different sizes.

  • The 3x3 Matrix is column major
  • Every other matrix is row major (I think - haven't checked them all)

Does anyone know why this decision might have been made? Since OpenGL is column major, I would think it would make sense to just use column major?

like image 831
Darkenor Avatar asked Dec 21 '11 16:12

Darkenor


People also ask

When would you use row-major vs column major?

The difference between the orders lies in which elements of an array are contiguous in memory. In row-major order, the consecutive elements of a row reside next to each other, whereas the same holds true for consecutive elements of a column in column-major order.

Is Julia column major?

Julia arrays are column major (Fortran ordered) whereas NumPy arrays are row major (C-ordered) by default.

What is the difference between row-major order and column major order?

N-dimensional arrays can also be stored in column-major or row-major layout. In column-major layout, the elements from the first (leftmost) dimension or index are contiguous in memory. In row-major, the elements from the last (rightmost) dimension or index are contiguous.

Why is it preferable to scan through an image in row-major order instead of column major order?

Reading memory in contiguous locations is faster than jumping around among locations. As a result, if the matrix is stored in row-major order, then iterating through its elements sequentially in row-major order may be faster than iterating through its elements in column-major order.


2 Answers

Like Oli Charlesworth already commented this might be a decision to improve caching behaviour. OpenGL's matrices are column major because on the client side you're more interested in the columns than the rows (the columns form the base of a coordinate system). If however the matrices are used for calculations like in physics or collision detection, a lot of operations will be row major. So this strongly depends on the kind of operations mostly performed on the matrix in question. The Doom3 engine makes heavy use of Plücker coordinates, so choosing the right memory layout has a very strong effect on overall performance and a simple switch between matrix majority may add/remove a significant number of operations involved.

like image 176
datenwolf Avatar answered Oct 21 '22 04:10

datenwolf


I can only guess:

If I remember correctly, the transformation matrix (which is 3x3) is the matrix you need most for OpenGL. Since OpenGL is column major it makes sense to keep the game-internal representation column major too, so you don't have to do additional work everytime you want to pass a 3x3 matrix to OpenGL.

Keeping the other matrices row major was probably a design decision. Maybe they've re-used code from other games which already use row major, or their programmers are just more comfortable working with it. Another possibility is that a lot of the operations they do on the other matrices predominantly make use rows instead of columns. Row major then provides you with a better memory layout and faster access times. It might also be that the file formats they use store matrices as row major.

It's a lot of "might be" and "if", but it's an approach, at least.

like image 31
s3rius Avatar answered Oct 21 '22 05:10

s3rius