Why Matrix4x4.MultiplyPoint does row-major access while Matrix4x4 is column-major?

Hello,

says “Matrices in unity are column major.” but the implementation of Matrix4x4.MultiplyPoint seems to do row-major access by multiplying row vectors of the matrix with the column vector. What’s the reason behind this implementation?

public Vector3 MultiplyPoint(Vector3 v)
{
	Vector3 result;
	result.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03;
	result.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13;
	result.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23;
	float num = this.m30 * v.x + this.m31 * v.y + this.m32 * v.z + this.m33;
	num = 1f / num;
	result.x *= num;
	result.y *= num;
	result.z *= num;
	return result;
}

I have to admit that the internal layout is really strange but all methods / operators work on the same basis.

First of all the float values are ordered like this:

m00
m01
m02
m03
m10
...

However the declaration order has no meaning at all. They have defined an indexer which accesses them in this order:

0 -> m00
1 -> m10
2 -> m20
3 -> m30
4 -> m01
5 -> m02
...

The row / column indexer just use this logic:

this[row + column*4].

From this information we can say that the first number in the variable names referes to the row index and the second to the column index: “m(r)(c)”

m00
 ||
 |\__ column index
 \___ row index

So the first column is made up of those values: m00 m10 m20 m30

According to the indexer layout it’s column major and that’s also how it’s used. The only thing that’s actually row major is the actual memory layout of the float values in the struct. That might be necessary for the native code. However since in C# you can’t access the fields in declaration order the order of the index