2 * ICE / OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 * Contains code for 4x4 matrices.
20 * \file IceMatrix4x4.h
21 * \author Pierre Terdiman
22 * \date April, 4, 2000
24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28 #ifndef __ICEMATRIX4X4_H__
29 #define __ICEMATRIX4X4_H__
31 // Forward declarations
35 #define MATRIX4X4_EPSILON (1.0e-7f)
37 class ICEMATHS_API Matrix4x4
39 // void LUBackwardSubstitution( sdword *indx, float* b );
40 // void LUDecomposition( sdword* indx, float* d );
43 //! Empty constructor.
44 inline_ Matrix4x4() {}
45 //! Constructor from 16 values
46 inline_ Matrix4x4( float m00, float m01, float m02, float m03,
47 float m10, float m11, float m12, float m13,
48 float m20, float m21, float m22, float m23,
49 float m30, float m31, float m32, float m33)
51 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
52 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
53 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
54 m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
57 inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); }
59 inline_ ~Matrix4x4() {}
61 //! Assign values (rotation only)
62 inline_ Matrix4x4& Set( float m00, float m01, float m02,
63 float m10, float m11, float m12,
64 float m20, float m21, float m22)
66 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
67 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
68 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
72 inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03,
73 float m10, float m11, float m12, float m13,
74 float m20, float m21, float m22, float m23,
75 float m30, float m31, float m32, float m33)
77 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
78 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
79 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
80 m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
84 //! Copy from a Matrix4x4
85 inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); }
89 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]; }
91 inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; }
93 inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; }
95 inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; }
97 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; }
99 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; }
100 //! Returns a column.
101 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]; }
102 //! Returns a column.
103 inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; }
105 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; }
107 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; }
110 //! Returns the translation part of the matrix.
111 inline_ const HPoint& GetTrans() const { return GetRow(3); }
112 //! Gets the translation part of the matrix
113 inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; }
114 //! Sets the translation part of the matrix, from a Point.
115 inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; }
116 //! Sets the translation part of the matrix, from a HPoint.
117 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; }
118 //! Sets the translation part of the matrix, from floats.
119 inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; }
122 //! Sets the scale from a Point. The point is put on the diagonal.
123 inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; }
124 //! Sets the scale from floats. Values are put on the diagonal.
125 inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; }
126 //! Scales from a Point. Each row is multiplied by a component.
127 void Scale(const Point& p)
129 m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z;
130 m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z;
131 m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z;
133 //! Scales from floats. Each row is multiplied by a value.
134 void Scale(float sx, float sy, float sz)
136 m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz;
137 m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz;
138 m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz;
142 inline_ HPoint GetRow(const udword row) const { return mRow[row]; }
144 inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; }
146 Matrix4x4& SetRow(const udword row, const Point& p)
151 m[row][3] = (row != 3) ? 0.0f : 1.0f;
154 //! Returns a column.
155 HPoint GetCol(const udword col) const
165 Matrix4x4& SetCol(const udword col, const HPoint& p)
174 Matrix4x4& SetCol(const udword col, const Point& p)
179 m[3][col] = (col != 3) ? 0.0f : 1.0f;
183 //! Computes the trace. The trace is the sum of the 4 diagonal components.
184 inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; }
185 //! Computes the trace of the upper 3x3 matrix.
186 inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; }
187 //! Clears the matrix.
188 inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
189 //! Sets the identity matrix.
190 inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; }
191 //! Checks for identity
192 inline_ bool IsIdentity() const
194 if(IR(m[0][0])!=IEEE_1_0) return false;
195 if(IR(m[0][1])!=0) return false;
196 if(IR(m[0][2])!=0) return false;
197 if(IR(m[0][3])!=0) return false;
199 if(IR(m[1][0])!=0) return false;
200 if(IR(m[1][1])!=IEEE_1_0) return false;
201 if(IR(m[1][2])!=0) return false;
202 if(IR(m[1][3])!=0) return false;
204 if(IR(m[2][0])!=0) return false;
205 if(IR(m[2][1])!=0) return false;
206 if(IR(m[2][2])!=IEEE_1_0) return false;
207 if(IR(m[2][3])!=0) return false;
209 if(IR(m[3][0])!=0) return false;
210 if(IR(m[3][1])!=0) return false;
211 if(IR(m[3][2])!=0) return false;
212 if(IR(m[3][3])!=IEEE_1_0) return false;
216 //! Checks matrix validity
217 inline_ BOOL IsValid() const
219 for(udword j=0;j<4;j++)
221 for(udword i=0;i<4;i++)
223 if(!IsValidFloat(m[j][i])) return FALSE;
229 //! Sets a rotation matrix around the X axis.
230 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; }
231 //! Sets a rotation matrix around the Y axis.
232 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; }
233 //! Sets a rotation matrix around the Z axis.
234 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; }
236 //! Makes a rotation matrix about an arbitrary axis
237 Matrix4x4& Rot(float angle, Point& p1, Point& p2);
239 //! Transposes the matrix.
242 IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
243 IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
244 IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]);
245 IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]);
246 IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]);
247 IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]);
250 //! Computes a cofactor. Used for matrix inversion.
251 float CoFactor(udword row, udword col) const;
252 //! Computes the determinant of the matrix.
253 float Determinant() const;
254 //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted.
256 // Matrix& ComputeAxisMatrix(Point& axis, float angle);
259 //! Casts a Matrix4x4 to a Matrix3x3.
260 inline_ operator Matrix3x3() const
263 m[0][0], m[0][1], m[0][2],
264 m[1][0], m[1][1], m[1][2],
265 m[2][0], m[2][1], m[2][2]);
267 //! Casts a Matrix4x4 to a Quat.
268 operator Quat() const;
269 //! Casts a Matrix4x4 to a PR.
272 // Arithmetic operators
273 //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4;
274 inline_ Matrix4x4 operator+(const Matrix4x4& mat) const
277 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],
278 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],
279 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],
280 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]);
283 //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4;
284 inline_ Matrix4x4 operator-(const Matrix4x4& mat) const
287 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],
288 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],
289 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],
290 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]);
293 //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4;
294 inline_ Matrix4x4 operator*(const Matrix4x4& mat) const
297 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],
298 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],
299 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],
300 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],
302 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],
303 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],
304 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],
305 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],
307 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],
308 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],
309 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],
310 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],
312 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],
313 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],
314 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],
315 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]);
318 //! Operator for HPoint Mul = Matrix4x4 * HPoint;
319 inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); }
321 //! Operator for Point Mul = Matrix4x4 * Point;
322 inline_ Point operator*(const Point& v) const
324 return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
325 m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
326 m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] );
329 //! Operator for Matrix4x4 Scale = Matrix4x4 * float;
330 inline_ Matrix4x4 operator*(float s) const
333 m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
334 m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
335 m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
336 m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
339 //! Operator for Matrix4x4 Scale = float * Matrix4x4;
340 inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat)
343 s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3],
344 s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3],
345 s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3],
346 s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]);
349 //! Operator for Matrix4x4 Div = Matrix4x4 / float;
350 inline_ Matrix4x4 operator/(float s) const
355 m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
356 m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
357 m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
358 m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
361 //! Operator for Matrix4x4 Div = float / Matrix4x4;
362 inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat)
365 s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3],
366 s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3],
367 s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3],
368 s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]);
371 //! Operator for Matrix4x4 += Matrix4x4;
372 inline_ Matrix4x4& operator+=(const Matrix4x4& mat)
374 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];
375 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];
376 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];
377 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];
381 //! Operator for Matrix4x4 -= Matrix4x4;
382 inline_ Matrix4x4& operator-=(const Matrix4x4& mat)
384 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];
385 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];
386 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];
387 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];
391 //! Operator for Matrix4x4 *= Matrix4x4;
392 Matrix4x4& operator*=(const Matrix4x4& mat)
397 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];
398 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];
399 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];
400 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];
403 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];
404 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];
405 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];
406 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];
409 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];
410 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];
411 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];
412 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];
415 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];
416 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];
417 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];
418 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];
423 //! Operator for Matrix4x4 *= float;
424 inline_ Matrix4x4& operator*=(float s)
426 m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
427 m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
428 m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
429 m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
433 //! Operator for Matrix4x4 /= float;
434 inline_ Matrix4x4& operator/=(float s)
437 m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
438 m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
439 m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
440 m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
444 inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; }
445 inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; }
452 //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix
453 inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot)
455 dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
456 dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
457 dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
460 //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix
461 inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot)
463 dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
464 dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
465 dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
468 ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src);
470 #endif // __ICEMATRIX4X4_H__