2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory
4
// Contact: pgregory@aqsis.com
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public
8
// License as published by the Free Software Foundation; either
9
// version 2 of the License, or (at your option) any later version.
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
// General Public License for more details.
16
// You should have received a copy of the GNU General Public
17
// License along with this library; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
\brief Implements the CqMatrix 4D homogenous matrix class.
23
\author Paul C. Gregory (pgregory@aqsis.com)
29
START_NAMESPACE( Aqsis )
32
//---------------------------------------------------------------------
33
/** Identity matrix constructor
42
//---------------------------------------------------------------------
43
/** Scale matrix constructor
44
* \param xs Float scale in x.
45
* \param ys Float scale in y.
46
* \param zs Float scale in z.
49
CqMatrix::CqMatrix( const TqFloat xs, const TqFloat ys, const TqFloat zs )
53
if ( xs == 1.0f && ys == 1.0f && zs == 1.0f )
57
m_aaElement[ 0 ][ 0 ] = xs;
58
m_aaElement[ 1 ][ 1 ] = ys;
59
m_aaElement[ 2 ][ 2 ] = zs;
60
m_aaElement[ 3 ][ 3 ] = 1.0;
62
m_fIdentity = TqFalse;
67
//---------------------------------------------------------------------
68
/** Translate constructor. Constructs a translation matrix translating by a given vector.
69
* \param Trans The vector by which to translate.
72
CqMatrix::CqMatrix( const CqVector3D& Trans )
76
if ( Trans.x() == 0.0f && Trans.y() == 0.0f && Trans.z() == 0.0f )
80
m_fIdentity = TqFalse;
82
m_aaElement[ 3 ][ 0 ] = Trans.x();
83
m_aaElement[ 3 ][ 1 ] = Trans.y();
84
m_aaElement[ 3 ][ 2 ] = Trans.z();
89
//---------------------------------------------------------------------
90
/** Rotate matrix constructor
91
* \param Angle The angle to rotate by.
92
* \param Axis The axis about which to rotate.
95
CqMatrix::CqMatrix( const TqFloat Angle, const CqVector3D Axis )
99
if ( Angle != 0.0f && Axis.Magnitude() != 0.0f )
100
Rotate( Angle, Axis );
104
//---------------------------------------------------------------------
105
/** Skew matrix constructor
107
* \param dx1, dy1, dz1
108
* \param dx2, dy2, dz2
110
* For now base this on what Larry Gritz posted a while back.
111
* There are some more optimizations that can be done.
113
#define PI 3.14159265359f
114
CqMatrix::CqMatrix( const TqFloat angle,
115
const TqFloat dx1, const TqFloat dy1, const TqFloat dz1,
116
const TqFloat dx2, const TqFloat dy2, const TqFloat dz2 )
118
// Normalize the two vectors, and construct a third perpendicular
119
CqVector3D d1( dx1, dy1, dz1 ), d2( dx2, dy2, dz2 );
123
// Assumes angle already changed to radians.
125
TqFloat d1d2dot = d1 * d2;
126
TqFloat axisangle = static_cast<TqFloat>(acos( d1d2dot ));
127
if ( angle >= axisangle || angle <= ( axisangle - PI ) )
129
// Skewed past the axes -- issue error, then just use identity matrix.
130
// No access to CqBasicError from here, so this will have to be down
131
// in RiSkew. That would duplicate the above math calculations
132
// unless they were passed to this constructor which would be odd
134
// CqBasicError(0,Severity_Normal,"RiSkew angle invalid.");
139
CqVector3D right = d1 % d2;
142
// d1ortho will be perpendicular to <d2> and <right> and can be
143
// used to construct a rotation matrix
144
CqVector3D d1ortho = d2 % right;
147
// 1) Rotate to a space where the skew operation is in a major plane.
148
// 2) Bend the y axis towards the z axis causing a skew.
150
CqMatrix Rot( right[ 0 ], d1ortho[ 0 ], d2[ 0 ], 0,
151
right[ 1 ], d1ortho[ 1 ], d2[ 1 ], 0,
152
right[ 2 ], d1ortho[ 2 ], d2[ 2 ], 0,
154
TqFloat par = d1d2dot; // Amount of d1 parallel to d2
155
TqFloat perp = static_cast<TqFloat>(sqrt( 1.0 - par * par )); // Amount perpendicular
156
TqFloat s = static_cast<TqFloat>(tan( angle + acos( perp ) ) * perp - par);
157
CqMatrix Skw( 1, 0, 0, 0,
161
// Note the Inverse of a rotation matrix is its Transpose.
162
*this = Rot.Transpose() * Skw * Rot;
166
//---------------------------------------------------------------------
167
/** Copy constructor.
170
CqMatrix::CqMatrix( const CqMatrix &From )
175
//---------------------------------------------------------------------
176
/** Constructor from a 2D float array.
177
* \param From 2D float array to copy data from.
180
CqMatrix::CqMatrix( TqFloat From[ 4 ][ 4 ] )
186
//---------------------------------------------------------------------
187
/** Constructor from a float array.
188
* \param From 1D float array to copy data from.
191
CqMatrix::CqMatrix( TqFloat From[ 16 ] )
196
//---------------------------------------------------------------------
197
/** Turn the matrix into an identity.
200
void CqMatrix::Identity()
202
m_aaElement[ 0 ][ 1 ] =
203
m_aaElement[ 0 ][ 2 ] =
204
m_aaElement[ 0 ][ 3 ] =
205
m_aaElement[ 1 ][ 0 ] =
206
m_aaElement[ 1 ][ 2 ] =
207
m_aaElement[ 1 ][ 3 ] =
208
m_aaElement[ 2 ][ 0 ] =
209
m_aaElement[ 2 ][ 1 ] =
210
m_aaElement[ 2 ][ 3 ] =
211
m_aaElement[ 3 ][ 0 ] =
212
m_aaElement[ 3 ][ 1 ] =
213
m_aaElement[ 3 ][ 2 ] = 0.0f;
215
m_aaElement[ 0 ][ 0 ] =
216
m_aaElement[ 1 ][ 1 ] =
217
m_aaElement[ 2 ][ 2 ] =
218
m_aaElement[ 3 ][ 3 ] = 1.0f;
220
m_fIdentity = TqTrue;
224
//---------------------------------------------------------------------
225
/** Scale matrix uniformly in all three axes.
226
* \param S The amount to scale by.
229
void CqMatrix::Scale( const TqFloat S )
235
//---------------------------------------------------------------------
236
/** Scale matrix in three axes.
237
* \param xs X scale factor.
238
* \param ys Y scale factor.
239
* \param zs Z scale factor.
242
void CqMatrix::Scale( const TqFloat xs, const TqFloat ys, const TqFloat zs )
244
CqMatrix Scale( xs, ys, zs );
246
this->PreMultiply( Scale );
250
//---------------------------------------------------------------------
251
/** Rotates this matrix by a given rotation angle about a given axis through the origin.
252
* \param Angle The angle to rotate by.
253
* \param Axis The axis about which to rotate.
256
void CqMatrix::Rotate( const TqFloat Angle, const CqVector3D Axis )
262
CqVector3D RotAxis = Axis;
263
R.m_fIdentity = TqFalse;
267
TqFloat s = static_cast<TqFloat>( sin( Angle ) );
268
TqFloat c = static_cast<TqFloat>( cos( Angle ) );
269
TqFloat t = 1.0f - c;
271
R.m_aaElement[ 0 ][ 0 ] = t * RotAxis.x() * RotAxis.x() + c;
272
R.m_aaElement[ 1 ][ 1 ] = t * RotAxis.y() * RotAxis.y() + c;
273
R.m_aaElement[ 2 ][ 2 ] = t * RotAxis.z() * RotAxis.z() + c;
275
TqFloat txy = t * RotAxis.x() * RotAxis.y();
276
TqFloat sz = s * RotAxis.z();
278
R.m_aaElement[ 0 ][ 1 ] = txy + sz;
279
R.m_aaElement[ 1 ][ 0 ] = txy - sz;
281
TqFloat txz = t * RotAxis.x() * RotAxis.z();
282
TqFloat sy = s * RotAxis.y();
284
R.m_aaElement[ 0 ][ 2 ] = txz - sy;
285
R.m_aaElement[ 2 ][ 0 ] = txz + sy;
287
TqFloat tyz = t * RotAxis.y() * RotAxis.z();
288
TqFloat sx = s * RotAxis.x();
290
R.m_aaElement[ 1 ][ 2 ] = tyz + sx;
291
R.m_aaElement[ 2 ][ 1 ] = tyz - sx;
293
this->PreMultiply( R );
298
//---------------------------------------------------------------------
299
/** Translates this matrix by a given vector.
300
* \param Trans The vector by which to translate.
303
void CqMatrix::Translate( const CqVector3D& Trans )
305
CqMatrix matTrans( Trans );
306
this->PreMultiply( matTrans );
311
//---------------------------------------------------------------------
312
/** Translates this matrix by three axis distances.
313
* \param xt X distance to translate.
314
* \param yt Y distance to translate.
315
* \param zt Z distance to translate.
318
void CqMatrix::Translate( const TqFloat xt, const TqFloat yt, const TqFloat zt )
320
if ( xt != 0.0f || yt != 0.0f || zt != 0.0f )
321
Translate( CqVector3D( xt, yt, zt ) );
325
//---------------------------------------------------------------------
326
/** Shears this matrix's X axis according to two shear factors, yh and zh
327
* \param yh Y shear factor.
328
* \param zh Z shear factor.
331
void CqMatrix::ShearX( const TqFloat yh, const TqFloat zh )
334
Shear.m_fIdentity = TqFalse;
336
Shear.m_aaElement[ 0 ][ 1 ] = yh;
337
Shear.m_aaElement[ 0 ][ 2 ] = zh;
339
this->PreMultiply( Shear );
343
//---------------------------------------------------------------------
344
/** Shears this matrix's Y axis according to two shear factors, xh and zh
345
* \param xh X shear factor.
346
* \param zh Z shear factor.
349
void CqMatrix::ShearY( const TqFloat xh, const TqFloat zh )
352
Shear.m_fIdentity = TqFalse;
354
Shear.m_aaElement[ 1 ][ 0 ] = xh;
355
Shear.m_aaElement[ 1 ][ 2 ] = zh;
357
this->PreMultiply( Shear );
360
//---------------------------------------------------------------------
361
/** Shears this matrix's Z axis according to two shear factors, xh and yh
362
* \param xh X shear factor.
363
* \param yh Y shear factor.
366
void CqMatrix::ShearZ( const TqFloat xh, const TqFloat yh )
369
Shear.m_fIdentity = TqFalse;
371
Shear.m_aaElement[ 2 ][ 0 ] = xh;
372
Shear.m_aaElement[ 2 ][ 1 ] = yh;
374
this->PreMultiply( Shear );
377
//---------------------------------------------------------------------
379
* \param angle The angle by which to skew the transformation.
380
* \param dx1 Along with the other float values, specifies the two vectors which control the direction of skew.
381
* \param dy1 Along with the other float values, specifies the two vectors which control the direction of skew.
382
* \param dz1 Along with the other float values, specifies the two vectors which control the direction of skew.
383
* \param dx2 Along with the other float values, specifies the two vectors which control the direction of skew.
384
* \param dy2 Along with the other float values, specifies the two vectors which control the direction of skew.
385
* \param dz2 Along with the other float values, specifies the two vectors which control the direction of skew.
388
void CqMatrix::Skew( const TqFloat angle,
389
const TqFloat dx1, const TqFloat dy1, const TqFloat dz1,
390
const TqFloat dx2, const TqFloat dy2, const TqFloat dz2 )
392
CqMatrix Skew( angle, dx1, dy1, dz1, dx2, dy2, dz2 );
394
this->PreMultiply( Skew );
397
//---------------------------------------------------------------------
398
/** Normalise the matrix, returning the homogenous part of the matrix to 1.
401
void CqMatrix::Normalise()
403
for ( TqInt i = 0; i < 4; i++ )
405
for ( TqInt j = 0; j < 4; j++ )
407
m_aaElement[ i ][ j ] /= m_aaElement[ 3 ][ 3 ];
413
//---------------------------------------------------------------------
414
/** Multiply two matrices together.
415
* \param From The matrix to multiply with this matrix.
416
* \return The resultant multiplied matrix.
419
CqMatrix CqMatrix::operator*( const CqMatrix &From ) const
421
CqMatrix Temp( *this );
427
//---------------------------------------------------------------------
428
/** Multiply this matrix by specified matrix. This now takes into account the types of matrices, in an attempt to speed it up.
429
* \param From The matrix to multiply with this matrix.
432
CqMatrix &CqMatrix::operator*=( const CqMatrix &From )
435
return ( *this = From );
436
else if ( From.m_fIdentity )
441
m_aaElement[ 0 ][ 0 ] = From.m_aaElement[ 0 ][ 0 ] * A.m_aaElement[ 0 ][ 0 ]
442
+ From.m_aaElement[ 0 ][ 1 ] * A.m_aaElement[ 1 ][ 0 ]
443
+ From.m_aaElement[ 0 ][ 2 ] * A.m_aaElement[ 2 ][ 0 ]
444
+ From.m_aaElement[ 0 ][ 3 ] * A.m_aaElement[ 3 ][ 0 ];
445
m_aaElement[ 0 ][ 1 ] = From.m_aaElement[ 0 ][ 0 ] * A.m_aaElement[ 0 ][ 1 ]
446
+ From.m_aaElement[ 0 ][ 1 ] * A.m_aaElement[ 1 ][ 1 ]
447
+ From.m_aaElement[ 0 ][ 2 ] * A.m_aaElement[ 2 ][ 1 ]
448
+ From.m_aaElement[ 0 ][ 3 ] * A.m_aaElement[ 3 ][ 1 ];
449
m_aaElement[ 0 ][ 2 ] = From.m_aaElement[ 0 ][ 0 ] * A.m_aaElement[ 0 ][ 2 ]
450
+ From.m_aaElement[ 0 ][ 1 ] * A.m_aaElement[ 1 ][ 2 ]
451
+ From.m_aaElement[ 0 ][ 2 ] * A.m_aaElement[ 2 ][ 2 ]
452
+ From.m_aaElement[ 0 ][ 3 ] * A.m_aaElement[ 3 ][ 2 ];
453
m_aaElement[ 0 ][ 3 ] = From.m_aaElement[ 0 ][ 0 ] * A.m_aaElement[ 0 ][ 3 ]
454
+ From.m_aaElement[ 0 ][ 1 ] * A.m_aaElement[ 1 ][ 3 ]
455
+ From.m_aaElement[ 0 ][ 2 ] * A.m_aaElement[ 2 ][ 3 ]
456
+ From.m_aaElement[ 0 ][ 3 ] * A.m_aaElement[ 3 ][ 3 ];
458
m_aaElement[ 1 ][ 0 ] = From.m_aaElement[ 1 ][ 0 ] * A.m_aaElement[ 0 ][ 0 ]
459
+ From.m_aaElement[ 1 ][ 1 ] * A.m_aaElement[ 1 ][ 0 ]
460
+ From.m_aaElement[ 1 ][ 2 ] * A.m_aaElement[ 2 ][ 0 ]
461
+ From.m_aaElement[ 1 ][ 3 ] * A.m_aaElement[ 3 ][ 0 ];
462
m_aaElement[ 1 ][ 1 ] = From.m_aaElement[ 1 ][ 0 ] * A.m_aaElement[ 0 ][ 1 ]
463
+ From.m_aaElement[ 1 ][ 1 ] * A.m_aaElement[ 1 ][ 1 ]
464
+ From.m_aaElement[ 1 ][ 2 ] * A.m_aaElement[ 2 ][ 1 ]
465
+ From.m_aaElement[ 1 ][ 3 ] * A.m_aaElement[ 3 ][ 1 ];
466
m_aaElement[ 1 ][ 2 ] = From.m_aaElement[ 1 ][ 0 ] * A.m_aaElement[ 0 ][ 2 ]
467
+ From.m_aaElement[ 1 ][ 1 ] * A.m_aaElement[ 1 ][ 2 ]
468
+ From.m_aaElement[ 1 ][ 2 ] * A.m_aaElement[ 2 ][ 2 ]
469
+ From.m_aaElement[ 1 ][ 3 ] * A.m_aaElement[ 3 ][ 2 ];
470
m_aaElement[ 1 ][ 3 ] = From.m_aaElement[ 1 ][ 0 ] * A.m_aaElement[ 0 ][ 3 ]
471
+ From.m_aaElement[ 1 ][ 1 ] * A.m_aaElement[ 1 ][ 3 ]
472
+ From.m_aaElement[ 1 ][ 2 ] * A.m_aaElement[ 2 ][ 3 ]
473
+ From.m_aaElement[ 1 ][ 3 ] * A.m_aaElement[ 3 ][ 3 ];
475
m_aaElement[ 2 ][ 0 ] = From.m_aaElement[ 2 ][ 0 ] * A.m_aaElement[ 0 ][ 0 ]
476
+ From.m_aaElement[ 2 ][ 1 ] * A.m_aaElement[ 1 ][ 0 ]
477
+ From.m_aaElement[ 2 ][ 2 ] * A.m_aaElement[ 2 ][ 0 ]
478
+ From.m_aaElement[ 2 ][ 3 ] * A.m_aaElement[ 3 ][ 0 ];
479
m_aaElement[ 2 ][ 1 ] = From.m_aaElement[ 2 ][ 0 ] * A.m_aaElement[ 0 ][ 1 ]
480
+ From.m_aaElement[ 2 ][ 1 ] * A.m_aaElement[ 1 ][ 1 ]
481
+ From.m_aaElement[ 2 ][ 2 ] * A.m_aaElement[ 2 ][ 1 ]
482
+ From.m_aaElement[ 2 ][ 3 ] * A.m_aaElement[ 3 ][ 1 ];
483
m_aaElement[ 2 ][ 2 ] = From.m_aaElement[ 2 ][ 0 ] * A.m_aaElement[ 0 ][ 2 ]
484
+ From.m_aaElement[ 2 ][ 1 ] * A.m_aaElement[ 1 ][ 2 ]
485
+ From.m_aaElement[ 2 ][ 2 ] * A.m_aaElement[ 2 ][ 2 ]
486
+ From.m_aaElement[ 2 ][ 3 ] * A.m_aaElement[ 3 ][ 2 ];
487
m_aaElement[ 2 ][ 3 ] = From.m_aaElement[ 2 ][ 0 ] * A.m_aaElement[ 0 ][ 3 ]
488
+ From.m_aaElement[ 2 ][ 1 ] * A.m_aaElement[ 1 ][ 3 ]
489
+ From.m_aaElement[ 2 ][ 2 ] * A.m_aaElement[ 2 ][ 3 ]
490
+ From.m_aaElement[ 2 ][ 3 ] * A.m_aaElement[ 3 ][ 3 ];
492
m_aaElement[ 3 ][ 0 ] = From.m_aaElement[ 3 ][ 0 ] * A.m_aaElement[ 0 ][ 0 ]
493
+ From.m_aaElement[ 3 ][ 1 ] * A.m_aaElement[ 1 ][ 0 ]
494
+ From.m_aaElement[ 3 ][ 2 ] * A.m_aaElement[ 2 ][ 0 ]
495
+ From.m_aaElement[ 3 ][ 3 ] * A.m_aaElement[ 3 ][ 0 ];
496
m_aaElement[ 3 ][ 1 ] = From.m_aaElement[ 3 ][ 0 ] * A.m_aaElement[ 0 ][ 1 ]
497
+ From.m_aaElement[ 3 ][ 1 ] * A.m_aaElement[ 1 ][ 1 ]
498
+ From.m_aaElement[ 3 ][ 2 ] * A.m_aaElement[ 2 ][ 1 ]
499
+ From.m_aaElement[ 3 ][ 3 ] * A.m_aaElement[ 3 ][ 1 ];
500
m_aaElement[ 3 ][ 2 ] = From.m_aaElement[ 3 ][ 0 ] * A.m_aaElement[ 0 ][ 2 ]
501
+ From.m_aaElement[ 3 ][ 1 ] * A.m_aaElement[ 1 ][ 2 ]
502
+ From.m_aaElement[ 3 ][ 2 ] * A.m_aaElement[ 2 ][ 2 ]
503
+ From.m_aaElement[ 3 ][ 3 ] * A.m_aaElement[ 3 ][ 2 ];
504
m_aaElement[ 3 ][ 3 ] = From.m_aaElement[ 3 ][ 0 ] * A.m_aaElement[ 0 ][ 3 ]
505
+ From.m_aaElement[ 3 ][ 1 ] * A.m_aaElement[ 1 ][ 3 ]
506
+ From.m_aaElement[ 3 ][ 2 ] * A.m_aaElement[ 2 ][ 3 ]
507
+ From.m_aaElement[ 3 ][ 3 ] * A.m_aaElement[ 3 ][ 3 ];
509
m_fIdentity = TqFalse;
513
//---------------------------------------------------------------------
514
/** Matrix multiplication of the form a = b * a.
515
* \param From The matrix to multiply with this matrix.
518
CqMatrix& CqMatrix::PreMultiply( const CqMatrix &From )
521
return ( *this = From );
522
else if ( From.m_fIdentity )
527
m_aaElement[ 0 ][ 0 ] = A.m_aaElement[ 0 ][ 0 ] * From.m_aaElement[ 0 ][ 0 ]
528
+ A.m_aaElement[ 0 ][ 1 ] * From.m_aaElement[ 1 ][ 0 ]
529
+ A.m_aaElement[ 0 ][ 2 ] * From.m_aaElement[ 2 ][ 0 ]
530
+ A.m_aaElement[ 0 ][ 3 ] * From.m_aaElement[ 3 ][ 0 ];
531
m_aaElement[ 0 ][ 1 ] = A.m_aaElement[ 0 ][ 0 ] * From.m_aaElement[ 0 ][ 1 ]
532
+ A.m_aaElement[ 0 ][ 1 ] * From.m_aaElement[ 1 ][ 1 ]
533
+ A.m_aaElement[ 0 ][ 2 ] * From.m_aaElement[ 2 ][ 1 ]
534
+ A.m_aaElement[ 0 ][ 3 ] * From.m_aaElement[ 3 ][ 1 ];
535
m_aaElement[ 0 ][ 2 ] = A.m_aaElement[ 0 ][ 0 ] * From.m_aaElement[ 0 ][ 2 ]
536
+ A.m_aaElement[ 0 ][ 1 ] * From.m_aaElement[ 1 ][ 2 ]
537
+ A.m_aaElement[ 0 ][ 2 ] * From.m_aaElement[ 2 ][ 2 ]
538
+ A.m_aaElement[ 0 ][ 3 ] * From.m_aaElement[ 3 ][ 2 ];
539
m_aaElement[ 0 ][ 3 ] = A.m_aaElement[ 0 ][ 0 ] * From.m_aaElement[ 0 ][ 3 ]
540
+ A.m_aaElement[ 0 ][ 1 ] * From.m_aaElement[ 1 ][ 3 ]
541
+ A.m_aaElement[ 0 ][ 2 ] * From.m_aaElement[ 2 ][ 3 ]
542
+ A.m_aaElement[ 0 ][ 3 ] * From.m_aaElement[ 3 ][ 3 ];
544
m_aaElement[ 1 ][ 0 ] = A.m_aaElement[ 1 ][ 0 ] * From.m_aaElement[ 0 ][ 0 ]
545
+ A.m_aaElement[ 1 ][ 1 ] * From.m_aaElement[ 1 ][ 0 ]
546
+ A.m_aaElement[ 1 ][ 2 ] * From.m_aaElement[ 2 ][ 0 ]
547
+ A.m_aaElement[ 1 ][ 3 ] * From.m_aaElement[ 3 ][ 0 ];
548
m_aaElement[ 1 ][ 1 ] = A.m_aaElement[ 1 ][ 0 ] * From.m_aaElement[ 0 ][ 1 ]
549
+ A.m_aaElement[ 1 ][ 1 ] * From.m_aaElement[ 1 ][ 1 ]
550
+ A.m_aaElement[ 1 ][ 2 ] * From.m_aaElement[ 2 ][ 1 ]
551
+ A.m_aaElement[ 1 ][ 3 ] * From.m_aaElement[ 3 ][ 1 ];
552
m_aaElement[ 1 ][ 2 ] = A.m_aaElement[ 1 ][ 0 ] * From.m_aaElement[ 0 ][ 2 ]
553
+ A.m_aaElement[ 1 ][ 1 ] * From.m_aaElement[ 1 ][ 2 ]
554
+ A.m_aaElement[ 1 ][ 2 ] * From.m_aaElement[ 2 ][ 2 ]
555
+ A.m_aaElement[ 1 ][ 3 ] * From.m_aaElement[ 3 ][ 2 ];
556
m_aaElement[ 1 ][ 3 ] = A.m_aaElement[ 1 ][ 0 ] * From.m_aaElement[ 0 ][ 3 ]
557
+ A.m_aaElement[ 1 ][ 1 ] * From.m_aaElement[ 1 ][ 3 ]
558
+ A.m_aaElement[ 1 ][ 2 ] * From.m_aaElement[ 2 ][ 3 ]
559
+ A.m_aaElement[ 1 ][ 3 ] * From.m_aaElement[ 3 ][ 3 ];
561
m_aaElement[ 2 ][ 0 ] = A.m_aaElement[ 2 ][ 0 ] * From.m_aaElement[ 0 ][ 0 ]
562
+ A.m_aaElement[ 2 ][ 1 ] * From.m_aaElement[ 1 ][ 0 ]
563
+ A.m_aaElement[ 2 ][ 2 ] * From.m_aaElement[ 2 ][ 0 ]
564
+ A.m_aaElement[ 2 ][ 3 ] * From.m_aaElement[ 3 ][ 0 ];
565
m_aaElement[ 2 ][ 1 ] = A.m_aaElement[ 2 ][ 0 ] * From.m_aaElement[ 0 ][ 1 ]
566
+ A.m_aaElement[ 2 ][ 1 ] * From.m_aaElement[ 1 ][ 1 ]
567
+ A.m_aaElement[ 2 ][ 2 ] * From.m_aaElement[ 2 ][ 1 ]
568
+ A.m_aaElement[ 2 ][ 3 ] * From.m_aaElement[ 3 ][ 1 ];
569
m_aaElement[ 2 ][ 2 ] = A.m_aaElement[ 2 ][ 0 ] * From.m_aaElement[ 0 ][ 2 ]
570
+ A.m_aaElement[ 2 ][ 1 ] * From.m_aaElement[ 1 ][ 2 ]
571
+ A.m_aaElement[ 2 ][ 2 ] * From.m_aaElement[ 2 ][ 2 ]
572
+ A.m_aaElement[ 2 ][ 3 ] * From.m_aaElement[ 3 ][ 2 ];
573
m_aaElement[ 2 ][ 3 ] = A.m_aaElement[ 2 ][ 0 ] * From.m_aaElement[ 0 ][ 3 ]
574
+ A.m_aaElement[ 2 ][ 1 ] * From.m_aaElement[ 1 ][ 3 ]
575
+ A.m_aaElement[ 2 ][ 2 ] * From.m_aaElement[ 2 ][ 3 ]
576
+ A.m_aaElement[ 2 ][ 3 ] * From.m_aaElement[ 3 ][ 3 ];
578
m_aaElement[ 3 ][ 0 ] = A.m_aaElement[ 3 ][ 0 ] * From.m_aaElement[ 0 ][ 0 ]
579
+ A.m_aaElement[ 3 ][ 1 ] * From.m_aaElement[ 1 ][ 0 ]
580
+ A.m_aaElement[ 3 ][ 2 ] * From.m_aaElement[ 2 ][ 0 ]
581
+ A.m_aaElement[ 3 ][ 3 ] * From.m_aaElement[ 3 ][ 0 ];
582
m_aaElement[ 3 ][ 1 ] = A.m_aaElement[ 3 ][ 0 ] * From.m_aaElement[ 0 ][ 1 ]
583
+ A.m_aaElement[ 3 ][ 1 ] * From.m_aaElement[ 1 ][ 1 ]
584
+ A.m_aaElement[ 3 ][ 2 ] * From.m_aaElement[ 2 ][ 1 ]
585
+ A.m_aaElement[ 3 ][ 3 ] * From.m_aaElement[ 3 ][ 1 ];
586
m_aaElement[ 3 ][ 2 ] = A.m_aaElement[ 3 ][ 0 ] * From.m_aaElement[ 0 ][ 2 ]
587
+ A.m_aaElement[ 3 ][ 1 ] * From.m_aaElement[ 1 ][ 2 ]
588
+ A.m_aaElement[ 3 ][ 2 ] * From.m_aaElement[ 2 ][ 2 ]
589
+ A.m_aaElement[ 3 ][ 3 ] * From.m_aaElement[ 3 ][ 2 ];
590
m_aaElement[ 3 ][ 3 ] = A.m_aaElement[ 3 ][ 0 ] * From.m_aaElement[ 0 ][ 3 ]
591
+ A.m_aaElement[ 3 ][ 1 ] * From.m_aaElement[ 1 ][ 3 ]
592
+ A.m_aaElement[ 3 ][ 2 ] * From.m_aaElement[ 2 ][ 3 ]
593
+ A.m_aaElement[ 3 ][ 3 ] * From.m_aaElement[ 3 ][ 3 ];
595
m_fIdentity = TqFalse;
599
//---------------------------------------------------------------------
600
/** Premultiplies this matrix by a vector, returning v*m. This is the same as postmultiply the transpose of m by a vector: T(m)*v
601
* \param Vector The vector to multiply.
602
* \return The result of multiplying the vector by this matrix.
605
CqVector4D CqMatrix::PreMultiply( const CqVector4D &Vector ) const
612
Result.x( m_aaElement[ 0 ][ 0 ] * Vector.x()
613
+ m_aaElement[ 0 ][ 1 ] * Vector.y()
614
+ m_aaElement[ 0 ][ 2 ] * Vector.z()
615
+ m_aaElement[ 0 ][ 3 ] * Vector.h() );
617
Result.y( m_aaElement[ 1 ][ 0 ] * Vector.x()
618
+ m_aaElement[ 1 ][ 1 ] * Vector.y()
619
+ m_aaElement[ 1 ][ 2 ] * Vector.z()
620
+ m_aaElement[ 1 ][ 3 ] * Vector.h() );
622
Result.z( m_aaElement[ 2 ][ 0 ] * Vector.x()
623
+ m_aaElement[ 2 ][ 1 ] * Vector.y()
624
+ m_aaElement[ 2 ][ 2 ] * Vector.z()
625
+ m_aaElement[ 2 ][ 3 ] * Vector.h() );
627
Result.h( m_aaElement[ 3 ][ 0 ] * Vector.x()
628
+ m_aaElement[ 3 ][ 1 ] * Vector.y()
629
+ m_aaElement[ 3 ][ 2 ] * Vector.z()
630
+ m_aaElement[ 3 ][ 3 ] * Vector.h() );
637
//---------------------------------------------------------------------
638
/** Apply scale matrix uniformly in all three axes.
639
* \param S The amount by which to scale matrix.
640
* \return Result of scaling this matrix by S.
643
CqMatrix CqMatrix::operator*( const TqFloat S ) const
645
CqMatrix Temp( *this );
651
//---------------------------------------------------------------------
652
/** Apply scale matrix uniformly in all three axes to this matrix.
653
* \param S The amount by which to scale this matrix.
654
* \return The result scaling this matrix by S.
657
CqMatrix &CqMatrix::operator*=( const TqFloat S )
659
CqMatrix ScaleMatrix( S, S, S );
661
this->PreMultiply( ScaleMatrix );
667
//---------------------------------------------------------------------
668
/** Multiply a vector by this matrix.
669
* \param Vector : The vector to multiply.
670
* \return The result of multiplying the vector by this matrix.
673
CqVector4D CqMatrix::operator*( const CqVector4D &Vector ) const
680
Result.x( m_aaElement[ 0 ][ 0 ] * Vector.x()
681
+ m_aaElement[ 1 ][ 0 ] * Vector.y()
682
+ m_aaElement[ 2 ][ 0 ] * Vector.z()
683
+ m_aaElement[ 3 ][ 0 ] * Vector.h() );
685
Result.y( m_aaElement[ 0 ][ 1 ] * Vector.x()
686
+ m_aaElement[ 1 ][ 1 ] * Vector.y()
687
+ m_aaElement[ 2 ][ 1 ] * Vector.z()
688
+ m_aaElement[ 3 ][ 1 ] * Vector.h() );
690
Result.z( m_aaElement[ 0 ][ 2 ] * Vector.x()
691
+ m_aaElement[ 1 ][ 2 ] * Vector.y()
692
+ m_aaElement[ 2 ][ 2 ] * Vector.z()
693
+ m_aaElement[ 3 ][ 2 ] * Vector.h() );
695
Result.h( m_aaElement[ 0 ][ 3 ] * Vector.x()
696
+ m_aaElement[ 1 ][ 3 ] * Vector.y()
697
+ m_aaElement[ 2 ][ 3 ] * Vector.z()
698
+ m_aaElement[ 3 ][ 3 ] * Vector.h() );
704
//---------------------------------------------------------------------
705
/** Multiply a vector by this matrix.
706
* \param Vector The vector to multiply.
707
* \return The result of multiplying the vector by this matrix.
710
CqVector3D CqMatrix::operator*( const CqVector3D &Vector ) const
717
TqFloat h = ( m_aaElement[ 0 ][ 3 ] * Vector.x()
718
+ m_aaElement[ 1 ][ 3 ] * Vector.y()
719
+ m_aaElement[ 2 ][ 3 ] * Vector.z()
720
+ m_aaElement[ 3 ][ 3 ] );
722
Result.x( ( m_aaElement[ 0 ][ 0 ] * Vector.x()
723
+ m_aaElement[ 1 ][ 0 ] * Vector.y()
724
+ m_aaElement[ 2 ][ 0 ] * Vector.z()
725
+ m_aaElement[ 3 ][ 0 ] ) / h );
727
Result.y( ( m_aaElement[ 0 ][ 1 ] * Vector.x()
728
+ m_aaElement[ 1 ][ 1 ] * Vector.y()
729
+ m_aaElement[ 2 ][ 1 ] * Vector.z()
730
+ m_aaElement[ 3 ][ 1 ] ) / h );
732
Result.z( ( m_aaElement[ 0 ][ 2 ] * Vector.x()
733
+ m_aaElement[ 1 ][ 2 ] * Vector.y()
734
+ m_aaElement[ 2 ][ 2 ] * Vector.z()
735
+ m_aaElement[ 3 ][ 2 ] ) / h );
742
//---------------------------------------------------------------------
743
/** Translate matrix by 4D Vector.
744
* \param Vector The vector to translate by.
745
* \return Result of translating this matrix by the vector.
748
CqMatrix CqMatrix::operator+( const CqVector4D &Vector ) const
750
CqMatrix Temp( *this );
756
//---------------------------------------------------------------------
757
/** Translate this matrix by 4D Vector.
758
* \param Vector The vector to translate by.
759
* \return The result of translating this matrix by the specified vector.
762
CqMatrix &CqMatrix::operator+=( const CqVector4D &Vector )
764
CqMatrix Trans( Vector );
766
this->PreMultiply( Trans );
772
//---------------------------------------------------------------------
773
/** Translate matrix by 4D Vector.
774
* \param Vector The vector to translate by.
775
* \return Result of translating this matrix by the vector.
778
CqMatrix CqMatrix::operator-( const CqVector4D &Vector ) const
780
CqMatrix Temp( *this );
786
//---------------------------------------------------------------------
787
/** Translate this matrix by 4D Vector.
788
* \param Vector The vector to translate by.
791
CqMatrix &CqMatrix::operator-=( const CqVector4D &Vector )
793
CqVector4D Temp( Vector );
799
CqMatrix Trans( Temp );
801
this->PreMultiply( Trans );
807
//---------------------------------------------------------------------
808
/** Add two matrices.
809
* \param From The matrix to add.
810
* \return Result of adding From to this matrix.
813
CqMatrix CqMatrix::operator+( const CqMatrix &From ) const
815
CqMatrix Temp( *this );
821
//---------------------------------------------------------------------
822
/** Add a given matrix to this matrix.
823
* \param From The matrix to add.
826
CqMatrix &CqMatrix::operator+=( const CqMatrix &From )
828
m_aaElement[ 0 ][ 0 ] += From.m_aaElement[ 0 ][ 0 ];
829
m_aaElement[ 1 ][ 0 ] += From.m_aaElement[ 1 ][ 0 ];
830
m_aaElement[ 2 ][ 0 ] += From.m_aaElement[ 2 ][ 0 ];
831
m_aaElement[ 3 ][ 0 ] += From.m_aaElement[ 3 ][ 0 ];
832
m_aaElement[ 0 ][ 1 ] += From.m_aaElement[ 0 ][ 1 ];
833
m_aaElement[ 1 ][ 1 ] += From.m_aaElement[ 1 ][ 1 ];
834
m_aaElement[ 2 ][ 1 ] += From.m_aaElement[ 2 ][ 1 ];
835
m_aaElement[ 3 ][ 1 ] += From.m_aaElement[ 3 ][ 1 ];
836
m_aaElement[ 0 ][ 2 ] += From.m_aaElement[ 0 ][ 2 ];
837
m_aaElement[ 1 ][ 2 ] += From.m_aaElement[ 1 ][ 2 ];
838
m_aaElement[ 2 ][ 2 ] += From.m_aaElement[ 2 ][ 2 ];
839
m_aaElement[ 3 ][ 2 ] += From.m_aaElement[ 3 ][ 2 ];
840
m_aaElement[ 0 ][ 3 ] += From.m_aaElement[ 0 ][ 3 ];
841
m_aaElement[ 1 ][ 3 ] += From.m_aaElement[ 1 ][ 3 ];
842
m_aaElement[ 2 ][ 3 ] += From.m_aaElement[ 2 ][ 3 ];
843
m_aaElement[ 3 ][ 3 ] += From.m_aaElement[ 3 ][ 3 ];
845
m_fIdentity = TqFalse;
851
//---------------------------------------------------------------------
852
/** Subtract two matrices.
853
* \param From The matrix to subtract.
854
* \return Result of subtracting From from this matrix.
857
CqMatrix CqMatrix::operator-( const CqMatrix &From ) const
859
CqMatrix Temp( *this );
865
//---------------------------------------------------------------------
866
/** Subtract a given matrix from this matrix.
867
* \param From The matrix to subtract.
870
CqMatrix &CqMatrix::operator-=( const CqMatrix &From )
872
m_aaElement[ 0 ][ 0 ] -= From.m_aaElement[ 0 ][ 0 ];
873
m_aaElement[ 1 ][ 0 ] -= From.m_aaElement[ 1 ][ 0 ];
874
m_aaElement[ 2 ][ 0 ] -= From.m_aaElement[ 2 ][ 0 ];
875
m_aaElement[ 3 ][ 0 ] -= From.m_aaElement[ 3 ][ 0 ];
876
m_aaElement[ 0 ][ 1 ] -= From.m_aaElement[ 0 ][ 1 ];
877
m_aaElement[ 1 ][ 1 ] -= From.m_aaElement[ 1 ][ 1 ];
878
m_aaElement[ 2 ][ 1 ] -= From.m_aaElement[ 2 ][ 1 ];
879
m_aaElement[ 3 ][ 1 ] -= From.m_aaElement[ 3 ][ 1 ];
880
m_aaElement[ 0 ][ 2 ] -= From.m_aaElement[ 0 ][ 2 ];
881
m_aaElement[ 1 ][ 2 ] -= From.m_aaElement[ 1 ][ 2 ];
882
m_aaElement[ 2 ][ 2 ] -= From.m_aaElement[ 2 ][ 2 ];
883
m_aaElement[ 3 ][ 2 ] -= From.m_aaElement[ 3 ][ 2 ];
884
m_aaElement[ 0 ][ 3 ] -= From.m_aaElement[ 0 ][ 3 ];
885
m_aaElement[ 1 ][ 3 ] -= From.m_aaElement[ 1 ][ 3 ];
886
m_aaElement[ 2 ][ 3 ] -= From.m_aaElement[ 2 ][ 3 ];
887
m_aaElement[ 3 ][ 3 ] -= From.m_aaElement[ 3 ][ 3 ];
889
m_fIdentity = TqFalse;
895
//---------------------------------------------------------------------
897
* \param From Matrix to copy information from.
900
CqMatrix &CqMatrix::operator=( const CqMatrix &From )
902
m_aaElement[ 0 ][ 0 ] = From.m_aaElement[ 0 ][ 0 ];
903
m_aaElement[ 1 ][ 0 ] = From.m_aaElement[ 1 ][ 0 ];
904
m_aaElement[ 2 ][ 0 ] = From.m_aaElement[ 2 ][ 0 ];
905
m_aaElement[ 3 ][ 0 ] = From.m_aaElement[ 3 ][ 0 ];
906
m_aaElement[ 0 ][ 1 ] = From.m_aaElement[ 0 ][ 1 ];
907
m_aaElement[ 1 ][ 1 ] = From.m_aaElement[ 1 ][ 1 ];
908
m_aaElement[ 2 ][ 1 ] = From.m_aaElement[ 2 ][ 1 ];
909
m_aaElement[ 3 ][ 1 ] = From.m_aaElement[ 3 ][ 1 ];
910
m_aaElement[ 0 ][ 2 ] = From.m_aaElement[ 0 ][ 2 ];
911
m_aaElement[ 1 ][ 2 ] = From.m_aaElement[ 1 ][ 2 ];
912
m_aaElement[ 2 ][ 2 ] = From.m_aaElement[ 2 ][ 2 ];
913
m_aaElement[ 3 ][ 2 ] = From.m_aaElement[ 3 ][ 2 ];
914
m_aaElement[ 0 ][ 3 ] = From.m_aaElement[ 0 ][ 3 ];
915
m_aaElement[ 1 ][ 3 ] = From.m_aaElement[ 1 ][ 3 ];
916
m_aaElement[ 2 ][ 3 ] = From.m_aaElement[ 2 ][ 3 ];
917
m_aaElement[ 3 ][ 3 ] = From.m_aaElement[ 3 ][ 3 ];
919
m_fIdentity = From.m_fIdentity;
924
//---------------------------------------------------------------------
926
* \param From Renderman matrix to copy information from.
929
CqMatrix &CqMatrix::operator=( TqFloat From[ 4 ][ 4 ] )
931
m_aaElement[ 0 ][ 0 ] = From[ 0 ][ 0 ];
932
m_aaElement[ 1 ][ 0 ] = From[ 1 ][ 0 ];
933
m_aaElement[ 2 ][ 0 ] = From[ 2 ][ 0 ];
934
m_aaElement[ 3 ][ 0 ] = From[ 3 ][ 0 ];
935
m_aaElement[ 0 ][ 1 ] = From[ 0 ][ 1 ];
936
m_aaElement[ 1 ][ 1 ] = From[ 1 ][ 1 ];
937
m_aaElement[ 2 ][ 1 ] = From[ 2 ][ 1 ];
938
m_aaElement[ 3 ][ 1 ] = From[ 3 ][ 1 ];
939
m_aaElement[ 0 ][ 2 ] = From[ 0 ][ 2 ];
940
m_aaElement[ 1 ][ 2 ] = From[ 1 ][ 2 ];
941
m_aaElement[ 2 ][ 2 ] = From[ 2 ][ 2 ];
942
m_aaElement[ 3 ][ 2 ] = From[ 3 ][ 2 ];
943
m_aaElement[ 0 ][ 3 ] = From[ 0 ][ 3 ];
944
m_aaElement[ 1 ][ 3 ] = From[ 1 ][ 3 ];
945
m_aaElement[ 2 ][ 3 ] = From[ 2 ][ 3 ];
946
m_aaElement[ 3 ][ 3 ] = From[ 3 ][ 3 ];
948
m_fIdentity = TqFalse;
953
//---------------------------------------------------------------------
955
* \param From Renderman matrix to copy information from.
958
CqMatrix &CqMatrix::operator=( TqFloat From[ 16 ] )
960
m_aaElement[ 0 ][ 0 ] = From[ 0 ];
961
m_aaElement[ 0 ][ 1 ] = From[ 1 ];
962
m_aaElement[ 0 ][ 2 ] = From[ 2 ];
963
m_aaElement[ 0 ][ 3 ] = From[ 3 ];
964
m_aaElement[ 1 ][ 0 ] = From[ 4 ];
965
m_aaElement[ 1 ][ 1 ] = From[ 5 ];
966
m_aaElement[ 1 ][ 2 ] = From[ 6 ];
967
m_aaElement[ 1 ][ 3 ] = From[ 7 ];
968
m_aaElement[ 2 ][ 0 ] = From[ 8 ];
969
m_aaElement[ 2 ][ 1 ] = From[ 9 ];
970
m_aaElement[ 2 ][ 2 ] = From[ 10 ];
971
m_aaElement[ 2 ][ 3 ] = From[ 11 ];
972
m_aaElement[ 3 ][ 0 ] = From[ 12 ];
973
m_aaElement[ 3 ][ 1 ] = From[ 13 ];
974
m_aaElement[ 3 ][ 2 ] = From[ 14 ];
975
m_aaElement[ 3 ][ 3 ] = From[ 15 ];
977
m_fIdentity = TqFalse;
983
//---------------------------------------------------------------------
984
/** Returns the inverse of this matrix using an algorithm from Graphics
985
* Gems IV (p554) - Gauss-Jordan elimination with partial pivoting
988
CqMatrix CqMatrix::Inverse() const
990
CqMatrix b; // b evolves from identity into inverse(a)
991
CqMatrix a( *this ); // a evolves from original matrix into identity
1000
b.m_fIdentity = TqFalse;
1006
// Loop over cols of a from left to right, eliminating above and below diag
1007
for ( j = 0; j < 4; j++ ) // Find largest pivot in column j among rows j..3
1010
for ( i = j + 1; i < 4; i++ )
1012
if ( fabs( a.m_aaElement[ i ][ j ] ) > fabs( a.m_aaElement[ i1 ][ j ] ) )
1020
// Swap rows i1 and j in a and b to put pivot on diagonal
1023
temp = a.m_aaElement[ i1 ][ 0 ];
1024
a.m_aaElement[ i1 ][ 0 ] = a.m_aaElement[ j ][ 0 ];
1025
a.m_aaElement[ j ][ 0 ] = temp;
1026
temp = a.m_aaElement[ i1 ][ 1 ];
1027
a.m_aaElement[ i1 ][ 1 ] = a.m_aaElement[ j ][ 1 ];
1028
a.m_aaElement[ j ][ 1 ] = temp;
1029
temp = a.m_aaElement[ i1 ][ 2 ];
1030
a.m_aaElement[ i1 ][ 2 ] = a.m_aaElement[ j ][ 2 ];
1031
a.m_aaElement[ j ][ 2 ] = temp;
1032
temp = a.m_aaElement[ i1 ][ 3 ];
1033
a.m_aaElement[ i1 ][ 3 ] = a.m_aaElement[ j ][ 3 ];
1034
a.m_aaElement[ j ][ 3 ] = temp;
1036
temp = b.m_aaElement[ i1 ][ 0 ];
1037
b.m_aaElement[ i1 ][ 0 ] = b.m_aaElement[ j ][ 0 ];
1038
b.m_aaElement[ j ][ 0 ] = temp;
1039
temp = b.m_aaElement[ i1 ][ 1 ];
1040
b.m_aaElement[ i1 ][ 1 ] = b.m_aaElement[ j ][ 1 ];
1041
b.m_aaElement[ j ][ 1 ] = temp;
1042
temp = b.m_aaElement[ i1 ][ 2 ];
1043
b.m_aaElement[ i1 ][ 2 ] = b.m_aaElement[ j ][ 2 ];
1044
b.m_aaElement[ j ][ 2 ] = temp;
1045
temp = b.m_aaElement[ i1 ][ 3 ];
1046
b.m_aaElement[ i1 ][ 3 ] = b.m_aaElement[ j ][ 3 ];
1047
b.m_aaElement[ j ][ 3 ] = temp;
1050
// Scale row j to have a unit diagonal
1051
if ( a.m_aaElement[ j ][ j ] == 0.0f )
1053
// Can't invert a singular matrix!
1054
// throw XssMatrix(MatrixErr_Singular, __LINE__, ssMakeWide(__FILE__));
1056
TqFloat scale = 1.0f / a.m_aaElement[ j ][ j ];
1057
b.m_aaElement[ j ][ 0 ] *= scale;
1058
b.m_aaElement[ j ][ 1 ] *= scale;
1059
b.m_aaElement[ j ][ 2 ] *= scale;
1060
b.m_aaElement[ j ][ 3 ] *= scale;
1061
// all elements to left of a[j][j] are already zero
1062
for ( i1 = j + 1; i1 < 4; i1++ )
1064
a.m_aaElement[ j ][ i1 ] *= scale;
1066
a.m_aaElement[ j ][ j ] = 1.0f;
1068
// Eliminate off-diagonal elements in column j of a, doing identical ops to b
1069
for ( i = 0; i < 4; i++ )
1073
scale = a.m_aaElement[ i ][ j ];
1074
b.m_aaElement[ i ][ 0 ] -= scale * b.m_aaElement[ j ][ 0 ];
1075
b.m_aaElement[ i ][ 1 ] -= scale * b.m_aaElement[ j ][ 1 ];
1076
b.m_aaElement[ i ][ 2 ] -= scale * b.m_aaElement[ j ][ 2 ];
1077
b.m_aaElement[ i ][ 3 ] -= scale * b.m_aaElement[ j ][ 3 ];
1079
// all elements to left of a[j][j] are zero
1081
for ( i1 = j + 1; i1 < 4; i1++ )
1083
a.m_aaElement[ i ][ i1 ] -= scale * a.m_aaElement[ j ][ i1 ];
1085
a.m_aaElement[ i ][ j ] = 0.0f;
1094
//---------------------------------------------------------------------
1095
/** Returns the transpose of this matrix
1098
CqMatrix CqMatrix::Transpose() const
1108
Temp.m_aaElement[ 0 ][ 0 ] = m_aaElement[ 0 ][ 0 ];
1109
Temp.m_aaElement[ 0 ][ 1 ] = m_aaElement[ 1 ][ 0 ];
1110
Temp.m_aaElement[ 0 ][ 2 ] = m_aaElement[ 2 ][ 0 ];
1111
Temp.m_aaElement[ 0 ][ 3 ] = m_aaElement[ 3 ][ 0 ];
1112
Temp.m_aaElement[ 1 ][ 0 ] = m_aaElement[ 0 ][ 1 ];
1113
Temp.m_aaElement[ 1 ][ 1 ] = m_aaElement[ 1 ][ 1 ];
1114
Temp.m_aaElement[ 1 ][ 2 ] = m_aaElement[ 2 ][ 1 ];
1115
Temp.m_aaElement[ 1 ][ 3 ] = m_aaElement[ 3 ][ 1 ];
1116
Temp.m_aaElement[ 2 ][ 0 ] = m_aaElement[ 0 ][ 2 ];
1117
Temp.m_aaElement[ 2 ][ 1 ] = m_aaElement[ 1 ][ 2 ];
1118
Temp.m_aaElement[ 2 ][ 2 ] = m_aaElement[ 2 ][ 2 ];
1119
Temp.m_aaElement[ 2 ][ 3 ] = m_aaElement[ 3 ][ 2 ];
1120
Temp.m_aaElement[ 3 ][ 0 ] = m_aaElement[ 0 ][ 3 ];
1121
Temp.m_aaElement[ 3 ][ 1 ] = m_aaElement[ 1 ][ 3 ];
1122
Temp.m_aaElement[ 3 ][ 2 ] = m_aaElement[ 2 ][ 3 ];
1123
Temp.m_aaElement[ 3 ][ 3 ] = m_aaElement[ 3 ][ 3 ];
1125
Temp.m_fIdentity = TqFalse;
1132
//---------------------------------------------------------------------
1133
/** A utility function, used by CqMatrix::GetDeterminant
1134
* Calculates the determinant of a 2x2 matrix
1137
static TqFloat det2x2( TqFloat a, TqFloat b, TqFloat c, TqFloat d )
1139
return a * d - b * c;
1142
//---------------------------------------------------------------------
1143
/** A utility function, used by CqMatrix::GetDeterminant
1144
* Calculates the determinant of a 3x3 matrix
1147
static TqFloat det3x3( TqFloat a1, TqFloat a2, TqFloat a3,
1148
TqFloat b1, TqFloat b2, TqFloat b3,
1149
TqFloat c1, TqFloat c2, TqFloat c3 )
1151
return a1 * det2x2( b2, b3, c2, c3 ) -
1152
b1 * det2x2( a2, a3, c2, c3 ) +
1153
c1 * det2x2( a2, a3, b2, b3 );
1157
//---------------------------------------------------------------------
1158
/** Returns the determinant of this matrix using an algorithm from
1159
* Graphics Gems I (p768)
1162
TqFloat CqMatrix::Determinant() const
1164
// Assign to individual variable names to aid selecting correct elements
1165
TqFloat a1 = m_aaElement[ 0 ][ 0 ];
1166
TqFloat b1 = m_aaElement[ 0 ][ 1 ];
1167
TqFloat c1 = m_aaElement[ 0 ][ 2 ];
1168
TqFloat d1 = m_aaElement[ 0 ][ 3 ];
1170
TqFloat a2 = m_aaElement[ 1 ][ 0 ];
1171
TqFloat b2 = m_aaElement[ 1 ][ 1 ];
1172
TqFloat c2 = m_aaElement[ 1 ][ 2 ];
1173
TqFloat d2 = m_aaElement[ 1 ][ 3 ];
1175
TqFloat a3 = m_aaElement[ 2 ][ 0 ];
1176
TqFloat b3 = m_aaElement[ 2 ][ 1 ];
1177
TqFloat c3 = m_aaElement[ 2 ][ 2 ];
1178
TqFloat d3 = m_aaElement[ 2 ][ 3 ];
1180
TqFloat a4 = m_aaElement[ 3 ][ 0 ];
1181
TqFloat b4 = m_aaElement[ 3 ][ 1 ];
1182
TqFloat c4 = m_aaElement[ 3 ][ 2 ];
1183
TqFloat d4 = m_aaElement[ 3 ][ 3 ];
1185
return a1 * det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4 ) -
1186
b1 * det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4 ) +
1187
c1 * det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4 ) -
1188
d1 * det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4 );
1191
//----------------------------------------------------------------------
1192
/** Outputs a matrix to an output stream.
1193
* \param Stream Stream to output the matrix to.
1194
* \param Matrix The matrix to output.
1195
* \return The new state of Stream.
1198
std::ostream &operator<<( std::ostream &Stream, const CqMatrix &Matrix )
1200
if ( !Matrix.fIdentity() )
1202
Stream << "|" << Matrix.m_aaElement[ 0 ][ 0 ] <<
1203
"," << Matrix.m_aaElement[ 0 ][ 1 ] <<
1204
"," << Matrix.m_aaElement[ 0 ][ 2 ] <<
1205
"," << Matrix.m_aaElement[ 0 ][ 3 ] << "|" << std::endl <<
1206
"|" << Matrix.m_aaElement[ 1 ][ 0 ] <<
1207
"," << Matrix.m_aaElement[ 1 ][ 1 ] <<
1208
"," << Matrix.m_aaElement[ 1 ][ 2 ] <<
1209
"," << Matrix.m_aaElement[ 1 ][ 3 ] << "|" << std::endl <<
1210
"|" << Matrix.m_aaElement[ 2 ][ 0 ] <<
1211
"," << Matrix.m_aaElement[ 2 ][ 1 ] <<
1212
"," << Matrix.m_aaElement[ 2 ][ 2 ] <<
1213
"," << Matrix.m_aaElement[ 2 ][ 3 ] << "|" << std::endl <<
1214
"|" << Matrix.m_aaElement[ 3 ][ 0 ] <<
1215
"," << Matrix.m_aaElement[ 3 ][ 1 ] <<
1216
"," << Matrix.m_aaElement[ 3 ][ 2 ] <<
1217
"," << Matrix.m_aaElement[ 3 ][ 3 ] << "|" << std::ends;
1222
"|" << 1.0f << "," << 0.0f << "," << 0.0f << "," << 0.0f << "|" << std::endl <<
1223
"|" << 0.0f << "," << 1.0f << "," << 0.0f << "," << 0.0f << "|" << std::endl <<
1224
"|" << 0.0f << "," << 0.0f << "," << 1.0f << "," << 0.0f << "|" << std::endl <<
1225
"|" << 0.0f << "," << 0.0f << "," << 0.0f << "," << 1.0f << "|" << std::ends;
1232
//----------------------------------------------------------------------
1233
/** Outputs a matrix to an output stream.
1234
* \param Stream Stream to output the matrix to.
1235
* \param Matrix The matrix to output.
1236
* \return The new state of Stream.
1239
std::ostream &operator<<( std::ostream &Stream, CqMatrix &Matrix )
1241
if ( !Matrix.fIdentity() )
1243
Stream << "|" << Matrix.m_aaElement[ 0 ][ 0 ] <<
1244
"," << Matrix.m_aaElement[ 0 ][ 1 ] <<
1245
"," << Matrix.m_aaElement[ 0 ][ 2 ] <<
1246
"," << Matrix.m_aaElement[ 0 ][ 3 ] << "|" << std::endl <<
1247
"|" << Matrix.m_aaElement[ 1 ][ 0 ] <<
1248
"," << Matrix.m_aaElement[ 1 ][ 1 ] <<
1249
"," << Matrix.m_aaElement[ 1 ][ 2 ] <<
1250
"," << Matrix.m_aaElement[ 1 ][ 3 ] << "|" << std::endl <<
1251
"|" << Matrix.m_aaElement[ 2 ][ 0 ] <<
1252
"," << Matrix.m_aaElement[ 2 ][ 1 ] <<
1253
"," << Matrix.m_aaElement[ 2 ][ 2 ] <<
1254
"," << Matrix.m_aaElement[ 2 ][ 3 ] << "|" << std::endl <<
1255
"|" << Matrix.m_aaElement[ 3 ][ 0 ] <<
1256
"," << Matrix.m_aaElement[ 3 ][ 1 ] <<
1257
"," << Matrix.m_aaElement[ 3 ][ 2 ] <<
1258
"," << Matrix.m_aaElement[ 3 ][ 3 ] << "|" << std::ends;
1263
"|" << 1.0f << "," << 0.0f << "," << 0.0f << "," << 0.0f << "|" << std::endl <<
1264
"|" << 0.0f << "," << 1.0f << "," << 0.0f << "," << 0.0f << "|" << std::endl <<
1265
"|" << 0.0f << "," << 0.0f << "," << 1.0f << "," << 0.0f << "|" << std::endl <<
1266
"|" << 0.0f << "," << 0.0f << "," << 0.0f << "," << 1.0f << "|" << std::ends;
1273
//---------------------------------------------------------------------
1274
/** Scale each element by the specified value.
1275
* \param S The amount by which to scale the matrix elements.
1276
* \param a The matrix to be scaled.
1277
* \return Result of scaling this matrix by S.
1280
CqMatrix operator*( TqFloat S, const CqMatrix& a )
1283
Temp.m_aaElement[ 0 ][ 0 ] *= S;
1284
Temp.m_aaElement[ 1 ][ 0 ] *= S;
1285
Temp.m_aaElement[ 2 ][ 0 ] *= S;
1286
Temp.m_aaElement[ 3 ][ 0 ] *= S;
1288
Temp.m_aaElement[ 0 ][ 1 ] *= S;
1289
Temp.m_aaElement[ 1 ][ 1 ] *= S;
1290
Temp.m_aaElement[ 2 ][ 1 ] *= S;
1291
Temp.m_aaElement[ 3 ][ 1 ] *= S;
1293
Temp.m_aaElement[ 0 ][ 2 ] *= S;
1294
Temp.m_aaElement[ 1 ][ 2 ] *= S;
1295
Temp.m_aaElement[ 2 ][ 2 ] *= S;
1296
Temp.m_aaElement[ 3 ][ 2 ] *= S;
1298
Temp.m_aaElement[ 0 ][ 3 ] *= S;
1299
Temp.m_aaElement[ 1 ][ 3 ] *= S;
1300
Temp.m_aaElement[ 2 ][ 3 ] *= S;
1301
Temp.m_aaElement[ 3 ][ 3 ] *= S;
1306
//---------------------------------------------------------------------
1307
/** Premultiply matrix by vector.
1310
CqVector4D operator*( const CqVector4D &Vector, const CqMatrix& Matrix )
1312
return ( Matrix.PreMultiply( Vector ) );
1315
//---------------------------------------------------------------------
1317
END_NAMESPACE( Aqsis )