Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / CDTestFramework / Opcode / Ice / IceMatrix4x4.h
1 /*
2  *      ICE / OPCODE - Optimized Collision Detection
3  * http://www.codercorner.com/Opcode.htm
4  * 
5  * Copyright (c) 2001-2008 Pierre Terdiman,  pierre@codercorner.com
6
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:
12
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.
16 */
17 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 /**
19  *      Contains code for 4x4 matrices.
20  *      \file           IceMatrix4x4.h
21  *      \author         Pierre Terdiman
22  *      \date           April, 4, 2000
23  */
24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
25
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27 // Include Guard
28 #ifndef __ICEMATRIX4X4_H__
29 #define __ICEMATRIX4X4_H__
30
31         // Forward declarations
32         class PRS;
33         class PR;
34
35         #define MATRIX4X4_EPSILON               (1.0e-7f)
36
37         class ICEMATHS_API Matrix4x4
38         {
39 //                              void    LUBackwardSubstitution( sdword *indx, float* b );
40 //                              void    LUDecomposition( sdword* indx, float* d );
41
42                 public:
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)
50                                                                         {
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;
55                                                                         }
56                 //! Copy constructor
57                 inline_                                         Matrix4x4(const Matrix4x4& mat)                         { CopyMemory(m, &mat.m, 16*sizeof(float));      }
58                 //! Destructor.
59                 inline_                                         ~Matrix4x4()                                                            {}
60
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)
65                                                                         {
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;
69                                                                                 return *this;
70                                                                         }
71                 //! Assign values
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)
76                                                                         {
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;
81                                                                                 return *this;
82                                                                         }
83
84                 //! Copy from a Matrix4x4
85                 inline_ void                            Copy(const Matrix4x4& source)                           { CopyMemory(m, source.m, 16*sizeof(float));    }
86
87                 // Row-column access
88                 //! Returns a row.
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];            }
90                 //! Returns a row.
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];                                            }
92                 //! Returns a row.
93                 inline_ const HPoint&           GetRow(const udword r)                          const   { return *(const HPoint*)&m[r][0];                                                                      }
94                 //! Returns a row.
95                 inline_ HPoint&                         GetRow(const udword r)                                          { return *(HPoint*)&m[r][0];                                                                            }
96                 //! Sets a row.
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;            }
98                 //! Sets a row.
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];                                            }
104                 //! Sets a column.
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;            }
106                 //! Sets a column.
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;  }
108
109                 // Translation
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;             }
120
121                 // Scale
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)
128                                                                         {
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;
132                                                                         }
133                 //! Scales from floats. Each row is multiplied by a value.
134                                 void                            Scale(float sx, float sy, float sz)
135                                                                         {
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;
139                                                                         }
140 /*
141                 //! Returns a row.
142                 inline_ HPoint          GetRow(const udword row)        const                   { return mRow[row];                                                                                                             }
143                 //! Sets a row.
144                 inline_ Matrix4x4&      SetRow(const udword row, const HPoint& p)       { mRow[row] = p;        return *this;                                                                           }
145                 //! Sets a row.
146                                                 Matrix4x4&      SetRow(const udword row, const Point& p)
147                                                 {
148                                                         m[row][0] = p.x;
149                                                         m[row][1] = p.y;
150                                                         m[row][2] = p.z;
151                                                         m[row][3] = (row != 3) ? 0.0f : 1.0f;
152                                                         return  *this;
153                                                 }
154                 //! Returns a column.
155                                                 HPoint          GetCol(const udword col)                const
156                                                 {
157                                                         HPoint  Res;
158                                                         Res.x = m[0][col];
159                                                         Res.y = m[1][col];
160                                                         Res.z = m[2][col];
161                                                         Res.w = m[3][col];
162                                                         return  Res;
163                                                 }
164                 //! Sets a column.
165                                                 Matrix4x4&      SetCol(const udword col, const HPoint& p)
166                                                 {
167                                                         m[0][col] = p.x;
168                                                         m[1][col] = p.y;
169                                                         m[2][col] = p.z;
170                                                         m[3][col] = p.w;
171                                                         return  *this;
172                                                 }
173                 //! Sets a column.
174                                                 Matrix4x4&      SetCol(const udword col, const Point& p)
175                                                 {
176                                                         m[0][col] = p.x;
177                                                         m[1][col] = p.y;
178                                                         m[2][col] = p.z;
179                                                         m[3][col] = (col != 3) ? 0.0f : 1.0f;
180                                                         return  *this;
181                                                 }
182 */
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
193                                                                         {
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;
198
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;
203
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;
208
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;
213                                                                                 return true;
214                                                                         }
215
216                 //! Checks matrix validity
217                 inline_ BOOL                            IsValid()               const
218                                                                         {
219                                                                                 for(udword j=0;j<4;j++)
220                                                                                 {
221                                                                                         for(udword i=0;i<4;i++)
222                                                                                         {
223                                                                                                 if(!IsValidFloat(m[j][i]))      return FALSE;
224                                                                                         }
225                                                                                 }
226                                                                                 return TRUE;
227                                                                         }
228
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;  }
235
236                 //! Makes a rotation matrix about an arbitrary axis
237                                 Matrix4x4&                      Rot(float angle, Point& p1, Point& p2);
238
239                 //! Transposes the matrix.
240                                 void                            Transpose()
241                                                                         {
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]);
248                                                                         }
249
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.
255                                 Matrix4x4&                      Invert();
256 //                              Matrix& ComputeAxisMatrix(Point& axis, float angle);
257
258                 // Cast operators
259                 //! Casts a Matrix4x4 to a Matrix3x3.
260                 inline_ operator                        Matrix3x3()     const
261                                                                         {
262                                                                                 return Matrix3x3(
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]);
266                                                                         }
267                 //! Casts a Matrix4x4 to a Quat.
268                                 operator                        Quat()  const;
269                 //! Casts a Matrix4x4 to a PR.
270                                 operator                        PR()    const;
271
272                 // Arithmetic operators
273                 //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4;
274                 inline_ Matrix4x4                       operator+(const Matrix4x4& mat) const
275                                                                         {
276                                                                                 return Matrix4x4(
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]);
281                                                                         }
282
283                 //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4;
284                 inline_ Matrix4x4                       operator-(const Matrix4x4& mat) const
285                                                                         {
286                                                                                 return Matrix4x4(
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]);
291                                                                         }
292
293                 //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4;
294                 inline_ Matrix4x4                       operator*(const Matrix4x4& mat) const
295                                                                         {
296                                                                                 return Matrix4x4(
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],
301
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],
306
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],
311
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]);
316                                                                         }
317
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); }
320
321                 //! Operator for Point Mul = Matrix4x4 * Point;
322                 inline_ Point                           operator*(const Point& v)               const
323                                                                         {
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]       );
327                                                                         }
328
329                 //! Operator for Matrix4x4 Scale = Matrix4x4 * float;
330                 inline_ Matrix4x4                       operator*(float s)                              const
331                                                                         {
332                                                                                 return Matrix4x4(
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);
337                                                                         }
338
339                 //! Operator for Matrix4x4 Scale = float * Matrix4x4;
340                 inline_ friend Matrix4x4        operator*(float s, const Matrix4x4& mat)
341                                                                         {
342                                                                                 return Matrix4x4(
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]);
347                                                                         }
348
349                 //! Operator for Matrix4x4 Div = Matrix4x4 / float;
350                 inline_ Matrix4x4                       operator/(float s)                              const
351                                                                         {
352                                                                                 if(s) s = 1.0f / s;
353
354                                                                                 return Matrix4x4(
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);
359                                                                         }
360
361                 //! Operator for Matrix4x4 Div = float / Matrix4x4;
362                 inline_ friend Matrix4x4        operator/(float s, const Matrix4x4& mat)
363                                                                         {
364                                                                                 return Matrix4x4(
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]);
369                                                                         }
370
371                 //! Operator for Matrix4x4 += Matrix4x4;
372                 inline_ Matrix4x4&                      operator+=(const Matrix4x4& mat)
373                                                                         {
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];
378                                                                                 return  *this;
379                                                                         }
380
381                 //! Operator for Matrix4x4 -= Matrix4x4;
382                 inline_ Matrix4x4&                      operator-=(const Matrix4x4& mat)
383                                                                         {
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];
388                                                                                 return  *this;
389                                                                         }
390
391                 //! Operator for Matrix4x4 *= Matrix4x4;
392                                 Matrix4x4&                      operator*=(const Matrix4x4& mat)
393                                                                         {
394                                                                                 HPoint TempRow;
395
396                                                                                 GetRow(0, TempRow);
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];
401
402                                                                                 GetRow(1, TempRow);
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];
407
408                                                                                 GetRow(2, TempRow);
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];
413
414                                                                                 GetRow(3, TempRow);
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];
419
420                                                                                 return  *this;
421                                                                         }
422
423                 //! Operator for Matrix4x4 *= float;
424                 inline_ Matrix4x4&              operator*=(float s)
425                                                                 {
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;
430                                                                         return  *this;
431                                                                 }
432
433                 //! Operator for Matrix4x4 /= float;
434                 inline_ Matrix4x4&              operator/=(float s)
435                                                                 {
436                                                                         if(s)  s = 1.0f / 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;
441                                                                         return  *this;
442                                                                 }
443
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];                  }
446
447                 public:
448
449                                 float                   m[4][4];
450         };
451
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)
454         {
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];
458         }
459
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)
462         {
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];
466         }
467
468         ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src);
469
470 #endif // __ICEMATRIX4X4_H__
471