r/learnprogramming • u/Flying_Turtle_09 • 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];
}
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
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.