1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
2 | /** |
---|
3 | * Contains code for 4x4 matrices. |
---|
4 | * \file IceMatrix4x4.h |
---|
5 | * \author Pierre Terdiman |
---|
6 | * \date April, 4, 2000 |
---|
7 | */ |
---|
8 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
9 | |
---|
10 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
11 | // Include Guard |
---|
12 | #ifndef __ICEMATRIX4X4_H__ |
---|
13 | #define __ICEMATRIX4X4_H__ |
---|
14 | |
---|
15 | // Forward declarations |
---|
16 | class PRS; |
---|
17 | class PR; |
---|
18 | |
---|
19 | #define MATRIX4X4_EPSILON (1.0e-7f) |
---|
20 | |
---|
21 | class ICEMATHS_API Matrix4x4 |
---|
22 | { |
---|
23 | // void LUBackwardSubstitution( sdword *indx, float* b ); |
---|
24 | // void LUDecomposition( sdword* indx, float* d ); |
---|
25 | |
---|
26 | public: |
---|
27 | //! Empty constructor. |
---|
28 | inline_ Matrix4x4() {} |
---|
29 | //! Constructor from 16 values |
---|
30 | inline_ Matrix4x4( float m00, float m01, float m02, float m03, |
---|
31 | float m10, float m11, float m12, float m13, |
---|
32 | float m20, float m21, float m22, float m23, |
---|
33 | float m30, float m31, float m32, float m33) |
---|
34 | { |
---|
35 | m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; |
---|
36 | m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; |
---|
37 | m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; |
---|
38 | m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; |
---|
39 | } |
---|
40 | //! Copy constructor |
---|
41 | inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); } |
---|
42 | //! Destructor. |
---|
43 | inline_ ~Matrix4x4() {} |
---|
44 | |
---|
45 | //! Assign values (rotation only) |
---|
46 | inline_ Matrix4x4& Set( float m00, float m01, float m02, |
---|
47 | float m10, float m11, float m12, |
---|
48 | float m20, float m21, float m22) |
---|
49 | { |
---|
50 | m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; |
---|
51 | m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; |
---|
52 | m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; |
---|
53 | return *this; |
---|
54 | } |
---|
55 | //! Assign values |
---|
56 | inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03, |
---|
57 | float m10, float m11, float m12, float m13, |
---|
58 | float m20, float m21, float m22, float m23, |
---|
59 | float m30, float m31, float m32, float m33) |
---|
60 | { |
---|
61 | m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; |
---|
62 | m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; |
---|
63 | m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; |
---|
64 | m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; |
---|
65 | return *this; |
---|
66 | } |
---|
67 | |
---|
68 | //! Copy from a Matrix4x4 |
---|
69 | inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); } |
---|
70 | |
---|
71 | // Row-column access |
---|
72 | //! Returns a row. |
---|
73 | inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; } |
---|
74 | //! Returns a row. |
---|
75 | inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; } |
---|
76 | //! Returns a row. |
---|
77 | inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; } |
---|
78 | //! Returns a row. |
---|
79 | inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; } |
---|
80 | //! Sets a row. |
---|
81 | inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; } |
---|
82 | //! Sets a row. |
---|
83 | inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; } |
---|
84 | //! Returns a column. |
---|
85 | inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; } |
---|
86 | //! Returns a column. |
---|
87 | inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; } |
---|
88 | //! Sets a column. |
---|
89 | inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; } |
---|
90 | //! Sets a column. |
---|
91 | inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; } |
---|
92 | |
---|
93 | // Translation |
---|
94 | //! Returns the translation part of the matrix. |
---|
95 | inline_ const HPoint& GetTrans() const { return GetRow(3); } |
---|
96 | //! Gets the translation part of the matrix |
---|
97 | inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; } |
---|
98 | //! Sets the translation part of the matrix, from a Point. |
---|
99 | inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; } |
---|
100 | //! Sets the translation part of the matrix, from a HPoint. |
---|
101 | inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; } |
---|
102 | //! Sets the translation part of the matrix, from floats. |
---|
103 | inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; } |
---|
104 | |
---|
105 | // Scale |
---|
106 | //! Sets the scale from a Point. The point is put on the diagonal. |
---|
107 | inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; } |
---|
108 | //! Sets the scale from floats. Values are put on the diagonal. |
---|
109 | inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; } |
---|
110 | //! Scales from a Point. Each row is multiplied by a component. |
---|
111 | void Scale(const Point& p) |
---|
112 | { |
---|
113 | m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z; |
---|
114 | m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z; |
---|
115 | m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z; |
---|
116 | } |
---|
117 | //! Scales from floats. Each row is multiplied by a value. |
---|
118 | void Scale(float sx, float sy, float sz) |
---|
119 | { |
---|
120 | m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz; |
---|
121 | m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz; |
---|
122 | m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz; |
---|
123 | } |
---|
124 | /* |
---|
125 | //! Returns a row. |
---|
126 | inline_ HPoint GetRow(const udword row) const { return mRow[row]; } |
---|
127 | //! Sets a row. |
---|
128 | inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; } |
---|
129 | //! Sets a row. |
---|
130 | Matrix4x4& SetRow(const udword row, const Point& p) |
---|
131 | { |
---|
132 | m[row][0] = p.x; |
---|
133 | m[row][1] = p.y; |
---|
134 | m[row][2] = p.z; |
---|
135 | m[row][3] = (row != 3) ? 0.0f : 1.0f; |
---|
136 | return *this; |
---|
137 | } |
---|
138 | //! Returns a column. |
---|
139 | HPoint GetCol(const udword col) const |
---|
140 | { |
---|
141 | HPoint Res; |
---|
142 | Res.x = m[0][col]; |
---|
143 | Res.y = m[1][col]; |
---|
144 | Res.z = m[2][col]; |
---|
145 | Res.w = m[3][col]; |
---|
146 | return Res; |
---|
147 | } |
---|
148 | //! Sets a column. |
---|
149 | Matrix4x4& SetCol(const udword col, const HPoint& p) |
---|
150 | { |
---|
151 | m[0][col] = p.x; |
---|
152 | m[1][col] = p.y; |
---|
153 | m[2][col] = p.z; |
---|
154 | m[3][col] = p.w; |
---|
155 | return *this; |
---|
156 | } |
---|
157 | //! Sets a column. |
---|
158 | Matrix4x4& SetCol(const udword col, const Point& p) |
---|
159 | { |
---|
160 | m[0][col] = p.x; |
---|
161 | m[1][col] = p.y; |
---|
162 | m[2][col] = p.z; |
---|
163 | m[3][col] = (col != 3) ? 0.0f : 1.0f; |
---|
164 | return *this; |
---|
165 | } |
---|
166 | */ |
---|
167 | //! Computes the trace. The trace is the sum of the 4 diagonal components. |
---|
168 | inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; } |
---|
169 | //! Computes the trace of the upper 3x3 matrix. |
---|
170 | inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; } |
---|
171 | //! Clears the matrix. |
---|
172 | inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } |
---|
173 | //! Sets the identity matrix. |
---|
174 | inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; } |
---|
175 | //! Checks for identity |
---|
176 | inline_ bool IsIdentity() const |
---|
177 | { |
---|
178 | if(IR(m[0][0])!=IEEE_1_0) return false; |
---|
179 | if(IR(m[0][1])!=0) return false; |
---|
180 | if(IR(m[0][2])!=0) return false; |
---|
181 | if(IR(m[0][3])!=0) return false; |
---|
182 | |
---|
183 | if(IR(m[1][0])!=0) return false; |
---|
184 | if(IR(m[1][1])!=IEEE_1_0) return false; |
---|
185 | if(IR(m[1][2])!=0) return false; |
---|
186 | if(IR(m[1][3])!=0) return false; |
---|
187 | |
---|
188 | if(IR(m[2][0])!=0) return false; |
---|
189 | if(IR(m[2][1])!=0) return false; |
---|
190 | if(IR(m[2][2])!=IEEE_1_0) return false; |
---|
191 | if(IR(m[2][3])!=0) return false; |
---|
192 | |
---|
193 | if(IR(m[3][0])!=0) return false; |
---|
194 | if(IR(m[3][1])!=0) return false; |
---|
195 | if(IR(m[3][2])!=0) return false; |
---|
196 | if(IR(m[3][3])!=IEEE_1_0) return false; |
---|
197 | return true; |
---|
198 | } |
---|
199 | |
---|
200 | //! Checks matrix validity |
---|
201 | inline_ BOOL IsValid() const |
---|
202 | { |
---|
203 | for(udword j=0;j<4;j++) |
---|
204 | { |
---|
205 | for(udword i=0;i<4;i++) |
---|
206 | { |
---|
207 | if(!IsValidFloat(m[j][i])) return FALSE; |
---|
208 | } |
---|
209 | } |
---|
210 | return TRUE; |
---|
211 | } |
---|
212 | |
---|
213 | //! Sets a rotation matrix around the X axis. |
---|
214 | void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; } |
---|
215 | //! Sets a rotation matrix around the Y axis. |
---|
216 | void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; } |
---|
217 | //! Sets a rotation matrix around the Z axis. |
---|
218 | void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; } |
---|
219 | |
---|
220 | //! Makes a rotation matrix about an arbitrary axis |
---|
221 | Matrix4x4& Rot(float angle, Point& p1, Point& p2); |
---|
222 | |
---|
223 | //! Transposes the matrix. |
---|
224 | void Transpose() |
---|
225 | { |
---|
226 | IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); |
---|
227 | IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); |
---|
228 | IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]); |
---|
229 | IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); |
---|
230 | IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]); |
---|
231 | IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]); |
---|
232 | } |
---|
233 | |
---|
234 | //! Computes a cofactor. Used for matrix inversion. |
---|
235 | float CoFactor(udword row, udword col) const; |
---|
236 | //! Computes the determinant of the matrix. |
---|
237 | float Determinant() const; |
---|
238 | //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted. |
---|
239 | Matrix4x4& Invert(); |
---|
240 | // Matrix& ComputeAxisMatrix(Point& axis, float angle); |
---|
241 | |
---|
242 | // Cast operators |
---|
243 | //! Casts a Matrix4x4 to a Matrix3x3. |
---|
244 | inline_ operator Matrix3x3() const |
---|
245 | { |
---|
246 | return Matrix3x3( |
---|
247 | m[0][0], m[0][1], m[0][2], |
---|
248 | m[1][0], m[1][1], m[1][2], |
---|
249 | m[2][0], m[2][1], m[2][2]); |
---|
250 | } |
---|
251 | //! Casts a Matrix4x4 to a Quat. |
---|
252 | operator Quat() const; |
---|
253 | //! Casts a Matrix4x4 to a PR. |
---|
254 | operator PR() const; |
---|
255 | |
---|
256 | // Arithmetic operators |
---|
257 | //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4; |
---|
258 | inline_ Matrix4x4 operator+(const Matrix4x4& mat) const |
---|
259 | { |
---|
260 | return Matrix4x4( |
---|
261 | m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3], |
---|
262 | m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3], |
---|
263 | m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3], |
---|
264 | m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]); |
---|
265 | } |
---|
266 | |
---|
267 | //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4; |
---|
268 | inline_ Matrix4x4 operator-(const Matrix4x4& mat) const |
---|
269 | { |
---|
270 | return Matrix4x4( |
---|
271 | m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3], |
---|
272 | m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3], |
---|
273 | m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3], |
---|
274 | m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]); |
---|
275 | } |
---|
276 | |
---|
277 | //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4; |
---|
278 | inline_ Matrix4x4 operator*(const Matrix4x4& mat) const |
---|
279 | { |
---|
280 | return Matrix4x4( |
---|
281 | m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0], |
---|
282 | m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1], |
---|
283 | m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2], |
---|
284 | m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3], |
---|
285 | |
---|
286 | m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0], |
---|
287 | m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1], |
---|
288 | m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2], |
---|
289 | m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3], |
---|
290 | |
---|
291 | m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0], |
---|
292 | m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1], |
---|
293 | m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2], |
---|
294 | m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3], |
---|
295 | |
---|
296 | m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0], |
---|
297 | m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1], |
---|
298 | m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2], |
---|
299 | m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]); |
---|
300 | } |
---|
301 | |
---|
302 | //! Operator for HPoint Mul = Matrix4x4 * HPoint; |
---|
303 | inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); } |
---|
304 | |
---|
305 | //! Operator for Point Mul = Matrix4x4 * Point; |
---|
306 | inline_ Point operator*(const Point& v) const |
---|
307 | { |
---|
308 | return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], |
---|
309 | m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], |
---|
310 | m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] ); |
---|
311 | } |
---|
312 | |
---|
313 | //! Operator for Matrix4x4 Scale = Matrix4x4 * float; |
---|
314 | inline_ Matrix4x4 operator*(float s) const |
---|
315 | { |
---|
316 | return Matrix4x4( |
---|
317 | m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, |
---|
318 | m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, |
---|
319 | m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, |
---|
320 | m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); |
---|
321 | } |
---|
322 | |
---|
323 | //! Operator for Matrix4x4 Scale = float * Matrix4x4; |
---|
324 | inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat) |
---|
325 | { |
---|
326 | return Matrix4x4( |
---|
327 | s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3], |
---|
328 | s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3], |
---|
329 | s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3], |
---|
330 | s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]); |
---|
331 | } |
---|
332 | |
---|
333 | //! Operator for Matrix4x4 Div = Matrix4x4 / float; |
---|
334 | inline_ Matrix4x4 operator/(float s) const |
---|
335 | { |
---|
336 | if(s) s = 1.0f / s; |
---|
337 | |
---|
338 | return Matrix4x4( |
---|
339 | m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, |
---|
340 | m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, |
---|
341 | m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, |
---|
342 | m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); |
---|
343 | } |
---|
344 | |
---|
345 | //! Operator for Matrix4x4 Div = float / Matrix4x4; |
---|
346 | inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat) |
---|
347 | { |
---|
348 | return Matrix4x4( |
---|
349 | s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3], |
---|
350 | s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3], |
---|
351 | s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3], |
---|
352 | s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]); |
---|
353 | } |
---|
354 | |
---|
355 | //! Operator for Matrix4x4 += Matrix4x4; |
---|
356 | inline_ Matrix4x4& operator+=(const Matrix4x4& mat) |
---|
357 | { |
---|
358 | m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3]; |
---|
359 | m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3]; |
---|
360 | m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3]; |
---|
361 | m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3]; |
---|
362 | return *this; |
---|
363 | } |
---|
364 | |
---|
365 | //! Operator for Matrix4x4 -= Matrix4x4; |
---|
366 | inline_ Matrix4x4& operator-=(const Matrix4x4& mat) |
---|
367 | { |
---|
368 | m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3]; |
---|
369 | m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3]; |
---|
370 | m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3]; |
---|
371 | m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3]; |
---|
372 | return *this; |
---|
373 | } |
---|
374 | |
---|
375 | //! Operator for Matrix4x4 *= Matrix4x4; |
---|
376 | Matrix4x4& operator*=(const Matrix4x4& mat) |
---|
377 | { |
---|
378 | HPoint TempRow; |
---|
379 | |
---|
380 | GetRow(0, TempRow); |
---|
381 | m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; |
---|
382 | m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; |
---|
383 | m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; |
---|
384 | m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; |
---|
385 | |
---|
386 | GetRow(1, TempRow); |
---|
387 | m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; |
---|
388 | m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; |
---|
389 | m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; |
---|
390 | m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; |
---|
391 | |
---|
392 | GetRow(2, TempRow); |
---|
393 | m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; |
---|
394 | m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; |
---|
395 | m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; |
---|
396 | m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; |
---|
397 | |
---|
398 | GetRow(3, TempRow); |
---|
399 | m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; |
---|
400 | m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; |
---|
401 | m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; |
---|
402 | m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; |
---|
403 | |
---|
404 | return *this; |
---|
405 | } |
---|
406 | |
---|
407 | //! Operator for Matrix4x4 *= float; |
---|
408 | inline_ Matrix4x4& operator*=(float s) |
---|
409 | { |
---|
410 | m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; |
---|
411 | m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; |
---|
412 | m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; |
---|
413 | m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; |
---|
414 | return *this; |
---|
415 | } |
---|
416 | |
---|
417 | //! Operator for Matrix4x4 /= float; |
---|
418 | inline_ Matrix4x4& operator/=(float s) |
---|
419 | { |
---|
420 | if(s) s = 1.0f / s; |
---|
421 | m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; |
---|
422 | m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; |
---|
423 | m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; |
---|
424 | m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; |
---|
425 | return *this; |
---|
426 | } |
---|
427 | |
---|
428 | inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; } |
---|
429 | inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; } |
---|
430 | |
---|
431 | public: |
---|
432 | |
---|
433 | float m[4][4]; |
---|
434 | }; |
---|
435 | |
---|
436 | //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix |
---|
437 | inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot) |
---|
438 | { |
---|
439 | dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; |
---|
440 | dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; |
---|
441 | dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; |
---|
442 | } |
---|
443 | |
---|
444 | //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix |
---|
445 | inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot) |
---|
446 | { |
---|
447 | dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; |
---|
448 | dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; |
---|
449 | dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; |
---|
450 | } |
---|
451 | |
---|
452 | ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src); |
---|
453 | |
---|
454 | #endif // __ICEMATRIX4X4_H__ |
---|
455 | |
---|