doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Matrix.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __MATH_MATRIX_H__
30 #define __MATH_MATRIX_H__
31 
32 /*
33 ===============================================================================
34 
35  Matrix classes, all matrices are row-major except idMat3
36 
37 ===============================================================================
38 */
39 
40 #define MATRIX_INVERSE_EPSILON 1e-14
41 #define MATRIX_EPSILON 1e-6
42 
43 class idAngles;
44 class idQuat;
45 class idCQuat;
46 class idRotation;
47 class idMat4;
48 
49 //===============================================================
50 //
51 // idMat2 - 2x2 matrix
52 //
53 //===============================================================
54 
55 class idMat2 {
56 public:
57  idMat2( void );
58  explicit idMat2( const idVec2 &x, const idVec2 &y );
59  explicit idMat2( const float xx, const float xy, const float yx, const float yy );
60  explicit idMat2( const float src[ 2 ][ 2 ] );
61 
62  const idVec2 & operator[]( int index ) const;
63  idVec2 & operator[]( int index );
64  idMat2 operator-() const;
65  idMat2 operator*( const float a ) const;
66  idVec2 operator*( const idVec2 &vec ) const;
67  idMat2 operator*( const idMat2 &a ) const;
68  idMat2 operator+( const idMat2 &a ) const;
69  idMat2 operator-( const idMat2 &a ) const;
70  idMat2 & operator*=( const float a );
71  idMat2 & operator*=( const idMat2 &a );
72  idMat2 & operator+=( const idMat2 &a );
73  idMat2 & operator-=( const idMat2 &a );
74 
75  friend idMat2 operator*( const float a, const idMat2 &mat );
76  friend idVec2 operator*( const idVec2 &vec, const idMat2 &mat );
77  friend idVec2 & operator*=( idVec2 &vec, const idMat2 &mat );
78 
79  bool Compare( const idMat2 &a ) const; // exact compare, no epsilon
80  bool Compare( const idMat2 &a, const float epsilon ) const; // compare with epsilon
81  bool operator==( const idMat2 &a ) const; // exact compare, no epsilon
82  bool operator!=( const idMat2 &a ) const; // exact compare, no epsilon
83 
84  void Zero( void );
85  void Identity( void );
86  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
87  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
88  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
89 
90  float Trace( void ) const;
91  float Determinant( void ) const;
92  idMat2 Transpose( void ) const; // returns transpose
93  idMat2 & TransposeSelf( void );
94  idMat2 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
95  bool InverseSelf( void ); // returns false if determinant is zero
96  idMat2 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
97  bool InverseFastSelf( void ); // returns false if determinant is zero
98 
99  int GetDimension( void ) const;
100 
101  const float * ToFloatPtr( void ) const;
102  float * ToFloatPtr( void );
103  const char * ToString( int precision = 2 ) const;
104 
105 private:
106  idVec2 mat[ 2 ];
107 };
108 
109 extern idMat2 mat2_zero;
110 extern idMat2 mat2_identity;
111 #define mat2_default mat2_identity
112 
113 ID_INLINE idMat2::idMat2( void ) {
114 }
115 
116 ID_INLINE idMat2::idMat2( const idVec2 &x, const idVec2 &y ) {
117  mat[ 0 ].x = x.x; mat[ 0 ].y = x.y;
118  mat[ 1 ].x = y.x; mat[ 1 ].y = y.y;
119 }
120 
121 ID_INLINE idMat2::idMat2( const float xx, const float xy, const float yx, const float yy ) {
122  mat[ 0 ].x = xx; mat[ 0 ].y = xy;
123  mat[ 1 ].x = yx; mat[ 1 ].y = yy;
124 }
125 
126 ID_INLINE idMat2::idMat2( const float src[ 2 ][ 2 ] ) {
127  memcpy( mat, src, 2 * 2 * sizeof( float ) );
128 }
129 
130 ID_INLINE const idVec2 &idMat2::operator[]( int index ) const {
131  //assert( ( index >= 0 ) && ( index < 2 ) );
132  return mat[ index ];
133 }
134 
135 ID_INLINE idVec2 &idMat2::operator[]( int index ) {
136  //assert( ( index >= 0 ) && ( index < 2 ) );
137  return mat[ index ];
138 }
139 
140 ID_INLINE idMat2 idMat2::operator-() const {
141  return idMat2( -mat[0][0], -mat[0][1],
142  -mat[1][0], -mat[1][1] );
143 }
144 
145 ID_INLINE idVec2 idMat2::operator*( const idVec2 &vec ) const {
146  return idVec2(
147  mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y,
148  mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y );
149 }
150 
151 ID_INLINE idMat2 idMat2::operator*( const idMat2 &a ) const {
152  return idMat2(
153  mat[0].x * a[0].x + mat[0].y * a[1].x,
154  mat[0].x * a[0].y + mat[0].y * a[1].y,
155  mat[1].x * a[0].x + mat[1].y * a[1].x,
156  mat[1].x * a[0].y + mat[1].y * a[1].y );
157 }
158 
159 ID_INLINE idMat2 idMat2::operator*( const float a ) const {
160  return idMat2(
161  mat[0].x * a, mat[0].y * a,
162  mat[1].x * a, mat[1].y * a );
163 }
164 
165 ID_INLINE idMat2 idMat2::operator+( const idMat2 &a ) const {
166  return idMat2(
167  mat[0].x + a[0].x, mat[0].y + a[0].y,
168  mat[1].x + a[1].x, mat[1].y + a[1].y );
169 }
170 
171 ID_INLINE idMat2 idMat2::operator-( const idMat2 &a ) const {
172  return idMat2(
173  mat[0].x - a[0].x, mat[0].y - a[0].y,
174  mat[1].x - a[1].x, mat[1].y - a[1].y );
175 }
176 
177 ID_INLINE idMat2 &idMat2::operator*=( const float a ) {
178  mat[0].x *= a; mat[0].y *= a;
179  mat[1].x *= a; mat[1].y *= a;
180 
181  return *this;
182 }
183 
184 ID_INLINE idMat2 &idMat2::operator*=( const idMat2 &a ) {
185  float x, y;
186  x = mat[0].x; y = mat[0].y;
187  mat[0].x = x * a[0].x + y * a[1].x;
188  mat[0].y = x * a[0].y + y * a[1].y;
189  x = mat[1].x; y = mat[1].y;
190  mat[1].x = x * a[0].x + y * a[1].x;
191  mat[1].y = x * a[0].y + y * a[1].y;
192  return *this;
193 }
194 
195 ID_INLINE idMat2 &idMat2::operator+=( const idMat2 &a ) {
196  mat[0].x += a[0].x; mat[0].y += a[0].y;
197  mat[1].x += a[1].x; mat[1].y += a[1].y;
198 
199  return *this;
200 }
201 
202 ID_INLINE idMat2 &idMat2::operator-=( const idMat2 &a ) {
203  mat[0].x -= a[0].x; mat[0].y -= a[0].y;
204  mat[1].x -= a[1].x; mat[1].y -= a[1].y;
205 
206  return *this;
207 }
208 
209 ID_INLINE idVec2 operator*( const idVec2 &vec, const idMat2 &mat ) {
210  return mat * vec;
211 }
212 
213 ID_INLINE idMat2 operator*( const float a, idMat2 const &mat ) {
214  return mat * a;
215 }
216 
217 ID_INLINE idVec2 &operator*=( idVec2 &vec, const idMat2 &mat ) {
218  vec = mat * vec;
219  return vec;
220 }
221 
222 ID_INLINE bool idMat2::Compare( const idMat2 &a ) const {
223  if ( mat[0].Compare( a[0] ) &&
224  mat[1].Compare( a[1] ) ) {
225  return true;
226  }
227  return false;
228 }
229 
230 ID_INLINE bool idMat2::Compare( const idMat2 &a, const float epsilon ) const {
231  if ( mat[0].Compare( a[0], epsilon ) &&
232  mat[1].Compare( a[1], epsilon ) ) {
233  return true;
234  }
235  return false;
236 }
237 
238 ID_INLINE bool idMat2::operator==( const idMat2 &a ) const {
239  return Compare( a );
240 }
241 
242 ID_INLINE bool idMat2::operator!=( const idMat2 &a ) const {
243  return !Compare( a );
244 }
245 
246 ID_INLINE void idMat2::Zero( void ) {
247  mat[0].Zero();
248  mat[1].Zero();
249 }
250 
251 ID_INLINE void idMat2::Identity( void ) {
252  *this = mat2_identity;
253 }
254 
255 ID_INLINE bool idMat2::IsIdentity( const float epsilon ) const {
256  return Compare( mat2_identity, epsilon );
257 }
258 
259 ID_INLINE bool idMat2::IsSymmetric( const float epsilon ) const {
260  return ( idMath::Fabs( mat[0][1] - mat[1][0] ) < epsilon );
261 }
262 
263 ID_INLINE bool idMat2::IsDiagonal( const float epsilon ) const {
264  if ( idMath::Fabs( mat[0][1] ) > epsilon ||
265  idMath::Fabs( mat[1][0] ) > epsilon ) {
266  return false;
267  }
268  return true;
269 }
270 
271 ID_INLINE float idMat2::Trace( void ) const {
272  return ( mat[0][0] + mat[1][1] );
273 }
274 
275 ID_INLINE float idMat2::Determinant( void ) const {
276  return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
277 }
278 
279 ID_INLINE idMat2 idMat2::Transpose( void ) const {
280  return idMat2( mat[0][0], mat[1][0],
281  mat[0][1], mat[1][1] );
282 }
283 
284 ID_INLINE idMat2 &idMat2::TransposeSelf( void ) {
285  float tmp;
286 
287  tmp = mat[0][1];
288  mat[0][1] = mat[1][0];
289  mat[1][0] = tmp;
290 
291  return *this;
292 }
293 
294 ID_INLINE idMat2 idMat2::Inverse( void ) const {
295  idMat2 invMat;
296 
297  invMat = *this;
298  int r = invMat.InverseSelf();
299  assert( r );
300  return invMat;
301 }
302 
303 ID_INLINE idMat2 idMat2::InverseFast( void ) const {
304  idMat2 invMat;
305 
306  invMat = *this;
307  int r = invMat.InverseFastSelf();
308  assert( r );
309  return invMat;
310 }
311 
312 ID_INLINE int idMat2::GetDimension( void ) const {
313  return 4;
314 }
315 
316 ID_INLINE const float *idMat2::ToFloatPtr( void ) const {
317  return mat[0].ToFloatPtr();
318 }
319 
320 ID_INLINE float *idMat2::ToFloatPtr( void ) {
321  return mat[0].ToFloatPtr();
322 }
323 
324 
325 //===============================================================
326 //
327 // idMat3 - 3x3 matrix
328 //
329 // NOTE: matrix is column-major
330 //
331 //===============================================================
332 
333 class idMat3 {
334 public:
335  idMat3( void );
336  explicit idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z );
337  explicit idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz );
338  explicit idMat3( const float src[ 3 ][ 3 ] );
339 
340  const idVec3 & operator[]( int index ) const;
341  idVec3 & operator[]( int index );
342  idMat3 operator-() const;
343  idMat3 operator*( const float a ) const;
344  idVec3 operator*( const idVec3 &vec ) const;
345  idMat3 operator*( const idMat3 &a ) const;
346  idMat3 operator+( const idMat3 &a ) const;
347  idMat3 operator-( const idMat3 &a ) const;
348  idMat3 & operator*=( const float a );
349  idMat3 & operator*=( const idMat3 &a );
350  idMat3 & operator+=( const idMat3 &a );
351  idMat3 & operator-=( const idMat3 &a );
352 
353  friend idMat3 operator*( const float a, const idMat3 &mat );
354  friend idVec3 operator*( const idVec3 &vec, const idMat3 &mat );
355  friend idVec3 & operator*=( idVec3 &vec, const idMat3 &mat );
356 
357  bool Compare( const idMat3 &a ) const; // exact compare, no epsilon
358  bool Compare( const idMat3 &a, const float epsilon ) const; // compare with epsilon
359  bool operator==( const idMat3 &a ) const; // exact compare, no epsilon
360  bool operator!=( const idMat3 &a ) const; // exact compare, no epsilon
361 
362  void Zero( void );
363  void Identity( void );
364  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
365  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
366  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
367  bool IsRotated( void ) const;
368 
369  void ProjectVector( const idVec3 &src, idVec3 &dst ) const;
370  void UnprojectVector( const idVec3 &src, idVec3 &dst ) const;
371 
372  bool FixDegeneracies( void ); // fix degenerate axial cases
373  bool FixDenormals( void ); // change tiny numbers to zero
374 
375  float Trace( void ) const;
376  float Determinant( void ) const;
377  idMat3 OrthoNormalize( void ) const;
378  idMat3 & OrthoNormalizeSelf( void );
379  idMat3 Transpose( void ) const; // returns transpose
380  idMat3 & TransposeSelf( void );
381  idMat3 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
382  bool InverseSelf( void ); // returns false if determinant is zero
383  idMat3 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
384  bool InverseFastSelf( void ); // returns false if determinant is zero
385  idMat3 TransposeMultiply( const idMat3 &b ) const;
386 
387  idMat3 InertiaTranslate( const float mass, const idVec3 &centerOfMass, const idVec3 &translation ) const;
388  idMat3 & InertiaTranslateSelf( const float mass, const idVec3 &centerOfMass, const idVec3 &translation );
389  idMat3 InertiaRotate( const idMat3 &rotation ) const;
390  idMat3 & InertiaRotateSelf( const idMat3 &rotation );
391 
392  int GetDimension( void ) const;
393 
394  idAngles ToAngles( void ) const;
395  idQuat ToQuat( void ) const;
396  idCQuat ToCQuat( void ) const;
397  idRotation ToRotation( void ) const;
398  idMat4 ToMat4( void ) const;
399  idVec3 ToAngularVelocity( void ) const;
400  const float * ToFloatPtr( void ) const;
401  float * ToFloatPtr( void );
402  const char * ToString( int precision = 2 ) const;
403 
404  friend void TransposeMultiply( const idMat3 &inv, const idMat3 &b, idMat3 &dst );
405  friend idMat3 SkewSymmetric( idVec3 const &src );
406 
407 private:
408  idVec3 mat[ 3 ];
409 };
410 
411 extern idMat3 mat3_zero;
412 extern idMat3 mat3_identity;
413 #define mat3_default mat3_identity
414 
415 ID_INLINE idMat3::idMat3( void ) {
416 }
417 
418 ID_INLINE idMat3::idMat3( const idVec3 &x, const idVec3 &y, const idVec3 &z ) {
419  mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z;
420  mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z;
421  mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z;
422 }
423 
424 ID_INLINE idMat3::idMat3( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) {
425  mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz;
426  mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz;
427  mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz;
428 }
429 
430 ID_INLINE idMat3::idMat3( const float src[ 3 ][ 3 ] ) {
431  memcpy( mat, src, 3 * 3 * sizeof( float ) );
432 }
433 
434 ID_INLINE const idVec3 &idMat3::operator[]( int index ) const {
435  //assert( ( index >= 0 ) && ( index < 3 ) );
436  return mat[ index ];
437 }
438 
439 ID_INLINE idVec3 &idMat3::operator[]( int index ) {
440  //assert( ( index >= 0 ) && ( index < 3 ) );
441  return mat[ index ];
442 }
443 
444 ID_INLINE idMat3 idMat3::operator-() const {
445  return idMat3( -mat[0][0], -mat[0][1], -mat[0][2],
446  -mat[1][0], -mat[1][1], -mat[1][2],
447  -mat[2][0], -mat[2][1], -mat[2][2] );
448 }
449 
450 ID_INLINE idVec3 idMat3::operator*( const idVec3 &vec ) const {
451  return idVec3(
452  mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z,
453  mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z,
454  mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z );
455 }
456 
457 ID_INLINE idMat3 idMat3::operator*( const idMat3 &a ) const {
458  int i, j;
459  const float *m1Ptr, *m2Ptr;
460  float *dstPtr;
461  idMat3 dst;
462 
463  m1Ptr = reinterpret_cast<const float *>(this);
464  m2Ptr = reinterpret_cast<const float *>(&a);
465  dstPtr = reinterpret_cast<float *>(&dst);
466 
467  for ( i = 0; i < 3; i++ ) {
468  for ( j = 0; j < 3; j++ ) {
469  *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 3 + j ]
470  + m1Ptr[1] * m2Ptr[ 1 * 3 + j ]
471  + m1Ptr[2] * m2Ptr[ 2 * 3 + j ];
472  dstPtr++;
473  }
474  m1Ptr += 3;
475  }
476  return dst;
477 }
478 
479 ID_INLINE idMat3 idMat3::operator*( const float a ) const {
480  return idMat3(
481  mat[0].x * a, mat[0].y * a, mat[0].z * a,
482  mat[1].x * a, mat[1].y * a, mat[1].z * a,
483  mat[2].x * a, mat[2].y * a, mat[2].z * a );
484 }
485 
486 ID_INLINE idMat3 idMat3::operator+( const idMat3 &a ) const {
487  return idMat3(
488  mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z,
489  mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z,
490  mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z );
491 }
492 
493 ID_INLINE idMat3 idMat3::operator-( const idMat3 &a ) const {
494  return idMat3(
495  mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z,
496  mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z,
497  mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z );
498 }
499 
500 ID_INLINE idMat3 &idMat3::operator*=( const float a ) {
501  mat[0].x *= a; mat[0].y *= a; mat[0].z *= a;
502  mat[1].x *= a; mat[1].y *= a; mat[1].z *= a;
503  mat[2].x *= a; mat[2].y *= a; mat[2].z *= a;
504 
505  return *this;
506 }
507 
508 ID_INLINE idMat3 &idMat3::operator*=( const idMat3 &a ) {
509  int i, j;
510  const float *m2Ptr;
511  float *m1Ptr, dst[3];
512 
513  m1Ptr = reinterpret_cast<float *>(this);
514  m2Ptr = reinterpret_cast<const float *>(&a);
515 
516  for ( i = 0; i < 3; i++ ) {
517  for ( j = 0; j < 3; j++ ) {
518  dst[j] = m1Ptr[0] * m2Ptr[ 0 * 3 + j ]
519  + m1Ptr[1] * m2Ptr[ 1 * 3 + j ]
520  + m1Ptr[2] * m2Ptr[ 2 * 3 + j ];
521  }
522  m1Ptr[0] = dst[0]; m1Ptr[1] = dst[1]; m1Ptr[2] = dst[2];
523  m1Ptr += 3;
524  }
525  return *this;
526 }
527 
528 ID_INLINE idMat3 &idMat3::operator+=( const idMat3 &a ) {
529  mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z;
530  mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z;
531  mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z;
532 
533  return *this;
534 }
535 
536 ID_INLINE idMat3 &idMat3::operator-=( const idMat3 &a ) {
537  mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z;
538  mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z;
539  mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z;
540 
541  return *this;
542 }
543 
544 ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat3 &mat ) {
545  return mat * vec;
546 }
547 
548 ID_INLINE idMat3 operator*( const float a, const idMat3 &mat ) {
549  return mat * a;
550 }
551 
552 ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat3 &mat ) {
553  float x = mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z;
554  float y = mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z;
555  vec.z = mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z;
556  vec.x = x;
557  vec.y = y;
558  return vec;
559 }
560 
561 ID_INLINE bool idMat3::Compare( const idMat3 &a ) const {
562  if ( mat[0].Compare( a[0] ) &&
563  mat[1].Compare( a[1] ) &&
564  mat[2].Compare( a[2] ) ) {
565  return true;
566  }
567  return false;
568 }
569 
570 ID_INLINE bool idMat3::Compare( const idMat3 &a, const float epsilon ) const {
571  if ( mat[0].Compare( a[0], epsilon ) &&
572  mat[1].Compare( a[1], epsilon ) &&
573  mat[2].Compare( a[2], epsilon ) ) {
574  return true;
575  }
576  return false;
577 }
578 
579 ID_INLINE bool idMat3::operator==( const idMat3 &a ) const {
580  return Compare( a );
581 }
582 
583 ID_INLINE bool idMat3::operator!=( const idMat3 &a ) const {
584  return !Compare( a );
585 }
586 
587 ID_INLINE void idMat3::Zero( void ) {
588  memset( mat, 0, sizeof( idMat3 ) );
589 }
590 
591 ID_INLINE void idMat3::Identity( void ) {
592  *this = mat3_identity;
593 }
594 
595 ID_INLINE bool idMat3::IsIdentity( const float epsilon ) const {
596  return Compare( mat3_identity, epsilon );
597 }
598 
599 ID_INLINE bool idMat3::IsSymmetric( const float epsilon ) const {
600  if ( idMath::Fabs( mat[0][1] - mat[1][0] ) > epsilon ) {
601  return false;
602  }
603  if ( idMath::Fabs( mat[0][2] - mat[2][0] ) > epsilon ) {
604  return false;
605  }
606  if ( idMath::Fabs( mat[1][2] - mat[2][1] ) > epsilon ) {
607  return false;
608  }
609  return true;
610 }
611 
612 ID_INLINE bool idMat3::IsDiagonal( const float epsilon ) const {
613  if ( idMath::Fabs( mat[0][1] ) > epsilon ||
614  idMath::Fabs( mat[0][2] ) > epsilon ||
615  idMath::Fabs( mat[1][0] ) > epsilon ||
616  idMath::Fabs( mat[1][2] ) > epsilon ||
617  idMath::Fabs( mat[2][0] ) > epsilon ||
618  idMath::Fabs( mat[2][1] ) > epsilon ) {
619  return false;
620  }
621  return true;
622 }
623 
624 ID_INLINE bool idMat3::IsRotated( void ) const {
625  return !Compare( mat3_identity );
626 }
627 
628 ID_INLINE void idMat3::ProjectVector( const idVec3 &src, idVec3 &dst ) const {
629  dst.x = src * mat[ 0 ];
630  dst.y = src * mat[ 1 ];
631  dst.z = src * mat[ 2 ];
632 }
633 
634 ID_INLINE void idMat3::UnprojectVector( const idVec3 &src, idVec3 &dst ) const {
635  dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z;
636 }
637 
638 ID_INLINE bool idMat3::FixDegeneracies( void ) {
639  bool r = mat[0].FixDegenerateNormal();
640  r |= mat[1].FixDegenerateNormal();
641  r |= mat[2].FixDegenerateNormal();
642  return r;
643 }
644 
645 ID_INLINE bool idMat3::FixDenormals( void ) {
646  bool r = mat[0].FixDenormals();
647  r |= mat[1].FixDenormals();
648  r |= mat[2].FixDenormals();
649  return r;
650 }
651 
652 ID_INLINE float idMat3::Trace( void ) const {
653  return ( mat[0][0] + mat[1][1] + mat[2][2] );
654 }
655 
656 ID_INLINE idMat3 idMat3::OrthoNormalize( void ) const {
657  idMat3 ortho;
658 
659  ortho = *this;
660  ortho[ 0 ].Normalize();
661  ortho[ 2 ].Cross( mat[ 0 ], mat[ 1 ] );
662  ortho[ 2 ].Normalize();
663  ortho[ 1 ].Cross( mat[ 2 ], mat[ 0 ] );
664  ortho[ 1 ].Normalize();
665  return ortho;
666 }
667 
668 ID_INLINE idMat3 &idMat3::OrthoNormalizeSelf( void ) {
669  mat[ 0 ].Normalize();
670  mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] );
671  mat[ 2 ].Normalize();
672  mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] );
673  mat[ 1 ].Normalize();
674  return *this;
675 }
676 
677 ID_INLINE idMat3 idMat3::Transpose( void ) const {
678  return idMat3( mat[0][0], mat[1][0], mat[2][0],
679  mat[0][1], mat[1][1], mat[2][1],
680  mat[0][2], mat[1][2], mat[2][2] );
681 }
682 
683 ID_INLINE idMat3 &idMat3::TransposeSelf( void ) {
684  float tmp0, tmp1, tmp2;
685 
686  tmp0 = mat[0][1];
687  mat[0][1] = mat[1][0];
688  mat[1][0] = tmp0;
689  tmp1 = mat[0][2];
690  mat[0][2] = mat[2][0];
691  mat[2][0] = tmp1;
692  tmp2 = mat[1][2];
693  mat[1][2] = mat[2][1];
694  mat[2][1] = tmp2;
695 
696  return *this;
697 }
698 
699 ID_INLINE idMat3 idMat3::Inverse( void ) const {
700  idMat3 invMat;
701 
702  invMat = *this;
703  int r = invMat.InverseSelf();
704  assert( r );
705  return invMat;
706 }
707 
708 ID_INLINE idMat3 idMat3::InverseFast( void ) const {
709  idMat3 invMat;
710 
711  invMat = *this;
712  int r = invMat.InverseFastSelf();
713  assert( r );
714  return invMat;
715 }
716 
717 ID_INLINE idMat3 idMat3::TransposeMultiply( const idMat3 &b ) const {
718  return idMat3( mat[0].x * b[0].x + mat[1].x * b[1].x + mat[2].x * b[2].x,
719  mat[0].x * b[0].y + mat[1].x * b[1].y + mat[2].x * b[2].y,
720  mat[0].x * b[0].z + mat[1].x * b[1].z + mat[2].x * b[2].z,
721  mat[0].y * b[0].x + mat[1].y * b[1].x + mat[2].y * b[2].x,
722  mat[0].y * b[0].y + mat[1].y * b[1].y + mat[2].y * b[2].y,
723  mat[0].y * b[0].z + mat[1].y * b[1].z + mat[2].y * b[2].z,
724  mat[0].z * b[0].x + mat[1].z * b[1].x + mat[2].z * b[2].x,
725  mat[0].z * b[0].y + mat[1].z * b[1].y + mat[2].z * b[2].y,
726  mat[0].z * b[0].z + mat[1].z * b[1].z + mat[2].z * b[2].z );
727 }
728 
729 ID_INLINE void TransposeMultiply( const idMat3 &transpose, const idMat3 &b, idMat3 &dst ) {
730  dst[0].x = transpose[0].x * b[0].x + transpose[1].x * b[1].x + transpose[2].x * b[2].x;
731  dst[0].y = transpose[0].x * b[0].y + transpose[1].x * b[1].y + transpose[2].x * b[2].y;
732  dst[0].z = transpose[0].x * b[0].z + transpose[1].x * b[1].z + transpose[2].x * b[2].z;
733  dst[1].x = transpose[0].y * b[0].x + transpose[1].y * b[1].x + transpose[2].y * b[2].x;
734  dst[1].y = transpose[0].y * b[0].y + transpose[1].y * b[1].y + transpose[2].y * b[2].y;
735  dst[1].z = transpose[0].y * b[0].z + transpose[1].y * b[1].z + transpose[2].y * b[2].z;
736  dst[2].x = transpose[0].z * b[0].x + transpose[1].z * b[1].x + transpose[2].z * b[2].x;
737  dst[2].y = transpose[0].z * b[0].y + transpose[1].z * b[1].y + transpose[2].z * b[2].y;
738  dst[2].z = transpose[0].z * b[0].z + transpose[1].z * b[1].z + transpose[2].z * b[2].z;
739 }
740 
741 ID_INLINE idMat3 SkewSymmetric( idVec3 const &src ) {
742  return idMat3( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f );
743 }
744 
745 ID_INLINE int idMat3::GetDimension( void ) const {
746  return 9;
747 }
748 
749 ID_INLINE const float *idMat3::ToFloatPtr( void ) const {
750  return mat[0].ToFloatPtr();
751 }
752 
753 ID_INLINE float *idMat3::ToFloatPtr( void ) {
754  return mat[0].ToFloatPtr();
755 }
756 
757 
758 //===============================================================
759 //
760 // idMat4 - 4x4 matrix
761 //
762 //===============================================================
763 
764 class idMat4 {
765 public:
766  idMat4( void );
767  explicit idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w );
768  explicit idMat4(const float xx, const float xy, const float xz, const float xw,
769  const float yx, const float yy, const float yz, const float yw,
770  const float zx, const float zy, const float zz, const float zw,
771  const float wx, const float wy, const float wz, const float ww );
772  explicit idMat4( const idMat3 &rotation, const idVec3 &translation );
773  explicit idMat4( const float src[ 4 ][ 4 ] );
774 
775  const idVec4 & operator[]( int index ) const;
776  idVec4 & operator[]( int index );
777  idMat4 operator*( const float a ) const;
778  idVec4 operator*( const idVec4 &vec ) const;
779  idVec3 operator*( const idVec3 &vec ) const;
780  idMat4 operator*( const idMat4 &a ) const;
781  idMat4 operator+( const idMat4 &a ) const;
782  idMat4 operator-( const idMat4 &a ) const;
783  idMat4 & operator*=( const float a );
784  idMat4 & operator*=( const idMat4 &a );
785  idMat4 & operator+=( const idMat4 &a );
786  idMat4 & operator-=( const idMat4 &a );
787 
788  friend idMat4 operator*( const float a, const idMat4 &mat );
789  friend idVec4 operator*( const idVec4 &vec, const idMat4 &mat );
790  friend idVec3 operator*( const idVec3 &vec, const idMat4 &mat );
791  friend idVec4 & operator*=( idVec4 &vec, const idMat4 &mat );
792  friend idVec3 & operator*=( idVec3 &vec, const idMat4 &mat );
793 
794  bool Compare( const idMat4 &a ) const; // exact compare, no epsilon
795  bool Compare( const idMat4 &a, const float epsilon ) const; // compare with epsilon
796  bool operator==( const idMat4 &a ) const; // exact compare, no epsilon
797  bool operator!=( const idMat4 &a ) const; // exact compare, no epsilon
798 
799  void Zero( void );
800  void Identity( void );
801  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
802  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
803  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
804  bool IsRotated( void ) const;
805 
806  void ProjectVector( const idVec4 &src, idVec4 &dst ) const;
807  void UnprojectVector( const idVec4 &src, idVec4 &dst ) const;
808 
809  float Trace( void ) const;
810  float Determinant( void ) const;
811  idMat4 Transpose( void ) const; // returns transpose
812  idMat4 & TransposeSelf( void );
813  idMat4 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
814  bool InverseSelf( void ); // returns false if determinant is zero
815  idMat4 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
816  bool InverseFastSelf( void ); // returns false if determinant is zero
817  idMat4 TransposeMultiply( const idMat4 &b ) const;
818 
819  int GetDimension( void ) const;
820 
821  const float * ToFloatPtr( void ) const;
822  float * ToFloatPtr( void );
823  const char * ToString( int precision = 2 ) const;
824 
825 private:
826  idVec4 mat[ 4 ];
827 };
828 
829 extern idMat4 mat4_zero;
830 extern idMat4 mat4_identity;
831 #define mat4_default mat4_identity
832 
833 ID_INLINE idMat4::idMat4( void ) {
834 }
835 
836 ID_INLINE idMat4::idMat4( const idVec4 &x, const idVec4 &y, const idVec4 &z, const idVec4 &w ) {
837  mat[ 0 ] = x;
838  mat[ 1 ] = y;
839  mat[ 2 ] = z;
840  mat[ 3 ] = w;
841 }
842 
843 ID_INLINE idMat4::idMat4( const float xx, const float xy, const float xz, const float xw,
844  const float yx, const float yy, const float yz, const float yw,
845  const float zx, const float zy, const float zz, const float zw,
846  const float wx, const float wy, const float wz, const float ww ) {
847  mat[0][0] = xx; mat[0][1] = xy; mat[0][2] = xz; mat[0][3] = xw;
848  mat[1][0] = yx; mat[1][1] = yy; mat[1][2] = yz; mat[1][3] = yw;
849  mat[2][0] = zx; mat[2][1] = zy; mat[2][2] = zz; mat[2][3] = zw;
850  mat[3][0] = wx; mat[3][1] = wy; mat[3][2] = wz; mat[3][3] = ww;
851 }
852 
853 ID_INLINE idMat4::idMat4( const idMat3 &rotation, const idVec3 &translation ) {
854  // NOTE: idMat3 is transposed because it is column-major
855  mat[ 0 ][ 0 ] = rotation[0][0];
856  mat[ 0 ][ 1 ] = rotation[1][0];
857  mat[ 0 ][ 2 ] = rotation[2][0];
858  mat[ 0 ][ 3 ] = translation[0];
859  mat[ 1 ][ 0 ] = rotation[0][1];
860  mat[ 1 ][ 1 ] = rotation[1][1];
861  mat[ 1 ][ 2 ] = rotation[2][1];
862  mat[ 1 ][ 3 ] = translation[1];
863  mat[ 2 ][ 0 ] = rotation[0][2];
864  mat[ 2 ][ 1 ] = rotation[1][2];
865  mat[ 2 ][ 2 ] = rotation[2][2];
866  mat[ 2 ][ 3 ] = translation[2];
867  mat[ 3 ][ 0 ] = 0.0f;
868  mat[ 3 ][ 1 ] = 0.0f;
869  mat[ 3 ][ 2 ] = 0.0f;
870  mat[ 3 ][ 3 ] = 1.0f;
871 }
872 
873 ID_INLINE idMat4::idMat4( const float src[ 4 ][ 4 ] ) {
874  memcpy( mat, src, 4 * 4 * sizeof( float ) );
875 }
876 
877 ID_INLINE const idVec4 &idMat4::operator[]( int index ) const {
878  //assert( ( index >= 0 ) && ( index < 4 ) );
879  return mat[ index ];
880 }
881 
882 ID_INLINE idVec4 &idMat4::operator[]( int index ) {
883  //assert( ( index >= 0 ) && ( index < 4 ) );
884  return mat[ index ];
885 }
886 
887 ID_INLINE idMat4 idMat4::operator*( const float a ) const {
888  return idMat4(
889  mat[0].x * a, mat[0].y * a, mat[0].z * a, mat[0].w * a,
890  mat[1].x * a, mat[1].y * a, mat[1].z * a, mat[1].w * a,
891  mat[2].x * a, mat[2].y * a, mat[2].z * a, mat[2].w * a,
892  mat[3].x * a, mat[3].y * a, mat[3].z * a, mat[3].w * a );
893 }
894 
895 ID_INLINE idVec4 idMat4::operator*( const idVec4 &vec ) const {
896  return idVec4(
897  mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w * vec.w,
898  mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w * vec.w,
899  mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w * vec.w,
900  mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w * vec.w );
901 }
902 
903 ID_INLINE idVec3 idMat4::operator*( const idVec3 &vec ) const {
904  float s = mat[ 3 ].x * vec.x + mat[ 3 ].y * vec.y + mat[ 3 ].z * vec.z + mat[ 3 ].w;
905  if ( s == 0.0f ) {
906  return idVec3( 0.0f, 0.0f, 0.0f );
907  }
908  if ( s == 1.0f ) {
909  return idVec3(
910  mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w,
911  mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w,
912  mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w );
913  }
914  else {
915  float invS = 1.0f / s;
916  return idVec3(
917  (mat[ 0 ].x * vec.x + mat[ 0 ].y * vec.y + mat[ 0 ].z * vec.z + mat[ 0 ].w) * invS,
918  (mat[ 1 ].x * vec.x + mat[ 1 ].y * vec.y + mat[ 1 ].z * vec.z + mat[ 1 ].w) * invS,
919  (mat[ 2 ].x * vec.x + mat[ 2 ].y * vec.y + mat[ 2 ].z * vec.z + mat[ 2 ].w) * invS );
920  }
921 }
922 
923 ID_INLINE idMat4 idMat4::operator*( const idMat4 &a ) const {
924  int i, j;
925  const float *m1Ptr, *m2Ptr;
926  float *dstPtr;
927  idMat4 dst;
928 
929  m1Ptr = reinterpret_cast<const float *>(this);
930  m2Ptr = reinterpret_cast<const float *>(&a);
931  dstPtr = reinterpret_cast<float *>(&dst);
932 
933  for ( i = 0; i < 4; i++ ) {
934  for ( j = 0; j < 4; j++ ) {
935  *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 4 + j ]
936  + m1Ptr[1] * m2Ptr[ 1 * 4 + j ]
937  + m1Ptr[2] * m2Ptr[ 2 * 4 + j ]
938  + m1Ptr[3] * m2Ptr[ 3 * 4 + j ];
939  dstPtr++;
940  }
941  m1Ptr += 4;
942  }
943  return dst;
944 }
945 
946 ID_INLINE idMat4 idMat4::operator+( const idMat4 &a ) const {
947  return idMat4(
948  mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, mat[0].w + a[0].w,
949  mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, mat[1].w + a[1].w,
950  mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z, mat[2].w + a[2].w,
951  mat[3].x + a[3].x, mat[3].y + a[3].y, mat[3].z + a[3].z, mat[3].w + a[3].w );
952 }
953 
954 ID_INLINE idMat4 idMat4::operator-( const idMat4 &a ) const {
955  return idMat4(
956  mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, mat[0].w - a[0].w,
957  mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, mat[1].w - a[1].w,
958  mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z, mat[2].w - a[2].w,
959  mat[3].x - a[3].x, mat[3].y - a[3].y, mat[3].z - a[3].z, mat[3].w - a[3].w );
960 }
961 
962 ID_INLINE idMat4 &idMat4::operator*=( const float a ) {
963  mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; mat[0].w *= a;
964  mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; mat[1].w *= a;
965  mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; mat[2].w *= a;
966  mat[3].x *= a; mat[3].y *= a; mat[3].z *= a; mat[3].w *= a;
967  return *this;
968 }
969 
970 ID_INLINE idMat4 &idMat4::operator*=( const idMat4 &a ) {
971  *this = (*this) * a;
972  return *this;
973 }
974 
975 ID_INLINE idMat4 &idMat4::operator+=( const idMat4 &a ) {
976  mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; mat[0].w += a[0].w;
977  mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; mat[1].w += a[1].w;
978  mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; mat[2].w += a[2].w;
979  mat[3].x += a[3].x; mat[3].y += a[3].y; mat[3].z += a[3].z; mat[3].w += a[3].w;
980  return *this;
981 }
982 
983 ID_INLINE idMat4 &idMat4::operator-=( const idMat4 &a ) {
984  mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; mat[0].w -= a[0].w;
985  mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; mat[1].w -= a[1].w;
986  mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; mat[2].w -= a[2].w;
987  mat[3].x -= a[3].x; mat[3].y -= a[3].y; mat[3].z -= a[3].z; mat[3].w -= a[3].w;
988  return *this;
989 }
990 
991 ID_INLINE idMat4 operator*( const float a, const idMat4 &mat ) {
992  return mat * a;
993 }
994 
995 ID_INLINE idVec4 operator*( const idVec4 &vec, const idMat4 &mat ) {
996  return mat * vec;
997 }
998 
999 ID_INLINE idVec3 operator*( const idVec3 &vec, const idMat4 &mat ) {
1000  return mat * vec;
1001 }
1002 
1003 ID_INLINE idVec4 &operator*=( idVec4 &vec, const idMat4 &mat ) {
1004  vec = mat * vec;
1005  return vec;
1006 }
1007 
1008 ID_INLINE idVec3 &operator*=( idVec3 &vec, const idMat4 &mat ) {
1009  vec = mat * vec;
1010  return vec;
1011 }
1012 
1013 ID_INLINE bool idMat4::Compare( const idMat4 &a ) const {
1014  dword i;
1015  const float *ptr1, *ptr2;
1016 
1017  ptr1 = reinterpret_cast<const float *>(mat);
1018  ptr2 = reinterpret_cast<const float *>(a.mat);
1019  for ( i = 0; i < 4*4; i++ ) {
1020  if ( ptr1[i] != ptr2[i] ) {
1021  return false;
1022  }
1023  }
1024  return true;
1025 }
1026 
1027 ID_INLINE bool idMat4::Compare( const idMat4 &a, const float epsilon ) const {
1028  dword i;
1029  const float *ptr1, *ptr2;
1030 
1031  ptr1 = reinterpret_cast<const float *>(mat);
1032  ptr2 = reinterpret_cast<const float *>(a.mat);
1033  for ( i = 0; i < 4*4; i++ ) {
1034  if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) {
1035  return false;
1036  }
1037  }
1038  return true;
1039 }
1040 
1041 ID_INLINE bool idMat4::operator==( const idMat4 &a ) const {
1042  return Compare( a );
1043 }
1044 
1045 ID_INLINE bool idMat4::operator!=( const idMat4 &a ) const {
1046  return !Compare( a );
1047 }
1048 
1049 ID_INLINE void idMat4::Zero( void ) {
1050  memset( mat, 0, sizeof( idMat4 ) );
1051 }
1052 
1053 ID_INLINE void idMat4::Identity( void ) {
1054  *this = mat4_identity;
1055 }
1056 
1057 ID_INLINE bool idMat4::IsIdentity( const float epsilon ) const {
1058  return Compare( mat4_identity, epsilon );
1059 }
1060 
1061 ID_INLINE bool idMat4::IsSymmetric( const float epsilon ) const {
1062  for ( int i = 1; i < 4; i++ ) {
1063  for ( int j = 0; j < i; j++ ) {
1064  if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) {
1065  return false;
1066  }
1067  }
1068  }
1069  return true;
1070 }
1071 
1072 ID_INLINE bool idMat4::IsDiagonal( const float epsilon ) const {
1073  for ( int i = 0; i < 4; i++ ) {
1074  for ( int j = 0; j < 4; j++ ) {
1075  if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) {
1076  return false;
1077  }
1078  }
1079  }
1080  return true;
1081 }
1082 
1083 ID_INLINE bool idMat4::IsRotated( void ) const {
1084  if ( !mat[ 0 ][ 1 ] && !mat[ 0 ][ 2 ] &&
1085  !mat[ 1 ][ 0 ] && !mat[ 1 ][ 2 ] &&
1086  !mat[ 2 ][ 0 ] && !mat[ 2 ][ 1 ] ) {
1087  return false;
1088  }
1089  return true;
1090 }
1091 
1092 ID_INLINE void idMat4::ProjectVector( const idVec4 &src, idVec4 &dst ) const {
1093  dst.x = src * mat[ 0 ];
1094  dst.y = src * mat[ 1 ];
1095  dst.z = src * mat[ 2 ];
1096  dst.w = src * mat[ 3 ];
1097 }
1098 
1099 ID_INLINE void idMat4::UnprojectVector( const idVec4 &src, idVec4 &dst ) const {
1100  dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z + mat[ 3 ] * src.w;
1101 }
1102 
1103 ID_INLINE float idMat4::Trace( void ) const {
1104  return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] );
1105 }
1106 
1107 ID_INLINE idMat4 idMat4::Inverse( void ) const {
1108  idMat4 invMat;
1109 
1110  invMat = *this;
1111  int r = invMat.InverseSelf();
1112  assert( r );
1113  return invMat;
1114 }
1115 
1116 ID_INLINE idMat4 idMat4::InverseFast( void ) const {
1117  idMat4 invMat;
1118 
1119  invMat = *this;
1120  int r = invMat.InverseFastSelf();
1121  assert( r );
1122  return invMat;
1123 }
1124 
1125 ID_INLINE idMat4 idMat3::ToMat4( void ) const {
1126  // NOTE: idMat3 is transposed because it is column-major
1127  return idMat4( mat[0][0], mat[1][0], mat[2][0], 0.0f,
1128  mat[0][1], mat[1][1], mat[2][1], 0.0f,
1129  mat[0][2], mat[1][2], mat[2][2], 0.0f,
1130  0.0f, 0.0f, 0.0f, 1.0f );
1131 }
1132 
1133 ID_INLINE int idMat4::GetDimension( void ) const {
1134  return 16;
1135 }
1136 
1137 ID_INLINE const float *idMat4::ToFloatPtr( void ) const {
1138  return mat[0].ToFloatPtr();
1139 }
1140 
1141 ID_INLINE float *idMat4::ToFloatPtr( void ) {
1142  return mat[0].ToFloatPtr();
1143 }
1144 
1145 
1146 //===============================================================
1147 //
1148 // idMat5 - 5x5 matrix
1149 //
1150 //===============================================================
1151 
1152 class idMat5 {
1153 public:
1154  idMat5( void );
1155  explicit idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 );
1156  explicit idMat5( const float src[ 5 ][ 5 ] );
1157 
1158  const idVec5 & operator[]( int index ) const;
1159  idVec5 & operator[]( int index );
1160  idMat5 operator*( const float a ) const;
1161  idVec5 operator*( const idVec5 &vec ) const;
1162  idMat5 operator*( const idMat5 &a ) const;
1163  idMat5 operator+( const idMat5 &a ) const;
1164  idMat5 operator-( const idMat5 &a ) const;
1165  idMat5 & operator*=( const float a );
1166  idMat5 & operator*=( const idMat5 &a );
1167  idMat5 & operator+=( const idMat5 &a );
1168  idMat5 & operator-=( const idMat5 &a );
1169 
1170  friend idMat5 operator*( const float a, const idMat5 &mat );
1171  friend idVec5 operator*( const idVec5 &vec, const idMat5 &mat );
1172  friend idVec5 & operator*=( idVec5 &vec, const idMat5 &mat );
1173 
1174  bool Compare( const idMat5 &a ) const; // exact compare, no epsilon
1175  bool Compare( const idMat5 &a, const float epsilon ) const; // compare with epsilon
1176  bool operator==( const idMat5 &a ) const; // exact compare, no epsilon
1177  bool operator!=( const idMat5 &a ) const; // exact compare, no epsilon
1178 
1179  void Zero( void );
1180  void Identity( void );
1181  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
1182  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
1183  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
1184 
1185  float Trace( void ) const;
1186  float Determinant( void ) const;
1187  idMat5 Transpose( void ) const; // returns transpose
1188  idMat5 & TransposeSelf( void );
1189  idMat5 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1190  bool InverseSelf( void ); // returns false if determinant is zero
1191  idMat5 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1192  bool InverseFastSelf( void ); // returns false if determinant is zero
1193 
1194  int GetDimension( void ) const;
1195 
1196  const float * ToFloatPtr( void ) const;
1197  float * ToFloatPtr( void );
1198  const char * ToString( int precision = 2 ) const;
1199 
1200 private:
1201  idVec5 mat[ 5 ];
1202 };
1203 
1204 extern idMat5 mat5_zero;
1205 extern idMat5 mat5_identity;
1206 #define mat5_default mat5_identity
1207 
1208 ID_INLINE idMat5::idMat5( void ) {
1209 }
1210 
1211 ID_INLINE idMat5::idMat5( const float src[ 5 ][ 5 ] ) {
1212  memcpy( mat, src, 5 * 5 * sizeof( float ) );
1213 }
1214 
1215 ID_INLINE idMat5::idMat5( const idVec5 &v0, const idVec5 &v1, const idVec5 &v2, const idVec5 &v3, const idVec5 &v4 ) {
1216  mat[0] = v0;
1217  mat[1] = v1;
1218  mat[2] = v2;
1219  mat[3] = v3;
1220  mat[4] = v4;
1221 }
1222 
1223 ID_INLINE const idVec5 &idMat5::operator[]( int index ) const {
1224  //assert( ( index >= 0 ) && ( index < 5 ) );
1225  return mat[ index ];
1226 }
1227 
1228 ID_INLINE idVec5 &idMat5::operator[]( int index ) {
1229  //assert( ( index >= 0 ) && ( index < 5 ) );
1230  return mat[ index ];
1231 }
1232 
1233 ID_INLINE idMat5 idMat5::operator*( const idMat5 &a ) const {
1234  int i, j;
1235  const float *m1Ptr, *m2Ptr;
1236  float *dstPtr;
1237  idMat5 dst;
1238 
1239  m1Ptr = reinterpret_cast<const float *>(this);
1240  m2Ptr = reinterpret_cast<const float *>(&a);
1241  dstPtr = reinterpret_cast<float *>(&dst);
1242 
1243  for ( i = 0; i < 5; i++ ) {
1244  for ( j = 0; j < 5; j++ ) {
1245  *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 5 + j ]
1246  + m1Ptr[1] * m2Ptr[ 1 * 5 + j ]
1247  + m1Ptr[2] * m2Ptr[ 2 * 5 + j ]
1248  + m1Ptr[3] * m2Ptr[ 3 * 5 + j ]
1249  + m1Ptr[4] * m2Ptr[ 4 * 5 + j ];
1250  dstPtr++;
1251  }
1252  m1Ptr += 5;
1253  }
1254  return dst;
1255 }
1256 
1257 ID_INLINE idMat5 idMat5::operator*( const float a ) const {
1258  return idMat5(
1259  idVec5( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a ),
1260  idVec5( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a ),
1261  idVec5( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a ),
1262  idVec5( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a ),
1263  idVec5( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a ) );
1264 }
1265 
1266 ID_INLINE idVec5 idMat5::operator*( const idVec5 &vec ) const {
1267  return idVec5(
1268  mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4],
1269  mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4],
1270  mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4],
1271  mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4],
1272  mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] );
1273 }
1274 
1275 ID_INLINE idMat5 idMat5::operator+( const idMat5 &a ) const {
1276  return idMat5(
1277  idVec5( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4] ),
1278  idVec5( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4] ),
1279  idVec5( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4] ),
1280  idVec5( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4] ),
1281  idVec5( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4] ) );
1282 }
1283 
1284 ID_INLINE idMat5 idMat5::operator-( const idMat5 &a ) const {
1285  return idMat5(
1286  idVec5( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4] ),
1287  idVec5( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4] ),
1288  idVec5( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4] ),
1289  idVec5( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4] ),
1290  idVec5( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4] ) );
1291 }
1292 
1293 ID_INLINE idMat5 &idMat5::operator*=( const float a ) {
1294  mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a;
1295  mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a;
1296  mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a;
1297  mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a;
1298  mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a;
1299  return *this;
1300 }
1301 
1302 ID_INLINE idMat5 &idMat5::operator*=( const idMat5 &a ) {
1303  *this = *this * a;
1304  return *this;
1305 }
1306 
1307 ID_INLINE idMat5 &idMat5::operator+=( const idMat5 &a ) {
1308  mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4];
1309  mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4];
1310  mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4];
1311  mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4];
1312  mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4];
1313  return *this;
1314 }
1315 
1316 ID_INLINE idMat5 &idMat5::operator-=( const idMat5 &a ) {
1317  mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4];
1318  mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4];
1319  mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4];
1320  mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4];
1321  mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4];
1322  return *this;
1323 }
1324 
1325 ID_INLINE idVec5 operator*( const idVec5 &vec, const idMat5 &mat ) {
1326  return mat * vec;
1327 }
1328 
1329 ID_INLINE idMat5 operator*( const float a, idMat5 const &mat ) {
1330  return mat * a;
1331 }
1332 
1333 ID_INLINE idVec5 &operator*=( idVec5 &vec, const idMat5 &mat ) {
1334  vec = mat * vec;
1335  return vec;
1336 }
1337 
1338 ID_INLINE bool idMat5::Compare( const idMat5 &a ) const {
1339  dword i;
1340  const float *ptr1, *ptr2;
1341 
1342  ptr1 = reinterpret_cast<const float *>(mat);
1343  ptr2 = reinterpret_cast<const float *>(a.mat);
1344  for ( i = 0; i < 5*5; i++ ) {
1345  if ( ptr1[i] != ptr2[i] ) {
1346  return false;
1347  }
1348  }
1349  return true;
1350 }
1351 
1352 ID_INLINE bool idMat5::Compare( const idMat5 &a, const float epsilon ) const {
1353  dword i;
1354  const float *ptr1, *ptr2;
1355 
1356  ptr1 = reinterpret_cast<const float *>(mat);
1357  ptr2 = reinterpret_cast<const float *>(a.mat);
1358  for ( i = 0; i < 5*5; i++ ) {
1359  if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) {
1360  return false;
1361  }
1362  }
1363  return true;
1364 }
1365 
1366 ID_INLINE bool idMat5::operator==( const idMat5 &a ) const {
1367  return Compare( a );
1368 }
1369 
1370 ID_INLINE bool idMat5::operator!=( const idMat5 &a ) const {
1371  return !Compare( a );
1372 }
1373 
1374 ID_INLINE void idMat5::Zero( void ) {
1375  memset( mat, 0, sizeof( idMat5 ) );
1376 }
1377 
1378 ID_INLINE void idMat5::Identity( void ) {
1379  *this = mat5_identity;
1380 }
1381 
1382 ID_INLINE bool idMat5::IsIdentity( const float epsilon ) const {
1383  return Compare( mat5_identity, epsilon );
1384 }
1385 
1386 ID_INLINE bool idMat5::IsSymmetric( const float epsilon ) const {
1387  for ( int i = 1; i < 5; i++ ) {
1388  for ( int j = 0; j < i; j++ ) {
1389  if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) {
1390  return false;
1391  }
1392  }
1393  }
1394  return true;
1395 }
1396 
1397 ID_INLINE bool idMat5::IsDiagonal( const float epsilon ) const {
1398  for ( int i = 0; i < 5; i++ ) {
1399  for ( int j = 0; j < 5; j++ ) {
1400  if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) {
1401  return false;
1402  }
1403  }
1404  }
1405  return true;
1406 }
1407 
1408 ID_INLINE float idMat5::Trace( void ) const {
1409  return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] );
1410 }
1411 
1412 ID_INLINE idMat5 idMat5::Inverse( void ) const {
1413  idMat5 invMat;
1414 
1415  invMat = *this;
1416  int r = invMat.InverseSelf();
1417  assert( r );
1418  return invMat;
1419 }
1420 
1421 ID_INLINE idMat5 idMat5::InverseFast( void ) const {
1422  idMat5 invMat;
1423 
1424  invMat = *this;
1425  int r = invMat.InverseFastSelf();
1426  assert( r );
1427  return invMat;
1428 }
1429 
1430 ID_INLINE int idMat5::GetDimension( void ) const {
1431  return 25;
1432 }
1433 
1434 ID_INLINE const float *idMat5::ToFloatPtr( void ) const {
1435  return mat[0].ToFloatPtr();
1436 }
1437 
1438 ID_INLINE float *idMat5::ToFloatPtr( void ) {
1439  return mat[0].ToFloatPtr();
1440 }
1441 
1442 
1443 //===============================================================
1444 //
1445 // idMat6 - 6x6 matrix
1446 //
1447 //===============================================================
1448 
1449 class idMat6 {
1450 public:
1451  idMat6( void );
1452  explicit idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 );
1453  explicit idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 );
1454  explicit idMat6( const float src[ 6 ][ 6 ] );
1455 
1456  const idVec6 & operator[]( int index ) const;
1457  idVec6 & operator[]( int index );
1458  idMat6 operator*( const float a ) const;
1459  idVec6 operator*( const idVec6 &vec ) const;
1460  idMat6 operator*( const idMat6 &a ) const;
1461  idMat6 operator+( const idMat6 &a ) const;
1462  idMat6 operator-( const idMat6 &a ) const;
1463  idMat6 & operator*=( const float a );
1464  idMat6 & operator*=( const idMat6 &a );
1465  idMat6 & operator+=( const idMat6 &a );
1466  idMat6 & operator-=( const idMat6 &a );
1467 
1468  friend idMat6 operator*( const float a, const idMat6 &mat );
1469  friend idVec6 operator*( const idVec6 &vec, const idMat6 &mat );
1470  friend idVec6 & operator*=( idVec6 &vec, const idMat6 &mat );
1471 
1472  bool Compare( const idMat6 &a ) const; // exact compare, no epsilon
1473  bool Compare( const idMat6 &a, const float epsilon ) const; // compare with epsilon
1474  bool operator==( const idMat6 &a ) const; // exact compare, no epsilon
1475  bool operator!=( const idMat6 &a ) const; // exact compare, no epsilon
1476 
1477  void Zero( void );
1478  void Identity( void );
1479  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
1480  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
1481  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
1482 
1483  idMat3 SubMat3( int n ) const;
1484  float Trace( void ) const;
1485  float Determinant( void ) const;
1486  idMat6 Transpose( void ) const; // returns transpose
1487  idMat6 & TransposeSelf( void );
1488  idMat6 Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1489  bool InverseSelf( void ); // returns false if determinant is zero
1490  idMat6 InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1491  bool InverseFastSelf( void ); // returns false if determinant is zero
1492 
1493  int GetDimension( void ) const;
1494 
1495  const float * ToFloatPtr( void ) const;
1496  float * ToFloatPtr( void );
1497  const char * ToString( int precision = 2 ) const;
1498 
1499 private:
1500  idVec6 mat[ 6 ];
1501 };
1502 
1503 extern idMat6 mat6_zero;
1504 extern idMat6 mat6_identity;
1505 #define mat6_default mat6_identity
1506 
1507 ID_INLINE idMat6::idMat6( void ) {
1508 }
1509 
1510 ID_INLINE idMat6::idMat6( const idMat3 &m0, const idMat3 &m1, const idMat3 &m2, const idMat3 &m3 ) {
1511  mat[0] = idVec6( m0[0][0], m0[0][1], m0[0][2], m1[0][0], m1[0][1], m1[0][2] );
1512  mat[1] = idVec6( m0[1][0], m0[1][1], m0[1][2], m1[1][0], m1[1][1], m1[1][2] );
1513  mat[2] = idVec6( m0[2][0], m0[2][1], m0[2][2], m1[2][0], m1[2][1], m1[2][2] );
1514  mat[3] = idVec6( m2[0][0], m2[0][1], m2[0][2], m3[0][0], m3[0][1], m3[0][2] );
1515  mat[4] = idVec6( m2[1][0], m2[1][1], m2[1][2], m3[1][0], m3[1][1], m3[1][2] );
1516  mat[5] = idVec6( m2[2][0], m2[2][1], m2[2][2], m3[2][0], m3[2][1], m3[2][2] );
1517 }
1518 
1519 ID_INLINE idMat6::idMat6( const idVec6 &v0, const idVec6 &v1, const idVec6 &v2, const idVec6 &v3, const idVec6 &v4, const idVec6 &v5 ) {
1520  mat[0] = v0;
1521  mat[1] = v1;
1522  mat[2] = v2;
1523  mat[3] = v3;
1524  mat[4] = v4;
1525  mat[5] = v5;
1526 }
1527 
1528 ID_INLINE idMat6::idMat6( const float src[ 6 ][ 6 ] ) {
1529  memcpy( mat, src, 6 * 6 * sizeof( float ) );
1530 }
1531 
1532 ID_INLINE const idVec6 &idMat6::operator[]( int index ) const {
1533  //assert( ( index >= 0 ) && ( index < 6 ) );
1534  return mat[ index ];
1535 }
1536 
1537 ID_INLINE idVec6 &idMat6::operator[]( int index ) {
1538  //assert( ( index >= 0 ) && ( index < 6 ) );
1539  return mat[ index ];
1540 }
1541 
1542 ID_INLINE idMat6 idMat6::operator*( const idMat6 &a ) const {
1543  int i, j;
1544  const float *m1Ptr, *m2Ptr;
1545  float *dstPtr;
1546  idMat6 dst;
1547 
1548  m1Ptr = reinterpret_cast<const float *>(this);
1549  m2Ptr = reinterpret_cast<const float *>(&a);
1550  dstPtr = reinterpret_cast<float *>(&dst);
1551 
1552  for ( i = 0; i < 6; i++ ) {
1553  for ( j = 0; j < 6; j++ ) {
1554  *dstPtr = m1Ptr[0] * m2Ptr[ 0 * 6 + j ]
1555  + m1Ptr[1] * m2Ptr[ 1 * 6 + j ]
1556  + m1Ptr[2] * m2Ptr[ 2 * 6 + j ]
1557  + m1Ptr[3] * m2Ptr[ 3 * 6 + j ]
1558  + m1Ptr[4] * m2Ptr[ 4 * 6 + j ]
1559  + m1Ptr[5] * m2Ptr[ 5 * 6 + j ];
1560  dstPtr++;
1561  }
1562  m1Ptr += 6;
1563  }
1564  return dst;
1565 }
1566 
1567 ID_INLINE idMat6 idMat6::operator*( const float a ) const {
1568  return idMat6(
1569  idVec6( mat[0][0] * a, mat[0][1] * a, mat[0][2] * a, mat[0][3] * a, mat[0][4] * a, mat[0][5] * a ),
1570  idVec6( mat[1][0] * a, mat[1][1] * a, mat[1][2] * a, mat[1][3] * a, mat[1][4] * a, mat[1][5] * a ),
1571  idVec6( mat[2][0] * a, mat[2][1] * a, mat[2][2] * a, mat[2][3] * a, mat[2][4] * a, mat[2][5] * a ),
1572  idVec6( mat[3][0] * a, mat[3][1] * a, mat[3][2] * a, mat[3][3] * a, mat[3][4] * a, mat[3][5] * a ),
1573  idVec6( mat[4][0] * a, mat[4][1] * a, mat[4][2] * a, mat[4][3] * a, mat[4][4] * a, mat[4][5] * a ),
1574  idVec6( mat[5][0] * a, mat[5][1] * a, mat[5][2] * a, mat[5][3] * a, mat[5][4] * a, mat[5][5] * a ) );
1575 }
1576 
1577 ID_INLINE idVec6 idMat6::operator*( const idVec6 &vec ) const {
1578  return idVec6(
1579  mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2] + mat[0][3] * vec[3] + mat[0][4] * vec[4] + mat[0][5] * vec[5],
1580  mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2] + mat[1][3] * vec[3] + mat[1][4] * vec[4] + mat[1][5] * vec[5],
1581  mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2] + mat[2][3] * vec[3] + mat[2][4] * vec[4] + mat[2][5] * vec[5],
1582  mat[3][0] * vec[0] + mat[3][1] * vec[1] + mat[3][2] * vec[2] + mat[3][3] * vec[3] + mat[3][4] * vec[4] + mat[3][5] * vec[5],
1583  mat[4][0] * vec[0] + mat[4][1] * vec[1] + mat[4][2] * vec[2] + mat[4][3] * vec[3] + mat[4][4] * vec[4] + mat[4][5] * vec[5],
1584  mat[5][0] * vec[0] + mat[5][1] * vec[1] + mat[5][2] * vec[2] + mat[5][3] * vec[3] + mat[5][4] * vec[4] + mat[5][5] * vec[5] );
1585 }
1586 
1587 ID_INLINE idMat6 idMat6::operator+( const idMat6 &a ) const {
1588  return idMat6(
1589  idVec6( mat[0][0] + a[0][0], mat[0][1] + a[0][1], mat[0][2] + a[0][2], mat[0][3] + a[0][3], mat[0][4] + a[0][4], mat[0][5] + a[0][5] ),
1590  idVec6( mat[1][0] + a[1][0], mat[1][1] + a[1][1], mat[1][2] + a[1][2], mat[1][3] + a[1][3], mat[1][4] + a[1][4], mat[1][5] + a[1][5] ),
1591  idVec6( mat[2][0] + a[2][0], mat[2][1] + a[2][1], mat[2][2] + a[2][2], mat[2][3] + a[2][3], mat[2][4] + a[2][4], mat[2][5] + a[2][5] ),
1592  idVec6( mat[3][0] + a[3][0], mat[3][1] + a[3][1], mat[3][2] + a[3][2], mat[3][3] + a[3][3], mat[3][4] + a[3][4], mat[3][5] + a[3][5] ),
1593  idVec6( mat[4][0] + a[4][0], mat[4][1] + a[4][1], mat[4][2] + a[4][2], mat[4][3] + a[4][3], mat[4][4] + a[4][4], mat[4][5] + a[4][5] ),
1594  idVec6( mat[5][0] + a[5][0], mat[5][1] + a[5][1], mat[5][2] + a[5][2], mat[5][3] + a[5][3], mat[5][4] + a[5][4], mat[5][5] + a[5][5] ) );
1595 }
1596 
1597 ID_INLINE idMat6 idMat6::operator-( const idMat6 &a ) const {
1598  return idMat6(
1599  idVec6( mat[0][0] - a[0][0], mat[0][1] - a[0][1], mat[0][2] - a[0][2], mat[0][3] - a[0][3], mat[0][4] - a[0][4], mat[0][5] - a[0][5] ),
1600  idVec6( mat[1][0] - a[1][0], mat[1][1] - a[1][1], mat[1][2] - a[1][2], mat[1][3] - a[1][3], mat[1][4] - a[1][4], mat[1][5] - a[1][5] ),
1601  idVec6( mat[2][0] - a[2][0], mat[2][1] - a[2][1], mat[2][2] - a[2][2], mat[2][3] - a[2][3], mat[2][4] - a[2][4], mat[2][5] - a[2][5] ),
1602  idVec6( mat[3][0] - a[3][0], mat[3][1] - a[3][1], mat[3][2] - a[3][2], mat[3][3] - a[3][3], mat[3][4] - a[3][4], mat[3][5] - a[3][5] ),
1603  idVec6( mat[4][0] - a[4][0], mat[4][1] - a[4][1], mat[4][2] - a[4][2], mat[4][3] - a[4][3], mat[4][4] - a[4][4], mat[4][5] - a[4][5] ),
1604  idVec6( mat[5][0] - a[5][0], mat[5][1] - a[5][1], mat[5][2] - a[5][2], mat[5][3] - a[5][3], mat[5][4] - a[5][4], mat[5][5] - a[5][5] ) );
1605 }
1606 
1607 ID_INLINE idMat6 &idMat6::operator*=( const float a ) {
1608  mat[0][0] *= a; mat[0][1] *= a; mat[0][2] *= a; mat[0][3] *= a; mat[0][4] *= a; mat[0][5] *= a;
1609  mat[1][0] *= a; mat[1][1] *= a; mat[1][2] *= a; mat[1][3] *= a; mat[1][4] *= a; mat[1][5] *= a;
1610  mat[2][0] *= a; mat[2][1] *= a; mat[2][2] *= a; mat[2][3] *= a; mat[2][4] *= a; mat[2][5] *= a;
1611  mat[3][0] *= a; mat[3][1] *= a; mat[3][2] *= a; mat[3][3] *= a; mat[3][4] *= a; mat[3][5] *= a;
1612  mat[4][0] *= a; mat[4][1] *= a; mat[4][2] *= a; mat[4][3] *= a; mat[4][4] *= a; mat[4][5] *= a;
1613  mat[5][0] *= a; mat[5][1] *= a; mat[5][2] *= a; mat[5][3] *= a; mat[5][4] *= a; mat[5][5] *= a;
1614  return *this;
1615 }
1616 
1617 ID_INLINE idMat6 &idMat6::operator*=( const idMat6 &a ) {
1618  *this = *this * a;
1619  return *this;
1620 }
1621 
1622 ID_INLINE idMat6 &idMat6::operator+=( const idMat6 &a ) {
1623  mat[0][0] += a[0][0]; mat[0][1] += a[0][1]; mat[0][2] += a[0][2]; mat[0][3] += a[0][3]; mat[0][4] += a[0][4]; mat[0][5] += a[0][5];
1624  mat[1][0] += a[1][0]; mat[1][1] += a[1][1]; mat[1][2] += a[1][2]; mat[1][3] += a[1][3]; mat[1][4] += a[1][4]; mat[1][5] += a[1][5];
1625  mat[2][0] += a[2][0]; mat[2][1] += a[2][1]; mat[2][2] += a[2][2]; mat[2][3] += a[2][3]; mat[2][4] += a[2][4]; mat[2][5] += a[2][5];
1626  mat[3][0] += a[3][0]; mat[3][1] += a[3][1]; mat[3][2] += a[3][2]; mat[3][3] += a[3][3]; mat[3][4] += a[3][4]; mat[3][5] += a[3][5];
1627  mat[4][0] += a[4][0]; mat[4][1] += a[4][1]; mat[4][2] += a[4][2]; mat[4][3] += a[4][3]; mat[4][4] += a[4][4]; mat[4][5] += a[4][5];
1628  mat[5][0] += a[5][0]; mat[5][1] += a[5][1]; mat[5][2] += a[5][2]; mat[5][3] += a[5][3]; mat[5][4] += a[5][4]; mat[5][5] += a[5][5];
1629  return *this;
1630 }
1631 
1632 ID_INLINE idMat6 &idMat6::operator-=( const idMat6 &a ) {
1633  mat[0][0] -= a[0][0]; mat[0][1] -= a[0][1]; mat[0][2] -= a[0][2]; mat[0][3] -= a[0][3]; mat[0][4] -= a[0][4]; mat[0][5] -= a[0][5];
1634  mat[1][0] -= a[1][0]; mat[1][1] -= a[1][1]; mat[1][2] -= a[1][2]; mat[1][3] -= a[1][3]; mat[1][4] -= a[1][4]; mat[1][5] -= a[1][5];
1635  mat[2][0] -= a[2][0]; mat[2][1] -= a[2][1]; mat[2][2] -= a[2][2]; mat[2][3] -= a[2][3]; mat[2][4] -= a[2][4]; mat[2][5] -= a[2][5];
1636  mat[3][0] -= a[3][0]; mat[3][1] -= a[3][1]; mat[3][2] -= a[3][2]; mat[3][3] -= a[3][3]; mat[3][4] -= a[3][4]; mat[3][5] -= a[3][5];
1637  mat[4][0] -= a[4][0]; mat[4][1] -= a[4][1]; mat[4][2] -= a[4][2]; mat[4][3] -= a[4][3]; mat[4][4] -= a[4][4]; mat[4][5] -= a[4][5];
1638  mat[5][0] -= a[5][0]; mat[5][1] -= a[5][1]; mat[5][2] -= a[5][2]; mat[5][3] -= a[5][3]; mat[5][4] -= a[5][4]; mat[5][5] -= a[5][5];
1639  return *this;
1640 }
1641 
1642 ID_INLINE idVec6 operator*( const idVec6 &vec, const idMat6 &mat ) {
1643  return mat * vec;
1644 }
1645 
1646 ID_INLINE idMat6 operator*( const float a, idMat6 const &mat ) {
1647  return mat * a;
1648 }
1649 
1650 ID_INLINE idVec6 &operator*=( idVec6 &vec, const idMat6 &mat ) {
1651  vec = mat * vec;
1652  return vec;
1653 }
1654 
1655 ID_INLINE bool idMat6::Compare( const idMat6 &a ) const {
1656  dword i;
1657  const float *ptr1, *ptr2;
1658 
1659  ptr1 = reinterpret_cast<const float *>(mat);
1660  ptr2 = reinterpret_cast<const float *>(a.mat);
1661  for ( i = 0; i < 6*6; i++ ) {
1662  if ( ptr1[i] != ptr2[i] ) {
1663  return false;
1664  }
1665  }
1666  return true;
1667 }
1668 
1669 ID_INLINE bool idMat6::Compare( const idMat6 &a, const float epsilon ) const {
1670  dword i;
1671  const float *ptr1, *ptr2;
1672 
1673  ptr1 = reinterpret_cast<const float *>(mat);
1674  ptr2 = reinterpret_cast<const float *>(a.mat);
1675  for ( i = 0; i < 6*6; i++ ) {
1676  if ( idMath::Fabs( ptr1[i] - ptr2[i] ) > epsilon ) {
1677  return false;
1678  }
1679  }
1680  return true;
1681 }
1682 
1683 ID_INLINE bool idMat6::operator==( const idMat6 &a ) const {
1684  return Compare( a );
1685 }
1686 
1687 ID_INLINE bool idMat6::operator!=( const idMat6 &a ) const {
1688  return !Compare( a );
1689 }
1690 
1691 ID_INLINE void idMat6::Zero( void ) {
1692  memset( mat, 0, sizeof( idMat6 ) );
1693 }
1694 
1695 ID_INLINE void idMat6::Identity( void ) {
1696  *this = mat6_identity;
1697 }
1698 
1699 ID_INLINE bool idMat6::IsIdentity( const float epsilon ) const {
1700  return Compare( mat6_identity, epsilon );
1701 }
1702 
1703 ID_INLINE bool idMat6::IsSymmetric( const float epsilon ) const {
1704  for ( int i = 1; i < 6; i++ ) {
1705  for ( int j = 0; j < i; j++ ) {
1706  if ( idMath::Fabs( mat[i][j] - mat[j][i] ) > epsilon ) {
1707  return false;
1708  }
1709  }
1710  }
1711  return true;
1712 }
1713 
1714 ID_INLINE bool idMat6::IsDiagonal( const float epsilon ) const {
1715  for ( int i = 0; i < 6; i++ ) {
1716  for ( int j = 0; j < 6; j++ ) {
1717  if ( i != j && idMath::Fabs( mat[i][j] ) > epsilon ) {
1718  return false;
1719  }
1720  }
1721  }
1722  return true;
1723 }
1724 
1725 ID_INLINE idMat3 idMat6::SubMat3( int n ) const {
1726  assert( n >= 0 && n < 4 );
1727  int b0 = ((n & 2) >> 1) * 3;
1728  int b1 = (n & 1) * 3;
1729  return idMat3(
1730  mat[b0 + 0][b1 + 0], mat[b0 + 0][b1 + 1], mat[b0 + 0][b1 + 2],
1731  mat[b0 + 1][b1 + 0], mat[b0 + 1][b1 + 1], mat[b0 + 1][b1 + 2],
1732  mat[b0 + 2][b1 + 0], mat[b0 + 2][b1 + 1], mat[b0 + 2][b1 + 2] );
1733 }
1734 
1735 ID_INLINE float idMat6::Trace( void ) const {
1736  return ( mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3] + mat[4][4] + mat[5][5] );
1737 }
1738 
1739 ID_INLINE idMat6 idMat6::Inverse( void ) const {
1740  idMat6 invMat;
1741 
1742  invMat = *this;
1743  int r = invMat.InverseSelf();
1744  assert( r );
1745  return invMat;
1746 }
1747 
1748 ID_INLINE idMat6 idMat6::InverseFast( void ) const {
1749  idMat6 invMat;
1750 
1751  invMat = *this;
1752  int r = invMat.InverseFastSelf();
1753  assert( r );
1754  return invMat;
1755 }
1756 
1757 ID_INLINE int idMat6::GetDimension( void ) const {
1758  return 36;
1759 }
1760 
1761 ID_INLINE const float *idMat6::ToFloatPtr( void ) const {
1762  return mat[0].ToFloatPtr();
1763 }
1764 
1765 ID_INLINE float *idMat6::ToFloatPtr( void ) {
1766  return mat[0].ToFloatPtr();
1767 }
1768 
1769 
1770 //===============================================================
1771 //
1772 // idMatX - arbitrary sized dense real matrix
1773 //
1774 // The matrix lives on 16 byte aligned and 16 byte padded memory.
1775 //
1776 // NOTE: due to the temporary memory pool idMatX cannot be used by multiple threads.
1777 //
1778 //===============================================================
1779 
1780 #define MATX_MAX_TEMP 1024
1781 #define MATX_QUAD( x ) ( ( ( ( x ) + 3 ) & ~3 ) * sizeof( float ) )
1782 #define MATX_CLEAREND() int s = numRows * numColumns; while( s < ( ( s + 3 ) & ~3 ) ) { mat[s++] = 0.0f; }
1783 #define MATX_ALLOCA( n ) ( (float *) _alloca16( MATX_QUAD( n ) ) )
1784 #define MATX_SIMD
1785 
1786 class idMatX {
1787 public:
1788  idMatX( void );
1789  explicit idMatX( int rows, int columns );
1790  explicit idMatX( int rows, int columns, float *src );
1791  ~idMatX( void );
1792 
1793  void Set( int rows, int columns, const float *src );
1794  void Set( const idMat3 &m1, const idMat3 &m2 );
1795  void Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 );
1796 
1797  const float * operator[]( int index ) const;
1798  float * operator[]( int index );
1799  idMatX & operator=( const idMatX &a );
1800  idMatX operator*( const float a ) const;
1801  idVecX operator*( const idVecX &vec ) const;
1802  idMatX operator*( const idMatX &a ) const;
1803  idMatX operator+( const idMatX &a ) const;
1804  idMatX operator-( const idMatX &a ) const;
1805  idMatX & operator*=( const float a );
1806  idMatX & operator*=( const idMatX &a );
1807  idMatX & operator+=( const idMatX &a );
1808  idMatX & operator-=( const idMatX &a );
1809 
1810  friend idMatX operator*( const float a, const idMatX &m );
1811  friend idVecX operator*( const idVecX &vec, const idMatX &m );
1812  friend idVecX & operator*=( idVecX &vec, const idMatX &m );
1813 
1814  bool Compare( const idMatX &a ) const; // exact compare, no epsilon
1815  bool Compare( const idMatX &a, const float epsilon ) const; // compare with epsilon
1816  bool operator==( const idMatX &a ) const; // exact compare, no epsilon
1817  bool operator!=( const idMatX &a ) const; // exact compare, no epsilon
1818 
1819  void SetSize( int rows, int columns ); // set the number of rows/columns
1820  void ChangeSize( int rows, int columns, bool makeZero = false ); // change the size keeping data intact where possible
1821  int GetNumRows( void ) const { return numRows; } // get the number of rows
1822  int GetNumColumns( void ) const { return numColumns; } // get the number of columns
1823  void SetData( int rows, int columns, float *data ); // set float array pointer
1824  void Zero( void ); // clear matrix
1825  void Zero( int rows, int columns ); // set size and clear matrix
1826  void Identity( void ); // clear to identity matrix
1827  void Identity( int rows, int columns ); // set size and clear to identity matrix
1828  void Diag( const idVecX &v ); // create diagonal matrix from vector
1829  void Random( int seed, float l = 0.0f, float u = 1.0f ); // fill matrix with random values
1830  void Random( int rows, int columns, int seed, float l = 0.0f, float u = 1.0f );
1831  void Negate( void ); // (*this) = - (*this)
1832  void Clamp( float min, float max ); // clamp all values
1833  idMatX & SwapRows( int r1, int r2 ); // swap rows
1834  idMatX & SwapColumns( int r1, int r2 ); // swap columns
1835  idMatX & SwapRowsColumns( int r1, int r2 ); // swap rows and columns
1836  idMatX & RemoveRow( int r ); // remove a row
1837  idMatX & RemoveColumn( int r ); // remove a column
1838  idMatX & RemoveRowColumn( int r ); // remove a row and column
1839  void ClearUpperTriangle( void ); // clear the upper triangle
1840  void ClearLowerTriangle( void ); // clear the lower triangle
1841  void SquareSubMatrix( const idMatX &m, int size ); // get square sub-matrix from 0,0 to size,size
1842  float MaxDifference( const idMatX &m ) const; // return maximum element difference between this and m
1843 
1844  bool IsSquare( void ) const { return ( numRows == numColumns ); }
1845  bool IsZero( const float epsilon = MATRIX_EPSILON ) const;
1846  bool IsIdentity( const float epsilon = MATRIX_EPSILON ) const;
1847  bool IsDiagonal( const float epsilon = MATRIX_EPSILON ) const;
1848  bool IsTriDiagonal( const float epsilon = MATRIX_EPSILON ) const;
1849  bool IsSymmetric( const float epsilon = MATRIX_EPSILON ) const;
1850  bool IsOrthogonal( const float epsilon = MATRIX_EPSILON ) const;
1851  bool IsOrthonormal( const float epsilon = MATRIX_EPSILON ) const;
1852  bool IsPMatrix( const float epsilon = MATRIX_EPSILON ) const;
1853  bool IsZMatrix( const float epsilon = MATRIX_EPSILON ) const;
1854  bool IsPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const;
1855  bool IsSymmetricPositiveDefinite( const float epsilon = MATRIX_EPSILON ) const;
1856  bool IsPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const;
1857  bool IsSymmetricPositiveSemiDefinite( const float epsilon = MATRIX_EPSILON ) const;
1858 
1859  float Trace( void ) const; // returns product of diagonal elements
1860  float Determinant( void ) const; // returns determinant of matrix
1861  idMatX Transpose( void ) const; // returns transpose
1862  idMatX & TransposeSelf( void ); // transposes the matrix itself
1863  idMatX Inverse( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1864  bool InverseSelf( void ); // returns false if determinant is zero
1865  idMatX InverseFast( void ) const; // returns the inverse ( m * m.Inverse() = identity )
1866  bool InverseFastSelf( void ); // returns false if determinant is zero
1867 
1868  bool LowerTriangularInverse( void ); // in-place inversion, returns false if determinant is zero
1869  bool UpperTriangularInverse( void ); // in-place inversion, returns false if determinant is zero
1870 
1871  idVecX Multiply( const idVecX &vec ) const; // (*this) * vec
1872  idVecX TransposeMultiply( const idVecX &vec ) const; // this->Transpose() * vec
1873 
1874  idMatX Multiply( const idMatX &a ) const; // (*this) * a
1875  idMatX TransposeMultiply( const idMatX &a ) const; // this->Transpose() * a
1876 
1877  void Multiply( idVecX &dst, const idVecX &vec ) const; // dst = (*this) * vec
1878  void MultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += (*this) * vec
1879  void MultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= (*this) * vec
1880  void TransposeMultiply( idVecX &dst, const idVecX &vec ) const; // dst = this->Transpose() * vec
1881  void TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const; // dst += this->Transpose() * vec
1882  void TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const; // dst -= this->Transpose() * vec
1883 
1884  void Multiply( idMatX &dst, const idMatX &a ) const; // dst = (*this) * a
1885  void TransposeMultiply( idMatX &dst, const idMatX &a ) const; // dst = this->Transpose() * a
1886 
1887  int GetDimension( void ) const; // returns total number of values in matrix
1888 
1889  const idVec6 & SubVec6( int row ) const; // interpret beginning of row as a const idVec6
1890  idVec6 & SubVec6( int row ); // interpret beginning of row as an idVec6
1891  const idVecX SubVecX( int row ) const; // interpret complete row as a const idVecX
1892  idVecX SubVecX( int row ); // interpret complete row as an idVecX
1893  const float * ToFloatPtr( void ) const; // pointer to const matrix float array
1894  float * ToFloatPtr( void ); // pointer to matrix float array
1895  const char * ToString( int precision = 2 ) const;
1896 
1897  void Update_RankOne( const idVecX &v, const idVecX &w, float alpha );
1898  void Update_RankOneSymmetric( const idVecX &v, float alpha );
1899  void Update_RowColumn( const idVecX &v, const idVecX &w, int r );
1900  void Update_RowColumnSymmetric( const idVecX &v, int r );
1901  void Update_Increment( const idVecX &v, const idVecX &w );
1902  void Update_IncrementSymmetric( const idVecX &v );
1903  void Update_Decrement( int r );
1904 
1905  bool Inverse_GaussJordan( void ); // invert in-place with Gauss-Jordan elimination
1906  bool Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha );
1907  bool Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r );
1908  bool Inverse_UpdateIncrement( const idVecX &v, const idVecX &w );
1909  bool Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r );
1910  void Inverse_Solve( idVecX &x, const idVecX &b ) const;
1911 
1912  bool LU_Factor( int *index, float *det = NULL ); // factor in-place: L * U
1913  bool LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index );
1914  bool LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index );
1915  bool LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index );
1916  bool LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index );
1917  void LU_Solve( idVecX &x, const idVecX &b, const int *index ) const;
1918  void LU_Inverse( idMatX &inv, const int *index ) const;
1919  void LU_UnpackFactors( idMatX &L, idMatX &U ) const;
1920  void LU_MultiplyFactors( idMatX &m, const int *index ) const;
1921 
1922  bool QR_Factor( idVecX &c, idVecX &d ); // factor in-place: Q * R
1923  bool QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha );
1924  bool QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r );
1925  bool QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w );
1926  bool QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r );
1927  void QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const;
1928  void QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const;
1929  void QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const;
1930  void QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const;
1931  void QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const;
1932 
1933  bool SVD_Factor( idVecX &w, idMatX &V ); // factor in-place: U * Diag(w) * V.Transpose()
1934  void SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const;
1935  void SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const;
1936  void SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const;
1937 
1938  bool Cholesky_Factor( void ); // factor in-place: L * L.Transpose()
1939  bool Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 );
1940  bool Cholesky_UpdateRowColumn( const idVecX &v, int r );
1941  bool Cholesky_UpdateIncrement( const idVecX &v );
1942  bool Cholesky_UpdateDecrement( const idVecX &v, int r );
1943  void Cholesky_Solve( idVecX &x, const idVecX &b ) const;
1944  void Cholesky_Inverse( idMatX &inv ) const;
1945  void Cholesky_MultiplyFactors( idMatX &m ) const;
1946 
1947  bool LDLT_Factor( void ); // factor in-place: L * D * L.Transpose()
1948  bool LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset = 0 );
1949  bool LDLT_UpdateRowColumn( const idVecX &v, int r );
1950  bool LDLT_UpdateIncrement( const idVecX &v );
1951  bool LDLT_UpdateDecrement( const idVecX &v, int r );
1952  void LDLT_Solve( idVecX &x, const idVecX &b ) const;
1953  void LDLT_Inverse( idMatX &inv ) const;
1954  void LDLT_UnpackFactors( idMatX &L, idMatX &D ) const;
1955  void LDLT_MultiplyFactors( idMatX &m ) const;
1956 
1957  void TriDiagonal_ClearTriangles( void );
1958  bool TriDiagonal_Solve( idVecX &x, const idVecX &b ) const;
1959  void TriDiagonal_Inverse( idMatX &inv ) const;
1960 
1961  bool Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues );
1962  bool Eigen_SolveSymmetric( idVecX &eigenValues );
1963  bool Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues );
1964  void Eigen_SortIncreasing( idVecX &eigenValues );
1965  void Eigen_SortDecreasing( idVecX &eigenValues );
1966 
1967  static void Test( void );
1968 
1969 private:
1970  int numRows; // number of rows
1971  int numColumns; // number of columns
1972  int alloced; // floats allocated, if -1 then mat points to data set with SetData
1973  float * mat; // memory the matrix is stored
1974 
1975  static float temp[MATX_MAX_TEMP+4]; // used to store intermediate results
1976  static float * tempPtr; // pointer to 16 byte aligned temporary memory
1977  static int tempIndex; // index into memory pool, wraps around
1978 
1979 private:
1980  void SetTempSize( int rows, int columns );
1981  float DeterminantGeneric( void ) const;
1982  bool InverseSelfGeneric( void );
1983  void QR_Rotate( idMatX &R, int i, float a, float b );
1984  float Pythag( float a, float b ) const;
1985  void SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm );
1986  void SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 );
1987  void HouseholderReduction( idVecX &diag, idVecX &subd );
1988  bool QL( idVecX &diag, idVecX &subd );
1989  void HessenbergReduction( idMatX &H );
1990  void ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi );
1991  bool HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues );
1992 };
1993 
1994 ID_INLINE idMatX::idMatX( void ) {
1995  numRows = numColumns = alloced = 0;
1996  mat = NULL;
1997 }
1998 
1999 ID_INLINE idMatX::~idMatX( void ) {
2000  // if not temp memory
2001  if ( mat != NULL && ( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP ) && alloced != -1 ) {
2002  Mem_Free16( mat );
2003  }
2004 }
2005 
2006 ID_INLINE idMatX::idMatX( int rows, int columns ) {
2007  numRows = numColumns = alloced = 0;
2008  mat = NULL;
2009  SetSize( rows, columns );
2010 }
2011 
2012 ID_INLINE idMatX::idMatX( int rows, int columns, float *src ) {
2013  numRows = numColumns = alloced = 0;
2014  mat = NULL;
2015  SetData( rows, columns, src );
2016 }
2017 
2018 ID_INLINE void idMatX::Set( int rows, int columns, const float *src ) {
2019  SetSize( rows, columns );
2020  memcpy( this->mat, src, rows * columns * sizeof( float ) );
2021 }
2022 
2023 ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2 ) {
2024  int i, j;
2025 
2026  SetSize( 3, 6 );
2027  for ( i = 0; i < 3; i++ ) {
2028  for ( j = 0; j < 3; j++ ) {
2029  mat[(i+0) * numColumns + (j+0)] = m1[i][j];
2030  mat[(i+0) * numColumns + (j+3)] = m2[i][j];
2031  }
2032  }
2033 }
2034 
2035 ID_INLINE void idMatX::Set( const idMat3 &m1, const idMat3 &m2, const idMat3 &m3, const idMat3 &m4 ) {
2036  int i, j;
2037 
2038  SetSize( 6, 6 );
2039  for ( i = 0; i < 3; i++ ) {
2040  for ( j = 0; j < 3; j++ ) {
2041  mat[(i+0) * numColumns + (j+0)] = m1[i][j];
2042  mat[(i+0) * numColumns + (j+3)] = m2[i][j];
2043  mat[(i+3) * numColumns + (j+0)] = m3[i][j];
2044  mat[(i+3) * numColumns + (j+3)] = m4[i][j];
2045  }
2046  }
2047 }
2048 
2049 ID_INLINE const float *idMatX::operator[]( int index ) const {
2050  assert( ( index >= 0 ) && ( index < numRows ) );
2051  return mat + index * numColumns;
2052 }
2053 
2054 ID_INLINE float *idMatX::operator[]( int index ) {
2055  assert( ( index >= 0 ) && ( index < numRows ) );
2056  return mat + index * numColumns;
2057 }
2058 
2059 ID_INLINE idMatX &idMatX::operator=( const idMatX &a ) {
2060  SetSize( a.numRows, a.numColumns );
2061 #ifdef MATX_SIMD
2062  SIMDProcessor->Copy16( mat, a.mat, a.numRows * a.numColumns );
2063 #else
2064  memcpy( mat, a.mat, a.numRows * a.numColumns * sizeof( float ) );
2065 #endif
2066  idMatX::tempIndex = 0;
2067  return *this;
2068 }
2069 
2070 ID_INLINE idMatX idMatX::operator*( const float a ) const {
2071  idMatX m;
2072 
2074 #ifdef MATX_SIMD
2076 #else
2077  int i, s;
2078  s = numRows * numColumns;
2079  for ( i = 0; i < s; i++ ) {
2080  m.mat[i] = mat[i] * a;
2081  }
2082 #endif
2083  return m;
2084 }
2085 
2086 ID_INLINE idVecX idMatX::operator*( const idVecX &vec ) const {
2087  idVecX dst;
2088 
2089  assert( numColumns == vec.GetSize() );
2090 
2091  dst.SetTempSize( numRows );
2092 #ifdef MATX_SIMD
2093  SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec );
2094 #else
2095  Multiply( dst, vec );
2096 #endif
2097  return dst;
2098 }
2099 
2100 ID_INLINE idMatX idMatX::operator*( const idMatX &a ) const {
2101  idMatX dst;
2102 
2103  assert( numColumns == a.numRows );
2104 
2105  dst.SetTempSize( numRows, a.numColumns );
2106 #ifdef MATX_SIMD
2107  SIMDProcessor->MatX_MultiplyMatX( dst, *this, a );
2108 #else
2109  Multiply( dst, a );
2110 #endif
2111  return dst;
2112 }
2113 
2114 ID_INLINE idMatX idMatX::operator+( const idMatX &a ) const {
2115  idMatX m;
2116 
2117  assert( numRows == a.numRows && numColumns == a.numColumns );
2119 #ifdef MATX_SIMD
2121 #else
2122  int i, s;
2123  s = numRows * numColumns;
2124  for ( i = 0; i < s; i++ ) {
2125  m.mat[i] = mat[i] + a.mat[i];
2126  }
2127 #endif
2128  return m;
2129 }
2130 
2131 ID_INLINE idMatX idMatX::operator-( const idMatX &a ) const {
2132  idMatX m;
2133 
2134  assert( numRows == a.numRows && numColumns == a.numColumns );
2136 #ifdef MATX_SIMD
2138 #else
2139  int i, s;
2140  s = numRows * numColumns;
2141  for ( i = 0; i < s; i++ ) {
2142  m.mat[i] = mat[i] - a.mat[i];
2143  }
2144 #endif
2145  return m;
2146 }
2147 
2148 ID_INLINE idMatX &idMatX::operator*=( const float a ) {
2149 #ifdef MATX_SIMD
2151 #else
2152  int i, s;
2153  s = numRows * numColumns;
2154  for ( i = 0; i < s; i++ ) {
2155  mat[i] *= a;
2156  }
2157 #endif
2158  idMatX::tempIndex = 0;
2159  return *this;
2160 }
2161 
2162 ID_INLINE idMatX &idMatX::operator*=( const idMatX &a ) {
2163  *this = *this * a;
2164  idMatX::tempIndex = 0;
2165  return *this;
2166 }
2167 
2168 ID_INLINE idMatX &idMatX::operator+=( const idMatX &a ) {
2169  assert( numRows == a.numRows && numColumns == a.numColumns );
2170 #ifdef MATX_SIMD
2172 #else
2173  int i, s;
2174  s = numRows * numColumns;
2175  for ( i = 0; i < s; i++ ) {
2176  mat[i] += a.mat[i];
2177  }
2178 #endif
2179  idMatX::tempIndex = 0;
2180  return *this;
2181 }
2182 
2183 ID_INLINE idMatX &idMatX::operator-=( const idMatX &a ) {
2184  assert( numRows == a.numRows && numColumns == a.numColumns );
2185 #ifdef MATX_SIMD
2187 #else
2188  int i, s;
2189  s = numRows * numColumns;
2190  for ( i = 0; i < s; i++ ) {
2191  mat[i] -= a.mat[i];
2192  }
2193 #endif
2194  idMatX::tempIndex = 0;
2195  return *this;
2196 }
2197 
2198 ID_INLINE idMatX operator*( const float a, idMatX const &m ) {
2199  return m * a;
2200 }
2201 
2202 ID_INLINE idVecX operator*( const idVecX &vec, const idMatX &m ) {
2203  return m * vec;
2204 }
2205 
2206 ID_INLINE idVecX &operator*=( idVecX &vec, const idMatX &m ) {
2207  vec = m * vec;
2208  return vec;
2209 }
2210 
2211 ID_INLINE bool idMatX::Compare( const idMatX &a ) const {
2212  int i, s;
2213 
2214  assert( numRows == a.numRows && numColumns == a.numColumns );
2215 
2216  s = numRows * numColumns;
2217  for ( i = 0; i < s; i++ ) {
2218  if ( mat[i] != a.mat[i] ) {
2219  return false;
2220  }
2221  }
2222  return true;
2223 }
2224 
2225 ID_INLINE bool idMatX::Compare( const idMatX &a, const float epsilon ) const {
2226  int i, s;
2227 
2228  assert( numRows == a.numRows && numColumns == a.numColumns );
2229 
2230  s = numRows * numColumns;
2231  for ( i = 0; i < s; i++ ) {
2232  if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) {
2233  return false;
2234  }
2235  }
2236  return true;
2237 }
2238 
2239 ID_INLINE bool idMatX::operator==( const idMatX &a ) const {
2240  return Compare( a );
2241 }
2242 
2243 ID_INLINE bool idMatX::operator!=( const idMatX &a ) const {
2244  return !Compare( a );
2245 }
2246 
2247 ID_INLINE void idMatX::SetSize( int rows, int columns ) {
2248  assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP );
2249  int alloc = ( rows * columns + 3 ) & ~3;
2250  if ( alloc > alloced && alloced != -1 ) {
2251  if ( mat != NULL ) {
2252  Mem_Free16( mat );
2253  }
2254  mat = (float *) Mem_Alloc16( alloc * sizeof( float ) );
2255  alloced = alloc;
2256  }
2257  numRows = rows;
2258  numColumns = columns;
2259  MATX_CLEAREND();
2260 }
2261 
2262 ID_INLINE void idMatX::SetTempSize( int rows, int columns ) {
2263  int newSize;
2264 
2265  newSize = ( rows * columns + 3 ) & ~3;
2266  assert( newSize < MATX_MAX_TEMP );
2267  if ( idMatX::tempIndex + newSize > MATX_MAX_TEMP ) {
2268  idMatX::tempIndex = 0;
2269  }
2271  idMatX::tempIndex += newSize;
2272  alloced = newSize;
2273  numRows = rows;
2274  numColumns = columns;
2275  MATX_CLEAREND();
2276 }
2277 
2278 ID_INLINE void idMatX::SetData( int rows, int columns, float *data ) {
2279  assert( mat < idMatX::tempPtr || mat > idMatX::tempPtr + MATX_MAX_TEMP );
2280  if ( mat != NULL && alloced != -1 ) {
2281  Mem_Free16( mat );
2282  }
2283  assert( ( ( (int) data ) & 15 ) == 0 ); // data must be 16 byte aligned
2284  mat = data;
2285  alloced = -1;
2286  numRows = rows;
2287  numColumns = columns;
2288  MATX_CLEAREND();
2289 }
2290 
2291 ID_INLINE void idMatX::Zero( void ) {
2292 #ifdef MATX_SIMD
2294 #else
2295  memset( mat, 0, numRows * numColumns * sizeof( float ) );
2296 #endif
2297 }
2298 
2299 ID_INLINE void idMatX::Zero( int rows, int columns ) {
2300  SetSize( rows, columns );
2301 #ifdef MATX_SIMD
2303 #else
2304  memset( mat, 0, rows * columns * sizeof( float ) );
2305 #endif
2306 }
2307 
2308 ID_INLINE void idMatX::Identity( void ) {
2309  assert( numRows == numColumns );
2310 #ifdef MATX_SIMD
2312 #else
2313  memset( mat, 0, numRows * numColumns * sizeof( float ) );
2314 #endif
2315  for ( int i = 0; i < numRows; i++ ) {
2316  mat[i * numColumns + i] = 1.0f;
2317  }
2318 }
2319 
2320 ID_INLINE void idMatX::Identity( int rows, int columns ) {
2321  assert( rows == columns );
2322  SetSize( rows, columns );
2323  idMatX::Identity();
2324 }
2325 
2326 ID_INLINE void idMatX::Diag( const idVecX &v ) {
2327  Zero( v.GetSize(), v.GetSize() );
2328  for ( int i = 0; i < v.GetSize(); i++ ) {
2329  mat[i * numColumns + i] = v[i];
2330  }
2331 }
2332 
2333 ID_INLINE void idMatX::Random( int seed, float l, float u ) {
2334  int i, s;
2335  float c;
2336  idRandom rnd(seed);
2337 
2338  c = u - l;
2339  s = numRows * numColumns;
2340  for ( i = 0; i < s; i++ ) {
2341  mat[i] = l + rnd.RandomFloat() * c;
2342  }
2343 }
2344 
2345 ID_INLINE void idMatX::Random( int rows, int columns, int seed, float l, float u ) {
2346  int i, s;
2347  float c;
2348  idRandom rnd(seed);
2349 
2350  SetSize( rows, columns );
2351  c = u - l;
2352  s = numRows * numColumns;
2353  for ( i = 0; i < s; i++ ) {
2354  mat[i] = l + rnd.RandomFloat() * c;
2355  }
2356 }
2357 
2358 ID_INLINE void idMatX::Negate( void ) {
2359 #ifdef MATX_SIMD
2361 #else
2362  int i, s;
2363  s = numRows * numColumns;
2364  for ( i = 0; i < s; i++ ) {
2365  mat[i] = -mat[i];
2366  }
2367 #endif
2368 }
2369 
2370 ID_INLINE void idMatX::Clamp( float min, float max ) {
2371  int i, s;
2372  s = numRows * numColumns;
2373  for ( i = 0; i < s; i++ ) {
2374  if ( mat[i] < min ) {
2375  mat[i] = min;
2376  } else if ( mat[i] > max ) {
2377  mat[i] = max;
2378  }
2379  }
2380 }
2381 
2382 ID_INLINE idMatX &idMatX::SwapRows( int r1, int r2 ) {
2383  float *ptr;
2384 
2385  ptr = (float *) _alloca16( numColumns * sizeof( float ) );
2386  memcpy( ptr, mat + r1 * numColumns, numColumns * sizeof( float ) );
2387  memcpy( mat + r1 * numColumns, mat + r2 * numColumns, numColumns * sizeof( float ) );
2388  memcpy( mat + r2 * numColumns, ptr, numColumns * sizeof( float ) );
2389 
2390  return *this;
2391 }
2392 
2393 ID_INLINE idMatX &idMatX::SwapColumns( int r1, int r2 ) {
2394  int i;
2395  float tmp, *ptr;
2396 
2397  for ( i = 0; i < numRows; i++ ) {
2398  ptr = mat + i * numColumns;
2399  tmp = ptr[r1];
2400  ptr[r1] = ptr[r2];
2401  ptr[r2] = tmp;
2402  }
2403 
2404  return *this;
2405 }
2406 
2407 ID_INLINE idMatX &idMatX::SwapRowsColumns( int r1, int r2 ) {
2408 
2409  SwapRows( r1, r2 );
2410  SwapColumns( r1, r2 );
2411  return *this;
2412 }
2413 
2414 ID_INLINE void idMatX::ClearUpperTriangle( void ) {
2415  assert( numRows == numColumns );
2416  for ( int i = numRows-2; i >= 0; i-- ) {
2417  memset( mat + i * numColumns + i + 1, 0, (numColumns - 1 - i) * sizeof(float) );
2418  }
2419 }
2420 
2421 ID_INLINE void idMatX::ClearLowerTriangle( void ) {
2422  assert( numRows == numColumns );
2423  for ( int i = 1; i < numRows; i++ ) {
2424  memset( mat + i * numColumns, 0, i * sizeof(float) );
2425  }
2426 }
2427 
2428 ID_INLINE void idMatX::SquareSubMatrix( const idMatX &m, int size ) {
2429  int i;
2430  assert( size <= m.numRows && size <= m.numColumns );
2431  SetSize( size, size );
2432  for ( i = 0; i < size; i++ ) {
2433  memcpy( mat + i * numColumns, m.mat + i * m.numColumns, size * sizeof( float ) );
2434  }
2435 }
2436 
2437 ID_INLINE float idMatX::MaxDifference( const idMatX &m ) const {
2438  int i, j;
2439  float diff, maxDiff;
2440 
2441  assert( numRows == m.numRows && numColumns == m.numColumns );
2442 
2443  maxDiff = -1.0f;
2444  for ( i = 0; i < numRows; i++ ) {
2445  for ( j = 0; j < numColumns; j++ ) {
2446  diff = idMath::Fabs( mat[ i * numColumns + j ] - m[i][j] );
2447  if ( maxDiff < 0.0f || diff > maxDiff ) {
2448  maxDiff = diff;
2449  }
2450  }
2451  }
2452  return maxDiff;
2453 }
2454 
2455 ID_INLINE bool idMatX::IsZero( const float epsilon ) const {
2456  // returns true if (*this) == Zero
2457  for ( int i = 0; i < numRows; i++ ) {
2458  for ( int j = 0; j < numColumns; j++ ) {
2459  if ( idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) {
2460  return false;
2461  }
2462  }
2463  }
2464  return true;
2465 }
2466 
2467 ID_INLINE bool idMatX::IsIdentity( const float epsilon ) const {
2468  // returns true if (*this) == Identity
2469  assert( numRows == numColumns );
2470  for ( int i = 0; i < numRows; i++ ) {
2471  for ( int j = 0; j < numColumns; j++ ) {
2472  if ( idMath::Fabs( mat[i * numColumns + j] - (float)( i == j ) ) > epsilon ) {
2473  return false;
2474  }
2475  }
2476  }
2477  return true;
2478 }
2479 
2480 ID_INLINE bool idMatX::IsDiagonal( const float epsilon ) const {
2481  // returns true if all elements are zero except for the elements on the diagonal
2482  assert( numRows == numColumns );
2483  for ( int i = 0; i < numRows; i++ ) {
2484  for ( int j = 0; j < numColumns; j++ ) {
2485  if ( i != j && idMath::Fabs( mat[i * numColumns + j] ) > epsilon ) {
2486  return false;
2487  }
2488  }
2489  }
2490  return true;
2491 }
2492 
2493 ID_INLINE bool idMatX::IsTriDiagonal( const float epsilon ) const {
2494  // returns true if all elements are zero except for the elements on the diagonal plus or minus one column
2495 
2496  if ( numRows != numColumns ) {
2497  return false;
2498  }
2499  for ( int i = 0; i < numRows-2; i++ ) {
2500  for ( int j = i+2; j < numColumns; j++ ) {
2501  if ( idMath::Fabs( (*this)[i][j] ) > epsilon ) {
2502  return false;
2503  }
2504  if ( idMath::Fabs( (*this)[j][i] ) > epsilon ) {
2505  return false;
2506  }
2507  }
2508  }
2509  return true;
2510 }
2511 
2512 ID_INLINE bool idMatX::IsSymmetric( const float epsilon ) const {
2513  // (*this)[i][j] == (*this)[j][i]
2514  if ( numRows != numColumns ) {
2515  return false;
2516  }
2517  for ( int i = 0; i < numRows; i++ ) {
2518  for ( int j = 0; j < numColumns; j++ ) {
2519  if ( idMath::Fabs( mat[ i * numColumns + j ] - mat[ j * numColumns + i ] ) > epsilon ) {
2520  return false;
2521  }
2522  }
2523  }
2524  return true;
2525 }
2526 
2527 ID_INLINE float idMatX::Trace( void ) const {
2528  float trace = 0.0f;
2529 
2530  assert( numRows == numColumns );
2531 
2532  // sum of elements on the diagonal
2533  for ( int i = 0; i < numRows; i++ ) {
2534  trace += mat[i * numRows + i];
2535  }
2536  return trace;
2537 }
2538 
2539 ID_INLINE float idMatX::Determinant( void ) const {
2540 
2541  assert( numRows == numColumns );
2542 
2543  switch( numRows ) {
2544  case 1:
2545  return mat[0];
2546  case 2:
2547  return reinterpret_cast<const idMat2 *>(mat)->Determinant();
2548  case 3:
2549  return reinterpret_cast<const idMat3 *>(mat)->Determinant();
2550  case 4:
2551  return reinterpret_cast<const idMat4 *>(mat)->Determinant();
2552  case 5:
2553  return reinterpret_cast<const idMat5 *>(mat)->Determinant();
2554  case 6:
2555  return reinterpret_cast<const idMat6 *>(mat)->Determinant();
2556  default:
2557  return DeterminantGeneric();
2558  }
2559  return 0.0f;
2560 }
2561 
2562 ID_INLINE idMatX idMatX::Transpose( void ) const {
2563  idMatX transpose;
2564  int i, j;
2565 
2566  transpose.SetTempSize( numColumns, numRows );
2567 
2568  for ( i = 0; i < numRows; i++ ) {
2569  for ( j = 0; j < numColumns; j++ ) {
2570  transpose.mat[j * transpose.numColumns + i] = mat[i * numColumns + j];
2571  }
2572  }
2573 
2574  return transpose;
2575 }
2576 
2577 ID_INLINE idMatX &idMatX::TransposeSelf( void ) {
2578  *this = Transpose();
2579  return *this;
2580 }
2581 
2582 ID_INLINE idMatX idMatX::Inverse( void ) const {
2583  idMatX invMat;
2584 
2585  invMat.SetTempSize( numRows, numColumns );
2586  memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) );
2587  int r = invMat.InverseSelf();
2588  assert( r );
2589  return invMat;
2590 }
2591 
2592 ID_INLINE bool idMatX::InverseSelf( void ) {
2593 
2594  assert( numRows == numColumns );
2595 
2596  switch( numRows ) {
2597  case 1:
2598  if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) {
2599  return false;
2600  }
2601  mat[0] = 1.0f / mat[0];
2602  return true;
2603  case 2:
2604  return reinterpret_cast<idMat2 *>(mat)->InverseSelf();
2605  case 3:
2606  return reinterpret_cast<idMat3 *>(mat)->InverseSelf();
2607  case 4:
2608  return reinterpret_cast<idMat4 *>(mat)->InverseSelf();
2609  case 5:
2610  return reinterpret_cast<idMat5 *>(mat)->InverseSelf();
2611  case 6:
2612  return reinterpret_cast<idMat6 *>(mat)->InverseSelf();
2613  default:
2614  return InverseSelfGeneric();
2615  }
2616 }
2617 
2618 ID_INLINE idMatX idMatX::InverseFast( void ) const {
2619  idMatX invMat;
2620 
2621  invMat.SetTempSize( numRows, numColumns );
2622  memcpy( invMat.mat, mat, numRows * numColumns * sizeof( float ) );
2623  int r = invMat.InverseFastSelf();
2624  assert( r );
2625  return invMat;
2626 }
2627 
2628 ID_INLINE bool idMatX::InverseFastSelf( void ) {
2629 
2630  assert( numRows == numColumns );
2631 
2632  switch( numRows ) {
2633  case 1:
2634  if ( idMath::Fabs( mat[0] ) < MATRIX_INVERSE_EPSILON ) {
2635  return false;
2636  }
2637  mat[0] = 1.0f / mat[0];
2638  return true;
2639  case 2:
2640  return reinterpret_cast<idMat2 *>(mat)->InverseFastSelf();
2641  case 3:
2642  return reinterpret_cast<idMat3 *>(mat)->InverseFastSelf();
2643  case 4:
2644  return reinterpret_cast<idMat4 *>(mat)->InverseFastSelf();
2645  case 5:
2646  return reinterpret_cast<idMat5 *>(mat)->InverseFastSelf();
2647  case 6:
2648  return reinterpret_cast<idMat6 *>(mat)->InverseFastSelf();
2649  default:
2650  return InverseSelfGeneric();
2651  }
2652  return false;
2653 }
2654 
2655 ID_INLINE idVecX idMatX::Multiply( const idVecX &vec ) const {
2656  idVecX dst;
2657 
2658  assert( numColumns == vec.GetSize() );
2659 
2660  dst.SetTempSize( numRows );
2661 #ifdef MATX_SIMD
2662  SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec );
2663 #else
2664  Multiply( dst, vec );
2665 #endif
2666  return dst;
2667 }
2668 
2669 ID_INLINE idMatX idMatX::Multiply( const idMatX &a ) const {
2670  idMatX dst;
2671 
2672  assert( numColumns == a.numRows );
2673 
2674  dst.SetTempSize( numRows, a.numColumns );
2675 #ifdef MATX_SIMD
2676  SIMDProcessor->MatX_MultiplyMatX( dst, *this, a );
2677 #else
2678  Multiply( dst, a );
2679 #endif
2680  return dst;
2681 }
2682 
2683 ID_INLINE idVecX idMatX::TransposeMultiply( const idVecX &vec ) const {
2684  idVecX dst;
2685 
2686  assert( numRows == vec.GetSize() );
2687 
2688  dst.SetTempSize( numColumns );
2689 #ifdef MATX_SIMD
2690  SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec );
2691 #else
2692  TransposeMultiply( dst, vec );
2693 #endif
2694  return dst;
2695 }
2696 
2697 ID_INLINE idMatX idMatX::TransposeMultiply( const idMatX &a ) const {
2698  idMatX dst;
2699 
2700  assert( numRows == a.numRows );
2701 
2702  dst.SetTempSize( numColumns, a.numColumns );
2703 #ifdef MATX_SIMD
2704  SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a );
2705 #else
2706  TransposeMultiply( dst, a );
2707 #endif
2708  return dst;
2709 }
2710 
2711 ID_INLINE void idMatX::Multiply( idVecX &dst, const idVecX &vec ) const {
2712 #ifdef MATX_SIMD
2713  SIMDProcessor->MatX_MultiplyVecX( dst, *this, vec );
2714 #else
2715  int i, j;
2716  const float *mPtr, *vPtr;
2717  float *dstPtr;
2718 
2719  mPtr = mat;
2720  vPtr = vec.ToFloatPtr();
2721  dstPtr = dst.ToFloatPtr();
2722  for ( i = 0; i < numRows; i++ ) {
2723  float sum = mPtr[0] * vPtr[0];
2724  for ( j = 1; j < numColumns; j++ ) {
2725  sum += mPtr[j] * vPtr[j];
2726  }
2727  dstPtr[i] = sum;
2728  mPtr += numColumns;
2729  }
2730 #endif
2731 }
2732 
2733 ID_INLINE void idMatX::MultiplyAdd( idVecX &dst, const idVecX &vec ) const {
2734 #ifdef MATX_SIMD
2735  SIMDProcessor->MatX_MultiplyAddVecX( dst, *this, vec );
2736 #else
2737  int i, j;
2738  const float *mPtr, *vPtr;
2739  float *dstPtr;
2740 
2741  mPtr = mat;
2742  vPtr = vec.ToFloatPtr();
2743  dstPtr = dst.ToFloatPtr();
2744  for ( i = 0; i < numRows; i++ ) {
2745  float sum = mPtr[0] * vPtr[0];
2746  for ( j = 1; j < numColumns; j++ ) {
2747  sum += mPtr[j] * vPtr[j];
2748  }
2749  dstPtr[i] += sum;
2750  mPtr += numColumns;
2751  }
2752 #endif
2753 }
2754 
2755 ID_INLINE void idMatX::MultiplySub( idVecX &dst, const idVecX &vec ) const {
2756 #ifdef MATX_SIMD
2757  SIMDProcessor->MatX_MultiplySubVecX( dst, *this, vec );
2758 #else
2759  int i, j;
2760  const float *mPtr, *vPtr;
2761  float *dstPtr;
2762 
2763  mPtr = mat;
2764  vPtr = vec.ToFloatPtr();
2765  dstPtr = dst.ToFloatPtr();
2766  for ( i = 0; i < numRows; i++ ) {
2767  float sum = mPtr[0] * vPtr[0];
2768  for ( j = 1; j < numColumns; j++ ) {
2769  sum += mPtr[j] * vPtr[j];
2770  }
2771  dstPtr[i] -= sum;
2772  mPtr += numColumns;
2773  }
2774 #endif
2775 }
2776 
2777 ID_INLINE void idMatX::TransposeMultiply( idVecX &dst, const idVecX &vec ) const {
2778 #ifdef MATX_SIMD
2779  SIMDProcessor->MatX_TransposeMultiplyVecX( dst, *this, vec );
2780 #else
2781  int i, j;
2782  const float *mPtr, *vPtr;
2783  float *dstPtr;
2784 
2785  vPtr = vec.ToFloatPtr();
2786  dstPtr = dst.ToFloatPtr();
2787  for ( i = 0; i < numColumns; i++ ) {
2788  mPtr = mat + i;
2789  float sum = mPtr[0] * vPtr[0];
2790  for ( j = 1; j < numRows; j++ ) {
2791  mPtr += numColumns;
2792  sum += mPtr[0] * vPtr[j];
2793  }
2794  dstPtr[i] = sum;
2795  }
2796 #endif
2797 }
2798 
2799 ID_INLINE void idMatX::TransposeMultiplyAdd( idVecX &dst, const idVecX &vec ) const {
2800 #ifdef MATX_SIMD
2801  SIMDProcessor->MatX_TransposeMultiplyAddVecX( dst, *this, vec );
2802 #else
2803  int i, j;
2804  const float *mPtr, *vPtr;
2805  float *dstPtr;
2806 
2807  vPtr = vec.ToFloatPtr();
2808  dstPtr = dst.ToFloatPtr();
2809  for ( i = 0; i < numColumns; i++ ) {
2810  mPtr = mat + i;
2811  float sum = mPtr[0] * vPtr[0];
2812  for ( j = 1; j < numRows; j++ ) {
2813  mPtr += numColumns;
2814  sum += mPtr[0] * vPtr[j];
2815  }
2816  dstPtr[i] += sum;
2817  }
2818 #endif
2819 }
2820 
2821 ID_INLINE void idMatX::TransposeMultiplySub( idVecX &dst, const idVecX &vec ) const {
2822 #ifdef MATX_SIMD
2823  SIMDProcessor->MatX_TransposeMultiplySubVecX( dst, *this, vec );
2824 #else
2825  int i, j;
2826  const float *mPtr, *vPtr;
2827  float *dstPtr;
2828 
2829  vPtr = vec.ToFloatPtr();
2830  dstPtr = dst.ToFloatPtr();
2831  for ( i = 0; i < numColumns; i++ ) {
2832  mPtr = mat + i;
2833  float sum = mPtr[0] * vPtr[0];
2834  for ( j = 1; j < numRows; j++ ) {
2835  mPtr += numColumns;
2836  sum += mPtr[0] * vPtr[j];
2837  }
2838  dstPtr[i] -= sum;
2839  }
2840 #endif
2841 }
2842 
2843 ID_INLINE void idMatX::Multiply( idMatX &dst, const idMatX &a ) const {
2844 #ifdef MATX_SIMD
2845  SIMDProcessor->MatX_MultiplyMatX( dst, *this, a );
2846 #else
2847  int i, j, k, l, n;
2848  float *dstPtr;
2849  const float *m1Ptr, *m2Ptr;
2850  double sum;
2851 
2852  assert( numColumns == a.numRows );
2853 
2854  dstPtr = dst.ToFloatPtr();
2855  m1Ptr = ToFloatPtr();
2856  m2Ptr = a.ToFloatPtr();
2857  k = numRows;
2858  l = a.GetNumColumns();
2859 
2860  for ( i = 0; i < k; i++ ) {
2861  for ( j = 0; j < l; j++ ) {
2862  m2Ptr = a.ToFloatPtr() + j;
2863  sum = m1Ptr[0] * m2Ptr[0];
2864  for ( n = 1; n < numColumns; n++ ) {
2865  m2Ptr += l;
2866  sum += m1Ptr[n] * m2Ptr[0];
2867  }
2868  *dstPtr++ = sum;
2869  }
2870  m1Ptr += numColumns;
2871  }
2872 #endif
2873 }
2874 
2875 ID_INLINE void idMatX::TransposeMultiply( idMatX &dst, const idMatX &a ) const {
2876 #ifdef MATX_SIMD
2877  SIMDProcessor->MatX_TransposeMultiplyMatX( dst, *this, a );
2878 #else
2879  int i, j, k, l, n;
2880  float *dstPtr;
2881  const float *m1Ptr, *m2Ptr;
2882  double sum;
2883 
2884  assert( numRows == a.numRows );
2885 
2886  dstPtr = dst.ToFloatPtr();
2887  m1Ptr = ToFloatPtr();
2888  k = numColumns;
2889  l = a.numColumns;
2890 
2891  for ( i = 0; i < k; i++ ) {
2892  for ( j = 0; j < l; j++ ) {
2893  m1Ptr = ToFloatPtr() + i;
2894  m2Ptr = a.ToFloatPtr() + j;
2895  sum = m1Ptr[0] * m2Ptr[0];
2896  for ( n = 1; n < numRows; n++ ) {
2897  m1Ptr += numColumns;
2898  m2Ptr += a.numColumns;
2899  sum += m1Ptr[0] * m2Ptr[0];
2900  }
2901  *dstPtr++ = sum;
2902  }
2903  }
2904 #endif
2905 }
2906 
2907 ID_INLINE int idMatX::GetDimension( void ) const {
2908  return numRows * numColumns;
2909 }
2910 
2911 ID_INLINE const idVec6 &idMatX::SubVec6( int row ) const {
2912  assert( numColumns >= 6 && row >= 0 && row < numRows );
2913  return *reinterpret_cast<const idVec6 *>(mat + row * numColumns);
2914 }
2915 
2916 ID_INLINE idVec6 &idMatX::SubVec6( int row ) {
2917  assert( numColumns >= 6 && row >= 0 && row < numRows );
2918  return *reinterpret_cast<idVec6 *>(mat + row * numColumns);
2919 }
2920 
2921 ID_INLINE const idVecX idMatX::SubVecX( int row ) const {
2922  idVecX v;
2923  assert( row >= 0 && row < numRows );
2924  v.SetData( numColumns, mat + row * numColumns );
2925  return v;
2926 }
2927 
2928 ID_INLINE idVecX idMatX::SubVecX( int row ) {
2929  idVecX v;
2930  assert( row >= 0 && row < numRows );
2931  v.SetData( numColumns, mat + row * numColumns );
2932  return v;
2933 }
2934 
2935 ID_INLINE const float *idMatX::ToFloatPtr( void ) const {
2936  return mat;
2937 }
2938 
2939 ID_INLINE float *idMatX::ToFloatPtr( void ) {
2940  return mat;
2941 }
2942 
2943 #endif /* !__MATH_MATRIX_H__ */
idMat4 operator+(const idMat4 &a) const
Definition: Matrix.h:946
idCQuat ToCQuat(void) const
Definition: Matrix.cpp:233
bool IsRotated(void) const
Definition: Matrix.h:1083
bool InverseFastSelf(void)
Definition: Matrix.h:2628
idVecX TransposeMultiply(const idVecX &vec) const
Definition: Matrix.h:2683
idMatX operator-(const idMatX &a) const
Definition: Matrix.h:2131
void ComplexDivision(float xr, float xi, float yr, float yi, float &cdivr, float &cdivi)
Definition: Matrix.cpp:6656
void Cholesky_Solve(idVecX &x, const idVecX &b) const
Definition: Matrix.cpp:5657
idMatX & TransposeSelf(void)
Definition: Matrix.h:2577
unsigned int dword
Definition: Lib.h:77
void Zero(void)
Definition: Matrix.h:1691
float Trace(void) const
Definition: Matrix.h:1103
idMatX & operator+=(const idMatX &a)
Definition: Matrix.h:2168
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:2512
#define min(a, b)
idMat5 operator-(const idMat5 &a) const
Definition: Matrix.h:1284
bool Eigen_SolveSymmetric(idVecX &eigenValues)
Definition: Matrix.cpp:6550
void LU_Inverse(idMatX &inv, const int *index) const
Definition: Matrix.cpp:4344
float Normalize(void)
Definition: Vector.h:646
virtual void VPCALL MatX_TransposeMultiplyAddVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
static int tempIndex
Definition: Matrix.h:1977
bool operator!=(const idMat3 &a) const
Definition: Matrix.h:583
virtual void VPCALL Sub16(float *dst, const float *src1, const float *src2, const int count)=0
const float * ToFloatPtr(void) const
Definition: Matrix.h:316
virtual void VPCALL SubAssign16(float *dst, const float *src, const int count)=0
idMat3 operator-() const
Definition: Matrix.h:444
assert(prefInfo.fullscreenBtn)
idMat4 Inverse(void) const
Definition: Matrix.h:1107
idVec6 mat[6]
Definition: Matrix.h:1500
Definition: Quat.h:306
int GetSize(void) const
Definition: Vector.h:1467
bool Cholesky_UpdateRowColumn(const idVecX &v, int r)
Definition: Matrix.cpp:5392
bool IsSquare(void) const
Definition: Matrix.h:1844
bool Compare(const idMat3 &a) const
Definition: Matrix.h:561
idMat2 mat2_zero
bool operator!=(const idMatX &a) const
Definition: Matrix.h:2243
ID_INLINE void TransposeMultiply(const idMat3 &transpose, const idMat3 &b, idMat3 &dst)
Definition: Matrix.h:729
float Trace(void) const
Definition: Matrix.h:652
void QR_Rotate(idMatX &R, int i, float a, float b)
Definition: Matrix.cpp:4504
bool Cholesky_UpdateIncrement(const idVecX &v)
Definition: Matrix.cpp:5574
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1061
float y
Definition: Vector.h:811
bool operator==(const idMat4 &a) const
Definition: Matrix.h:1041
idMat4 & operator-=(const idMat4 &a)
Definition: Matrix.h:983
bool QR_UpdateRankOne(idMatX &R, const idVecX &v, const idVecX &w, float alpha)
Definition: Matrix.cpp:4547
float y
Definition: Vector.h:55
float DeterminantGeneric(void) const
Definition: Matrix.cpp:7138
void UnprojectVector(const idVec4 &src, idVec4 &dst) const
Definition: Matrix.h:1099
bool QR_UpdateRowColumn(idMatX &R, const idVecX &v, const idVecX &w, int r)
Definition: Matrix.cpp:4598
bool InverseSelf(void)
Definition: Matrix.cpp:689
void Update_RowColumn(const idVecX &v, const idVecX &w, int r)
Definition: Matrix.cpp:3500
const GLdouble * v
Definition: glext.h:2936
const char * ToString(int precision=2) const
Definition: Matrix.cpp:610
float MaxDifference(const idMatX &m) const
Definition: Matrix.h:2437
const float * ToFloatPtr(void) const
Definition: Matrix.h:1761
bool Inverse_UpdateIncrement(const idVecX &v, const idVecX &w)
Definition: Matrix.cpp:3787
idMat2 & operator*=(const float a)
Definition: Matrix.h:177
idMat5 Inverse(void) const
Definition: Matrix.h:1412
bool SVD_Factor(idVecX &w, idMatX &V)
Definition: Matrix.cpp:5057
idMatX & SwapRows(int r1, int r2)
Definition: Matrix.h:2382
void SetTempSize(int rows, int columns)
Definition: Matrix.h:2262
virtual void VPCALL MatX_TransposeMultiplyMatX(idMatX &dst, const idMatX &m1, const idMatX &m2)=0
const float * ToFloatPtr(void) const
Definition: Vector.h:719
ID_INLINE idVec2 operator*(const idVec2 &vec, const idMat2 &mat)
Definition: Matrix.h:209
bool Inverse_UpdateRankOne(const idVecX &v, const idVecX &w, float alpha)
Definition: Matrix.cpp:3709
bool Inverse_GaussJordan(void)
Definition: Matrix.cpp:3620
idMat3 Transpose(void) const
Definition: Matrix.h:677
idMat2 InverseFast(void) const
Definition: Matrix.h:303
void LDLT_MultiplyFactors(idMatX &m) const
Definition: Matrix.cpp:6212
idMatX & RemoveRow(int r)
Definition: Matrix.cpp:3001
idMat4 mat4_zero
void Set(int rows, int columns, const float *src)
Definition: Matrix.h:2018
void Identity(void)
Definition: Matrix.h:251
idMatX & operator=(const idMatX &a)
Definition: Matrix.h:2059
bool InverseFastSelf(void)
Definition: Matrix.cpp:378
GLenum GLint GLint y
Definition: glext.h:2849
GLenum GLsizei n
Definition: glext.h:3705
bool LU_Factor(int *index, float *det=NULL)
Definition: Matrix.cpp:3863
void TriDiagonal_Inverse(idMatX &inv) const
Definition: Matrix.cpp:6304
float z
Definition: Vector.h:812
idMat3 & operator-=(const idMat3 &a)
Definition: Matrix.h:536
float z
Definition: Vector.h:320
idMat2 Transpose(void) const
Definition: Matrix.h:279
const float * ToFloatPtr(void) const
Definition: Matrix.h:1434
bool HessenbergToRealSchur(idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues)
Definition: Matrix.cpp:6678
int GetDimension(void) const
Definition: Matrix.h:2907
idMat2 operator+(const idMat2 &a) const
Definition: Matrix.h:165
bool InverseSelf(void)
Definition: Matrix.cpp:333
virtual void VPCALL MatX_MultiplyMatX(idMatX &dst, const idMatX &m1, const idMatX &m2)=0
idMat3 & operator+=(const idMat3 &a)
Definition: Matrix.h:528
idMat4(void)
Definition: Matrix.h:833
idMat2 & operator+=(const idMat2 &a)
Definition: Matrix.h:195
bool operator==(const idMatX &a) const
Definition: Matrix.h:2239
idVec5 mat[5]
Definition: Matrix.h:1201
idMat6 operator*(const float a) const
Definition: Matrix.h:1567
Definition: Vector.h:316
Definition: eax4.h:1413
bool operator==(const idMat6 &a) const
Definition: Matrix.h:1683
void LDLT_UnpackFactors(idMatX &L, idMatX &D) const
Definition: Matrix.cpp:6191
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:599
bool Eigen_SolveSymmetricTriDiagonal(idVecX &eigenValues)
Definition: Matrix.cpp:6520
const char * ToString(int precision=2) const
Definition: Matrix.cpp:1738
Definition: eax4.h:1412
int GetDimension(void) const
Definition: Matrix.h:1430
void Update_RankOne(const idVecX &v, const idVecX &w, float alpha)
Definition: Matrix.cpp:3450
bool IsPositiveDefinite(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3227
float Determinant(void) const
Definition: Matrix.cpp:665
const idVec4 & operator[](int index) const
Definition: Matrix.h:877
void ClearUpperTriangle(void)
Definition: Matrix.h:2414
ID_INLINE idVec2 & operator*=(idVec2 &vec, const idMat2 &mat)
Definition: Matrix.h:217
GLclampf GLclampf GLclampf alpha
Definition: glext.h:2843
idMatX Transpose(void) const
Definition: Matrix.h:2562
idMat4 Transpose(void) const
Definition: Matrix.cpp:629
GLdouble s
Definition: glext.h:2935
GLuint src
Definition: glext.h:5390
const char * ToString(int precision=2) const
Definition: Matrix.cpp:1045
void Update_RowColumnSymmetric(const idVecX &v, int r)
Definition: Matrix.cpp:3528
void MultiplySub(idVecX &dst, const idVecX &vec) const
Definition: Matrix.h:2755
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
GLfloat v0
Definition: glext.h:3606
void SVD_Solve(idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V) const
Definition: Matrix.cpp:5185
idMat4 mat4_identity
void Identity(void)
Definition: Matrix.h:591
float x
Definition: Vector.h:318
bool IsRotated(void) const
Definition: Matrix.h:624
void Cholesky_Inverse(idMatX &inv) const
Definition: Matrix.cpp:5690
bool Compare(const idMat2 &a) const
Definition: Matrix.h:222
idMat5 & operator*=(const float a)
Definition: Matrix.h:1293
void Identity(void)
Definition: Matrix.h:2308
GLenum GLint x
Definition: glext.h:2849
idMat6 InverseFast(void) const
Definition: Matrix.h:1748
int i
Definition: process.py:33
idMat2 & TransposeSelf(void)
Definition: Matrix.h:284
const float * ToFloatPtr(void) const
Definition: Vector.h:1410
GLintptr offset
Definition: glext.h:3113
void Cholesky_MultiplyFactors(idMatX &m) const
Definition: Matrix.cpp:5719
void LU_MultiplyFactors(idMatX &m, const int *index) const
Definition: Matrix.cpp:4396
bool LU_UpdateIncrement(const idVecX &v, const idVecX &w, int *index)
Definition: Matrix.cpp:4170
idMat3 InverseFast(void) const
Definition: Matrix.h:708
bool operator==(const idMat5 &a) const
Definition: Matrix.h:1366
virtual void VPCALL MatX_TransposeMultiplyVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
bool IsSymmetricPositiveSemiDefinite(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3366
idMatX InverseFast(void) const
Definition: Matrix.h:2618
virtual void VPCALL Zero16(float *dst, const int count)=0
const idVec2 & operator[](int index) const
Definition: Matrix.h:130
void Update_Increment(const idVecX &v, const idVecX &w)
Definition: Matrix.cpp:3557
#define MATRIX_EPSILON
Definition: Matrix.h:41
idMatX & RemoveRowColumn(int r)
Definition: Matrix.cpp:3040
bool LDLT_Factor(void)
Definition: Matrix.cpp:5750
idMat2 mat2_identity
idMat4 & TransposeSelf(void)
Definition: Matrix.cpp:646
bool LDLT_UpdateIncrement(const idVecX &v)
Definition: Matrix.cpp:6041
void MultiplyAdd(idVecX &dst, const idVecX &vec) const
Definition: Matrix.h:2733
list l
Definition: prepare.py:17
idVec3 ToAngularVelocity(void) const
Definition: Matrix.cpp:309
bool InverseFastSelf(void)
Definition: Matrix.cpp:1301
void Zero(void)
Definition: Vector.h:119
idMat2 operator-() const
Definition: Matrix.h:140
static float temp[MATX_MAX_TEMP+4]
Definition: Matrix.h:1975
idMat2 operator*(const float a) const
Definition: Matrix.h:159
idMat2 Inverse(void) const
Definition: Matrix.h:294
void Zero(void)
Definition: Matrix.h:246
float Determinant(void) const
Definition: Matrix.h:275
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:255
idMat5 & operator+=(const idMat5 &a)
Definition: Matrix.h:1307
void TransposeMultiplySub(idVecX &dst, const idVecX &vec) const
Definition: Matrix.h:2821
idMatX & RemoveColumn(int r)
Definition: Matrix.cpp:3020
bool LU_UpdateRankOne(const idVecX &v, const idVecX &w, float alpha, int *index)
Definition: Matrix.cpp:3947
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1397
bool LDLT_UpdateRankOne(const idVecX &v, float alpha, int offset=0)
Definition: Matrix.cpp:5795
bool InverseSelf(void)
Definition: Matrix.cpp:47
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1714
idMat5(void)
Definition: Matrix.h:1208
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
idVecX Multiply(const idVecX &vec) const
Definition: Matrix.h:2655
GLuint dst
Definition: glext.h:5285
idMat3 InertiaTranslate(const float mass, const idVec3 &centerOfMass, const idVec3 &translation) const
Definition: Matrix.cpp:537
int GetNumColumns(void) const
Definition: Matrix.h:1822
idMat3 SubMat3(int n) const
Definition: Matrix.h:1725
Definition: Vector.h:52
void ClearLowerTriangle(void)
Definition: Matrix.h:2421
bool FixDenormals(void)
Definition: Matrix.h:645
idMat5 operator*(const float a) const
Definition: Matrix.h:1257
void Eigen_SortDecreasing(idVecX &eigenValues)
Definition: Matrix.cpp:7113
idMat6 Transpose(void) const
Definition: Matrix.cpp:1757
void TriDiagonal_ClearTriangles(void)
Definition: Matrix.cpp:6247
void Update_Decrement(int r)
Definition: Matrix.cpp:3609
const float * operator[](int index) const
Definition: Matrix.h:2049
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1703
Definition: Vector.h:808
bool IsOrthonormal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3104
void LDLT_Solve(idVecX &x, const idVecX &b) const
Definition: Matrix.cpp:6124
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:2480
virtual void VPCALL AddAssign16(float *dst, const float *src, const int count)=0
virtual void VPCALL MatX_MultiplySubVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
void LU_UnpackFactors(idMatX &L, idMatX &U) const
Definition: Matrix.cpp:4373
float RandomFloat(void)
Definition: Random.h:82
#define H(x, y, z)
Definition: md5.c:105
bool operator!=(const idMat2 &a) const
Definition: Matrix.h:242
const idVec3 & operator[](int index) const
Definition: Matrix.h:434
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:612
void HouseholderReduction(idVecX &diag, idVecX &subd)
Definition: Matrix.cpp:6337
idMatX & SwapColumns(int r1, int r2)
Definition: Matrix.h:2393
void LDLT_Inverse(idMatX &inv) const
Definition: Matrix.cpp:6162
const idVec6 & SubVec6(int row) const
Definition: Matrix.h:2911
virtual void VPCALL MatX_MultiplyVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
idMat4 TransposeMultiply(const idMat4 &b) const
static float Fabs(float f)
Definition: Math.h:779
bool operator==(const idMat2 &a) const
Definition: Matrix.h:238
#define NULL
Definition: Lib.h:88
idMat5 Transpose(void) const
Definition: Matrix.cpp:1064
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1072
bool LDLT_UpdateDecrement(const idVecX &v, int r)
Definition: Matrix.cpp:6087
bool IsSymmetricPositiveDefinite(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3277
~idMatX(void)
Definition: Matrix.h:1999
idMat6 Inverse(void) const
Definition: Matrix.h:1739
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:595
const float * ToFloatPtr(void) const
Definition: Vector.h:1910
float y
Definition: Vector.h:319
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
void SVD_BiDiag(idVecX &w, idVecX &rv1, float &anorm)
Definition: Matrix.cpp:4893
virtual void VPCALL MulAssign16(float *dst, const float constant, const int count)=0
virtual void VPCALL Mul16(float *dst, const float *src1, const float constant, const int count)=0
void * Mem_Alloc16(const int size)
Definition: Heap.cpp:1107
bool QR_UpdateDecrement(idMatX &R, const idVecX &v, const idVecX &w, int r)
Definition: Matrix.cpp:4659
const char * ToString(int precision=2) const
Definition: Matrix.cpp:3439
Definition: eax4.h:1413
int GetNumRows(void) const
Definition: Matrix.h:1821
void TransposeMultiplyAdd(idVecX &dst, const idVecX &vec) const
Definition: Matrix.h:2799
float w
Definition: Vector.h:813
float x
Definition: Vector.h:54
idMat4 operator*(const float a) const
Definition: Matrix.h:887
bool IsZero(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:2455
void Identity(void)
Definition: Matrix.h:1695
bool operator==(const idMat3 &a) const
Definition: Matrix.h:579
void Random(int seed, float l=0.0f, float u=1.0f)
Definition: Matrix.h:2333
int alloced
Definition: Matrix.h:1972
void SVD_MultiplyFactors(idMatX &m, const idVecX &w, const idMatX &V) const
Definition: Matrix.cpp:5260
idMat3 mat3_zero
void Zero(void)
Definition: Matrix.h:2291
friend idMat3 SkewSymmetric(idVec3 const &src)
Definition: Matrix.h:741
const char * ToString(int precision=2) const
Definition: Matrix.cpp:2927
bool InverseFastSelf(void)
Definition: Matrix.cpp:775
bool Compare(const idMat4 &a) const
Definition: Matrix.h:1013
bool LU_UpdateRowColumn(const idVecX &v, const idVecX &w, int r, int *index)
Definition: Matrix.cpp:4022
bool Inverse_UpdateDecrement(const idVecX &v, const idVecX &w, int r)
Definition: Matrix.cpp:3812
void Update_IncrementSymmetric(const idVecX &v)
Definition: Matrix.cpp:3586
bool Compare(const idMat6 &a) const
Definition: Matrix.h:1655
float * mat
Definition: Matrix.h:1973
idMat6 & operator+=(const idMat6 &a)
Definition: Matrix.h:1622
idMatX & SwapRowsColumns(int r1, int r2)
Definition: Matrix.h:2407
virtual void VPCALL Add16(float *dst, const float *src1, const float *src2, const int count)=0
idMatX & operator*=(const float a)
Definition: Matrix.h:2148
const idVec6 & operator[](int index) const
Definition: Matrix.h:1532
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
bool operator!=(const idMat6 &a) const
Definition: Matrix.h:1687
bool TriDiagonal_Solve(idVecX &x, const idVecX &b) const
Definition: Matrix.cpp:6266
bool operator!=(const idMat5 &a) const
Definition: Matrix.h:1370
virtual void VPCALL Copy16(float *dst, const float *src, const int count)=0
bool Inverse_UpdateRowColumn(const idVecX &v, const idVecX &w, int r)
Definition: Matrix.cpp:3753
bool FixDegenerateNormal(void)
Definition: Vector.h:535
idMat3 & OrthoNormalizeSelf(void)
Definition: Matrix.h:668
idMatX(void)
Definition: Matrix.h:1994
bool IsDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:263
bool IsPositiveSemiDefinite(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3301
GLsizei GLboolean transpose
Definition: glext.h:3622
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
const char * ToString(int precision=2) const
Definition: Matrix.cpp:128
virtual void VPCALL MatX_TransposeMultiplySubVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
idMat3(void)
Definition: Matrix.h:415
float Determinant(void) const
Definition: Matrix.h:2539
GLfloat GLfloat v1
Definition: glext.h:3607
idMat3 OrthoNormalize(void) const
Definition: Matrix.h:656
void ProjectVector(const idVec3 &src, idVec3 &dst) const
Definition: Matrix.h:628
idVec3 mat[3]
Definition: Matrix.h:408
void Zero(void)
Definition: Matrix.h:587
bool Cholesky_UpdateDecrement(const idVecX &v, int r)
Definition: Matrix.cpp:5620
float Trace(void) const
Definition: Matrix.h:1408
const float * ToFloatPtr(void) const
Definition: Vector.h:1143
GLubyte GLubyte b
Definition: glext.h:4662
idMat3 mat3_identity
Definition: Quat.h:48
idMat2(void)
Definition: Matrix.h:113
idMat6 mat6_zero
bool InverseSelfGeneric(void)
Definition: Matrix.cpp:7159
const idVecX SubVecX(int row) const
Definition: Matrix.h:2921
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1386
#define MATX_CLEAREND()
Definition: Matrix.h:1782
void QR_MultiplyFactors(idMatX &m, const idVecX &c, const idVecX &d) const
Definition: Matrix.cpp:4830
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1382
bool InverseSelf(void)
Definition: Matrix.cpp:1142
int GetDimension(void) const
Definition: Matrix.h:1757
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:3609
idMatX operator*(const float a) const
Definition: Matrix.h:2070
bool Cholesky_Factor(void)
Definition: Matrix.cpp:5294
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
bool IsPMatrix(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3147
int GetDimension(void) const
Definition: Matrix.h:1133
Definition: Matrix.h:333
Definition: eax4.h:1412
void SetSize(int rows, int columns)
Definition: Matrix.h:2247
bool Cholesky_UpdateRankOne(const idVecX &v, float alpha, int offset=0)
Definition: Matrix.cpp:5337
void Update_RankOneSymmetric(const idVecX &v, float alpha)
Definition: Matrix.cpp:3472
virtual void VPCALL MatX_MultiplyAddVecX(idVecX &dst, const idMatX &mat, const idVecX &vec)=0
GLenum GLenum GLvoid * row
Definition: glext.h:2866
idMat3 & InertiaRotateSelf(const idMat3 &rotation)
Definition: Matrix.cpp:599
idMat6 mat6_identity
#define MATX_MAX_TEMP
Definition: Matrix.h:1780
int numColumns
Definition: Matrix.h:1971
idMat3 InertiaRotate(const idMat3 &rotation) const
Definition: Matrix.cpp:589
tuple f
Definition: idal.py:89
Definition: eax4.h:1413
const float * ToFloatPtr(void) const
Definition: Matrix.h:1137
idMat3 & operator*=(const float a)
Definition: Matrix.h:500
int numRows
Definition: Matrix.h:1970
void SVD_InitialWV(idVecX &w, idMatX &V, idVecX &rv1)
Definition: Matrix.cpp:4983
void SquareSubMatrix(const idMatX &m, int size)
Definition: Matrix.h:2428
idMat4 InverseFast(void) const
Definition: Matrix.h:1116
bool InverseSelf(void)
Definition: Matrix.cpp:1869
idQuat ToQuat(void) const
Definition: Matrix.cpp:182
bool IsSymmetric(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:259
const float * ToFloatPtr(void) const
Definition: Vector.h:301
idMat5 mat5_zero
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:2467
void LU_Solve(idVecX &x, const idVecX &b, const int *index) const
Definition: Matrix.cpp:4308
int GetDimension(void) const
Definition: Matrix.h:312
idMat2 & operator-=(const idMat2 &a)
Definition: Matrix.h:202
GLsizeiptr size
Definition: glext.h:3112
void Zero(void)
Definition: Matrix.h:1049
void SetData(int rows, int columns, float *data)
Definition: Matrix.h:2278
const idVec5 & operator[](int index) const
Definition: Matrix.h:1223
void Mem_Free16(void *ptr)
Definition: Heap.cpp:1128
void QR_Solve(idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d) const
Definition: Matrix.cpp:4694
bool QR_UpdateIncrement(idMatX &R, const idVecX &v, const idVecX &w)
Definition: Matrix.cpp:4631
int GetDimension(void) const
Definition: Matrix.h:745
void HessenbergReduction(idMatX &H)
Definition: Matrix.cpp:6569
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1057
bool QL(idVecX &diag, idVecX &subd)
Definition: Matrix.cpp:6442
void ProjectVector(const idVec4 &src, idVec4 &dst) const
Definition: Matrix.h:1092
idMat6 operator+(const idMat6 &a) const
Definition: Matrix.h:1587
idMatX Inverse(void) const
Definition: Matrix.h:2582
void SetData(int length, float *data)
Definition: Vector.h:1756
bool operator!=(const idMat4 &a) const
Definition: Matrix.h:1045
bool UpperTriangularInverse(void)
Definition: Matrix.cpp:3412
idRotation ToRotation(void) const
Definition: Matrix.cpp:246
float Trace(void) const
Definition: Matrix.h:271
bool InverseFastSelf(void)
Definition: Matrix.cpp:74
float Trace(void) const
Definition: Matrix.h:2527
idMat5 mat5_identity
static void Test(void)
Definition: Matrix.cpp:7193
void SVD_Inverse(idMatX &inv, const idVecX &w, const idMatX &V) const
Definition: Matrix.cpp:5223
bool QR_Factor(idVecX &c, idVecX &d)
Definition: Matrix.cpp:4435
idMat5 & TransposeSelf(void)
Definition: Matrix.cpp:1081
idAngles ToAngles(void) const
Definition: Matrix.cpp:147
void QR_Inverse(idMatX &inv, const idVecX &c, const idVecX &d) const
Definition: Matrix.cpp:4764
float Trace(void) const
Definition: Matrix.h:1735
idMat3 operator*(const float a) const
Definition: Matrix.h:479
void Zero(void)
Definition: Matrix.h:1374
void UnprojectVector(const idVec3 &src, idVec3 &dst) const
Definition: Matrix.h:634
idMat4 operator-(const idMat4 &a) const
Definition: Matrix.h:954
idMat6 & TransposeSelf(void)
Definition: Matrix.cpp:1774
idMat6 & operator-=(const idMat6 &a)
Definition: Matrix.h:1632
ID_INLINE idMat3 SkewSymmetric(idVec3 const &src)
Definition: Matrix.h:741
bool InverseSelf(void)
Definition: Matrix.h:2592
GLint j
Definition: qgl.h:264
bool Eigen_Solve(idVecX &realEigenValues, idVecX &imaginaryEigenValues)
Definition: Matrix.cpp:7066
idMatX operator+(const idMatX &a) const
Definition: Matrix.h:2114
idVec4 mat[4]
Definition: Matrix.h:826
bool InverseFastSelf(void)
Definition: Matrix.cpp:2186
static float * tempPtr
Definition: Matrix.h:1976
bool LowerTriangularInverse(void)
Definition: Matrix.cpp:3383
float Determinant(void) const
Definition: Matrix.cpp:1100
bool LDLT_UpdateRowColumn(const idVecX &v, int r)
Definition: Matrix.cpp:5847
idMat5 & operator-=(const idMat5 &a)
Definition: Matrix.h:1316
bool IsOrthogonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3072
idVec2 mat[2]
Definition: Matrix.h:106
#define max(x, y)
Definition: os.h:70
Definition: Matrix.h:55
idMat3 & InertiaTranslateSelf(const float mass, const idVec3 &centerOfMass, const idVec3 &translation)
Definition: Matrix.cpp:562
void Eigen_SortIncreasing(idVecX &eigenValues)
Definition: Matrix.cpp:7088
const float * ToFloatPtr(void) const
Definition: Matrix.h:749
virtual void VPCALL Negate16(float *dst, const int count)=0
idMat6 operator-(const idMat6 &a) const
Definition: Matrix.h:1597
void Identity(void)
Definition: Matrix.h:1378
void Inverse_Solve(idVecX &x, const idVecX &b) const
Definition: Matrix.cpp:3846
void QR_UnpackFactors(idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d) const
Definition: Matrix.cpp:4793
void ChangeSize(int rows, int columns, bool makeZero=false)
Definition: Matrix.cpp:2948
float x
Definition: Vector.h:810
float Determinant(void) const
Definition: Matrix.cpp:1793
idMat3 Inverse(void) const
Definition: Matrix.h:699
idMat3 TransposeMultiply(const idMat3 &b) const
Definition: Matrix.h:717
Definition: Matrix.h:764
GLdouble GLdouble z
Definition: glext.h:3067
idMatX & operator-=(const idMatX &a)
Definition: Matrix.h:2183
void Negate(void)
Definition: Matrix.h:2358
const float * ToFloatPtr(void) const
Definition: Matrix.h:2935
idMat4 ToMat4(void) const
Definition: Matrix.h:1125
idMat3 operator+(const idMat3 &a) const
Definition: Matrix.h:486
idMat5 InverseFast(void) const
Definition: Matrix.h:1421
idMat5 operator+(const idMat5 &a) const
Definition: Matrix.h:1275
idMat4 & operator*=(const float a)
Definition: Matrix.h:962
bool IsZMatrix(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.cpp:3202
bool IsIdentity(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:1699
bool Compare(const idMat5 &a) const
Definition: Matrix.h:1338
bool FixDegeneracies(void)
Definition: Matrix.h:638
bool IsTriDiagonal(const float epsilon=MATRIX_EPSILON) const
Definition: Matrix.h:2493
void SetTempSize(int size)
Definition: Vector.h:1743
idMat6 & operator*=(const float a)
Definition: Matrix.h:1607
void Clamp(float min, float max)
Definition: Matrix.h:2370
float Pythag(float a, float b) const
Definition: Matrix.cpp:4870
void Diag(const idVecX &v)
Definition: Matrix.h:2326
idMat6(void)
Definition: Matrix.h:1507
bool LU_UpdateDecrement(const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index)
Definition: Matrix.cpp:4219
idMat4 & operator+=(const idMat4 &a)
Definition: Matrix.h:975
bool FixDenormals(void)
Definition: Vector.h:602
#define MATRIX_INVERSE_EPSILON
Definition: Matrix.h:40
bool Compare(const idMatX &a) const
Definition: Matrix.h:2211
float Determinant(void) const
Definition: Matrix.cpp:319
idMat3 & TransposeSelf(void)
Definition: Matrix.h:683
idSIMDProcessor * SIMDProcessor
Definition: Simd.cpp:43
void Identity(void)
Definition: Matrix.h:1053