- Home /
Why Matrix4x4.MultiplyPoint does row-major access while Matrix4x4 is column-major?
Hello, http://docs.unity3d.com/ScriptReference/Matrix4x4.html 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;
}
Answer by Bunny83 · Jun 09, 2015 at 05:45 AM
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
The floats are not stored in row-major order (m00, m01, m02, m03...), they are stored in column-major order (m00, m10, m20, m30, ...). You can verify this with ilspy/dnspy or by casting a $$anonymous$$atrix4x4* to a float* and exa$$anonymous$$ing it in detail.
Thus, it does make sense: indexing and underlying storage are both column-major.