1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 * Contains code for 4x4 matrices.
4 * \file IceMatrix4x4.cpp
5 * \author Pierre Terdiman
8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13 * DirectX-compliant, ie row-column order, ie m[Row][Col].
15 * m11 m12 m13 m14 first row.
16 * m21 m22 m23 m24 second row.
17 * m31 m32 m33 m34 third row.
18 * m41 m42 m43 m44 fourth row.
19 * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1).
20 * Stored in memory as m11 m12 m13 m14 m21...
22 * Multiplication rules:
24 * [x'y'z'1] = [xyz1][M]
26 * x' = x*m11 + y*m21 + z*m31 + m41
27 * y' = x*m12 + y*m22 + z*m32 + m42
28 * z' = x*m13 + y*m23 + z*m33 + m43
29 * 1' = 0 + 0 + 0 + m44
32 * \author Pierre Terdiman
35 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 using namespace IceMaths
;
43 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
45 * Inverts a PR matrix. (which only contains a rotation and a translation)
46 * This is faster and less subject to FPU errors than the generic inversion code.
49 * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
50 * \param dest [out] destination matrix
51 * \param src [in] source matrix
53 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54 ICEMATHS_API
void IceMaths::InvertPRMatrix(Matrix4x4
& dest
, const Matrix4x4
& src
)
56 dest
.m
[0][0] = src
.m
[0][0];
57 dest
.m
[1][0] = src
.m
[0][1];
58 dest
.m
[2][0] = src
.m
[0][2];
59 dest
.m
[3][0] = -(src
.m
[3][0]*src
.m
[0][0] + src
.m
[3][1]*src
.m
[0][1] + src
.m
[3][2]*src
.m
[0][2]);
61 dest
.m
[0][1] = src
.m
[1][0];
62 dest
.m
[1][1] = src
.m
[1][1];
63 dest
.m
[2][1] = src
.m
[1][2];
64 dest
.m
[3][1] = -(src
.m
[3][0]*src
.m
[1][0] + src
.m
[3][1]*src
.m
[1][1] + src
.m
[3][2]*src
.m
[1][2]);
66 dest
.m
[0][2] = src
.m
[2][0];
67 dest
.m
[1][2] = src
.m
[2][1];
68 dest
.m
[2][2] = src
.m
[2][2];
69 dest
.m
[3][2] = -(src
.m
[3][0]*src
.m
[2][0] + src
.m
[3][1]*src
.m
[2][1] + src
.m
[3][2]*src
.m
[2][2]);
77 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78 // Compute the cofactor of the Matrix at a specified location
79 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80 float Matrix4x4::CoFactor(udword row
, udword col
) const
82 return (( m
[(row
+1)&3][(col
+1)&3]*m
[(row
+2)&3][(col
+2)&3]*m
[(row
+3)&3][(col
+3)&3] +
83 m
[(row
+1)&3][(col
+2)&3]*m
[(row
+2)&3][(col
+3)&3]*m
[(row
+3)&3][(col
+1)&3] +
84 m
[(row
+1)&3][(col
+3)&3]*m
[(row
+2)&3][(col
+1)&3]*m
[(row
+3)&3][(col
+2)&3])
85 - (m
[(row
+3)&3][(col
+1)&3]*m
[(row
+2)&3][(col
+2)&3]*m
[(row
+1)&3][(col
+3)&3] +
86 m
[(row
+3)&3][(col
+2)&3]*m
[(row
+2)&3][(col
+3)&3]*m
[(row
+1)&3][(col
+1)&3] +
87 m
[(row
+3)&3][(col
+3)&3]*m
[(row
+2)&3][(col
+1)&3]*m
[(row
+1)&3][(col
+2)&3])) * ((row
+ col
) & 1 ? -1.0f
: +1.0f
);
90 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 // Compute the determinant of the Matrix
92 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 float Matrix4x4::Determinant() const
95 return m
[0][0] * CoFactor(0, 0) +
96 m
[0][1] * CoFactor(0, 1) +
97 m
[0][2] * CoFactor(0, 2) +
98 m
[0][3] * CoFactor(0, 3);
101 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102 // Compute the inverse of the matrix
103 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 Matrix4x4
& Matrix4x4::Invert()
106 float Det
= Determinant();
109 if(fabsf(Det
) < MATRIX4X4_EPSILON
)
110 return *this; // The matrix is not invertible! Singular case!
112 float IDet
= 1.0f
/ Det
;
114 Temp
.m
[0][0] = CoFactor(0,0) * IDet
;
115 Temp
.m
[1][0] = CoFactor(0,1) * IDet
;
116 Temp
.m
[2][0] = CoFactor(0,2) * IDet
;
117 Temp
.m
[3][0] = CoFactor(0,3) * IDet
;
118 Temp
.m
[0][1] = CoFactor(1,0) * IDet
;
119 Temp
.m
[1][1] = CoFactor(1,1) * IDet
;
120 Temp
.m
[2][1] = CoFactor(1,2) * IDet
;
121 Temp
.m
[3][1] = CoFactor(1,3) * IDet
;
122 Temp
.m
[0][2] = CoFactor(2,0) * IDet
;
123 Temp
.m
[1][2] = CoFactor(2,1) * IDet
;
124 Temp
.m
[2][2] = CoFactor(2,2) * IDet
;
125 Temp
.m
[3][2] = CoFactor(2,3) * IDet
;
126 Temp
.m
[0][3] = CoFactor(3,0) * IDet
;
127 Temp
.m
[1][3] = CoFactor(3,1) * IDet
;
128 Temp
.m
[2][3] = CoFactor(3,2) * IDet
;
129 Temp
.m
[3][3] = CoFactor(3,3) * IDet
;