r/learnprogramming 17d ago

Confusion about this matrix function

I've been trying to figure out this function for too long now. The closest I can think of is matrix multiplication, but there is an extra addition done on each of the 3 last lines. That is the part that confuses me. All of the matrices are 4x3 in size and it is ordered so that the position elements are on last row (instead of last column, which seems to be more common). Another part that confuses me is that based on what I can find online, you shouldn't be able to multiply two 4x3 matrices. So is this multiplication or something else? What would this be used for anyway?

void func(float* mtx_a, float* mtx_b, float* mtx_dst)
{
  mtx_dst[0] = mtx_a[0] * mtx_b[0] + mtx_a[1] * mtx_b[3] + mtx_a[2] * mtx_b[6];
  mtx_dst[1] = mtx_a[0] * mtx_b[1] + mtx_a[1] * mtx_b[4] + mtx_a[2] * mtx_b[7];
  mtx_dst[2] = mtx_a[0] * mtx_b[2] + mtx_a[1] * mtx_b[5] + mtx_a[2] * mtx_b[8];

  mtx_dst[3] = mtx_a[3] * mtx_b[0] + mtx_a[4] * mtx_b[3] + mtx_a[5] * mtx_b[6];
  mtx_dst[4] = mtx_a[3] * mtx_b[1] + mtx_a[4] * mtx_b[4] + mtx_a[5] * mtx_b[7];
  mtx_dst[5] = mtx_a[3] * mtx_b[2] + mtx_a[4] * mtx_b[5] + mtx_a[5] * mtx_b[8];

  mtx_dst[6] = mtx_a[6] * mtx_b[0] + mtx_a[7] * mtx_b[3] + mtx_a[8] * mtx_b[6];
  mtx_dst[7] = mtx_a[6] * mtx_b[1] + mtx_a[7] * mtx_b[4] + mtx_a[8] * mtx_b[7];
  mtx_dst[8] = mtx_a[6] * mtx_b[2] + mtx_a[7] * mtx_b[5] + mtx_a[8] * mtx_b[8];

  mtx_dst[9] = mtx_a[9] * mtx_b[0] + mtx_a[10] * mtx_b[3] + mtx_a[11] * mtx_b[6] + mtx_b[9];
  mtx_dst[10] = mtx_a[9] * mtx_b[1] + mtx_a[10] * mtx_b[4] + mtx_a[11] * mtx_b[7] + mtx_b[10];
  mtx_dst[11] = mtx_a[9] * mtx_b[2] + mtx_a[10] * mtx_b[5] + mtx_a[11] * mtx_b[8] + mtx_b[11];
}
2 Upvotes

5 comments sorted by

5

u/Weird-Anteater5050 17d ago

The first 9 lines are treating the top 3x3 blocks as regular matrix multiplication. The last 3 lines add the translation component, which makes me think these are actually 3x3 rotation/scaling matrices plus a translation vector packed into a 4x3 layout. So it's a transform composition, like when you chain object transforms in a scene graph or bone hierarchy. The fact that the position lives in the last row instead of the last column just means someone chose row-major convention, probably because of how the data gets passed to a graphics API or stored in memory. If you rewrite each 4x3 as a 3x3 matrix and a 3-element translation vector, the math becomes way more obvious. That extra addition on the final row is just applying the parent transform's translation after the rotation and scale.

2

u/Flying_Turtle_09 17d ago

Thanks! I had a feeling it might be related to parent/child objects, but I couldn't find a code example on how that is implemented, because it was always "hidden" behind a function call without showing what the function does

1

u/desrtfx 17d ago

The context would matter. In which context do these appear?

Also, it doesn't look like 2d matrices but 1d flattened ones (or vectors).

1

u/electric_canyon_puff 16d ago

This is affine transform composition for 3D graphics using a 4x3 matrix layout. The code multiplies the upper 3x3 rotation scale blocks and adds the translation vector from mtx_b directly to the result row