Not only is using column-major vs row-major counter-intuitive, Apple's documentation on "Working with Matrices" further exacerbates the confusion by their examples of "constructing" a "Translate Matrix" and a "Rotation Matrix" in 2D.
Translate Matrix Per Apple's Documentation ()
Translate A translate matrix takes the following form:
1 0 0 0 1 0 tx ty 1The simd library provides constants for identity matrices (matrices with ones along the diagonal, and zeros elsewhere). The 3 x 3 Float identity matrix is matrix_identity_float3x3.
The following function returns a simd_float3x3 matrix using the specified tx and ty translate values by setting the elements in an identity matrix:
func makeTranslationMatrix(tx: Float, ty: Float) -> simd_float3x3 { var matrix = matrix_identity_float3x3 matrix[0, 2] = tx matrix[1, 2] = ty return matrix }
My Issue with it
The line of code matrix[0, 2] = tx sets the value of the first column and the third row to tx. let translationMatrix = makeTranslationMatrix(tx: 1, ty: 3) and printing out the 2nd column print(translationMatrix.columns.2) will yield float3(0.0, 0.0, 1.0). I am very confused regarding why it is the last row that contains the translation values, rather than the column. This convention is not used when using SCNMatrix4MakeTranslation and creating a simd_float4x4 out of the SCNMatrix4 object.
var A = SCNMatrix4MakeTranslation(1,2,3)
var Asimd = simd_float4x4(A)
A.m41 // 1
A.m42 // 2
A.m43 // 3
A.m44 // 1
Asimd.columns.3 // float4(1.0, 2.0, 3.0, 1.0)
Both SCNMatrix4 and simd_float4x4 follow the column major naming convention. In the 2D example from Apple, it is the last row that contains the translation values, whereas with SCNMatrix4 and converting to simd_float4x4, it is the last column that contains the translation values. Apple's example seems to be doing the same with the Rotation Matrices as well.
What am I missing?