From 8fe2ba31a9b10fca319d954c3af0744f2c077e69 Mon Sep 17 00:00:00 2001 From: Manuel Freiberger Date: Tue, 9 Jan 2018 23:46:36 +0100 Subject: [PATCH 1/2] Clarify the matrix layout The columns of the matrix are the images of the standard base vectors rather than the base vectors themselves. Added some description of the row-major storage format. --- doc/dox.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/dox.h b/doc/dox.h index afd6e487a..710807ae3 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -561,17 +561,24 @@ The output UV coordinate system has its origin in the lower-left corner: @endcode Use the #aiProcess_FlipUVs flag to get UV coordinates with the upper-left corner als origin. -All matrices in the library are row-major. That means that the matrices are stored row by row in memory, -which is similar to the OpenGL matrix layout. A typical 4x4 matrix including a translational part looks like this: +A typical 4x4 matrix including a translational part looks like this: @code X1 Y1 Z1 T1 X2 Y2 Z2 T2 X3 Y3 Z3 T3 0 0 0 1 @endcode -with (X1, X2, X3) being the X base vector, (Y1, Y2, Y3) being the Y base vector, (Z1, Z2, Z3) -being the Z base vector and (T1, T2, T3) being the translation part. If you want to use these matrices -in DirectX functions, you have to transpose them. +with (X1, X2, X3) being the image of the X base vector, (Y1, Y2, Y3) being the image of the +Y base vector, (Z1, Z2, Z3) being the image of the Z base vector and (T1, T2, T3) being the +translation part. +All matrices in the library are row-major. That means that the matrix elements are stored row by row in memory, +which is identical to the OpenGL matrix layout. So the above matrix is stored in memory as +[X1, Y1, Z1, T1, X2, Y2, Z2, T2, X3, Y3, Z3, T3, 0, 0, 0, 1]. If you want to use these matrices +in a framework, which expects the matrix layout to be column-major (stored along the columns), such as +DirectX or Matlab, you will have to transpose the matrix first. + +To be very precise: The transposition has nothing to do with a left-handed or right-handed coordinate system +but 'converts' between row-major and column-major storage format.
From 33ddbf9aa08297ad057d3b5e7cf3f815a1319559 Mon Sep 17 00:00:00 2001 From: Manuel Freiberger Date: Thu, 11 Jan 2018 20:58:47 +0100 Subject: [PATCH 2/2] Correct matrix layout documentation Actually, both OpenGL and DirectX specify a matrix layout where the base vectors and the translational part is consecutive in memory. OpenGL uses post-multiplication of column-vectors and stores the matrix in column-major storage format: | X1 Y1 Z1 T1 | | a | | X2 Y2 Z2 T2 | | b | | X3 Y3 Z3 T3 | | c | | 0 0 0 1 | | 1 | DirectX on the other hand uses row-major storage format but also pre-multiplication of row-vectors | a b c 1 | | X1 X2 X3 0 | | Y1 Y2 Y3 0 | | Z1 Z2 Z3 0 | | T1 T2 T3 1 | So a matrix is stored the same way in both frameworks and both times the translational part is consecutive, which is not the format that Assimp uses. --- doc/dox.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/dox.h b/doc/dox.h index 710807ae3..3215016ab 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -566,19 +566,22 @@ A typical 4x4 matrix including a translational part looks like this: X1 Y1 Z1 T1 X2 Y2 Z2 T2 X3 Y3 Z3 T3 -0 0 0 1 + 0 0 0 1 @endcode -with (X1, X2, X3) being the image of the X base vector, (Y1, Y2, Y3) being the image of the -Y base vector, (Z1, Z2, Z3) being the image of the Z base vector and (T1, T2, T3) being the -translation part. -All matrices in the library are row-major. That means that the matrix elements are stored row by row in memory, -which is identical to the OpenGL matrix layout. So the above matrix is stored in memory as -[X1, Y1, Z1, T1, X2, Y2, Z2, T2, X3, Y3, Z3, T3, 0, 0, 0, 1]. If you want to use these matrices -in a framework, which expects the matrix layout to be column-major (stored along the columns), such as -DirectX or Matlab, you will have to transpose the matrix first. +with (X1, X2, X3) being the local X base vector, (Y1, Y2, Y3) being the local +Y base vector, (Z1, Z2, Z3) being the local Z base vector and (T1, T2, T3) being the +offset of the local origin (the translational part). +All matrices in the library use row-major storage order. That means that the matrix elements are +stored row-by-row, i.e. they end up like this in memory: +[X1, Y1, Z1, T1, X2, Y2, Z2, T2, X3, Y3, Z3, T3, 0, 0, 0, 1]. -To be very precise: The transposition has nothing to do with a left-handed or right-handed coordinate system -but 'converts' between row-major and column-major storage format. +Note that this is neither the OpenGL format nor the DirectX format, because both of them specify the +matrix layout such that the translational part occupies three consecutive addresses in memory (so those +matrices end with [..., T1, T2, T3, 1]), whereas the translation in an Assimp matrix is found at +the offsets 3, 7 and 11 (spread across the matrix). You can transpose an Assimp matrix to end up with +the format that OpenGL and DirectX mandate. To be very precise: The transposition has nothing +to do with a left-handed or right-handed coordinate system but 'converts' between row-major and +column-major storage format.