~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to libaqsistypes/matrix.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Aqsis
 
2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory
 
3
//
 
4
// Contact: pgregory@aqsis.com
 
5
//
 
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.
 
10
//
 
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.
 
15
//
 
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
 
19
 
 
20
 
 
21
/** \file
 
22
                \brief Implements the CqMatrix 4D homogenous matrix class.
 
23
                \author Paul C. Gregory (pgregory@aqsis.com)
 
24
*/
 
25
 
 
26
#include        <math.h>
 
27
#include        "matrix.h"
 
28
 
 
29
START_NAMESPACE( Aqsis )
 
30
 
 
31
 
 
32
//---------------------------------------------------------------------
 
33
/** Identity matrix constructor
 
34
 */
 
35
 
 
36
CqMatrix::CqMatrix( )
 
37
{
 
38
    Identity();
 
39
}
 
40
 
 
41
 
 
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.
 
47
 */
 
48
 
 
49
CqMatrix::CqMatrix( const TqFloat xs, const TqFloat ys, const TqFloat zs )
 
50
{
 
51
    Identity();
 
52
 
 
53
    if ( xs == 1.0f && ys == 1.0f && zs == 1.0f )
 
54
        m_fIdentity = TqTrue;
 
55
    else
 
56
    {
 
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;
 
61
 
 
62
        m_fIdentity = TqFalse;
 
63
    }
 
64
}
 
65
 
 
66
 
 
67
//---------------------------------------------------------------------
 
68
/** Translate constructor. Constructs a translation matrix translating by a given vector.
 
69
 * \param Trans The vector by which to translate.
 
70
 */
 
71
 
 
72
CqMatrix::CqMatrix( const CqVector3D& Trans )
 
73
{
 
74
    Identity();
 
75
 
 
76
    if ( Trans.x() == 0.0f && Trans.y() == 0.0f && Trans.z() == 0.0f )
 
77
        m_fIdentity = TqTrue;
 
78
    else
 
79
    {
 
80
        m_fIdentity = TqFalse;
 
81
 
 
82
        m_aaElement[ 3 ][ 0 ] = Trans.x();
 
83
        m_aaElement[ 3 ][ 1 ] = Trans.y();
 
84
        m_aaElement[ 3 ][ 2 ] = Trans.z();
 
85
    }
 
86
}
 
87
 
 
88
 
 
89
//---------------------------------------------------------------------
 
90
/** Rotate matrix constructor
 
91
 * \param Angle The angle to rotate by.
 
92
 * \param Axis The axis about which to rotate.
 
93
 */
 
94
 
 
95
CqMatrix::CqMatrix( const TqFloat Angle, const CqVector3D Axis )
 
96
{
 
97
    Identity();
 
98
 
 
99
    if ( Angle != 0.0f && Axis.Magnitude() != 0.0f )
 
100
        Rotate( Angle, Axis );
 
101
}
 
102
 
 
103
 
 
104
//---------------------------------------------------------------------
 
105
/** Skew matrix constructor
 
106
 * \param Angle 
 
107
 * \param dx1, dy1, dz1
 
108
 * \param dx2, dy2, dz2
 
109
 *
 
110
 * For now base this on what Larry Gritz posted a while back.
 
111
 * There are some more optimizations that can be done.
 
112
 */
 
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 )
 
117
{
 
118
    // Normalize the two vectors, and construct a third perpendicular
 
119
    CqVector3D d1( dx1, dy1, dz1 ), d2( dx2, dy2, dz2 );
 
120
    d1.Unit();
 
121
    d2.Unit();
 
122
 
 
123
    // Assumes angle already changed to radians.
 
124
 
 
125
    TqFloat d1d2dot = d1 * d2;
 
126
    TqFloat axisangle = static_cast<TqFloat>(acos( d1d2dot ));
 
127
    if ( angle >= axisangle || angle <= ( axisangle - PI ) )
 
128
    {
 
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
 
133
        //   looking:
 
134
        // CqBasicError(0,Severity_Normal,"RiSkew angle invalid.");
 
135
        Identity();
 
136
    }
 
137
    else
 
138
    {
 
139
        CqVector3D right = d1 % d2;
 
140
        right.Unit();
 
141
 
 
142
        // d1ortho will be perpendicular to <d2> and <right> and can be
 
143
        // used to construct a rotation matrix
 
144
        CqVector3D d1ortho = d2 % right;
 
145
 
 
146
 
 
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.
 
149
        // 3) Rotate back.
 
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,
 
153
                      0, 0, 0, 1 );
 
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,
 
158
                      0, 1, s, 0,
 
159
                      0, 0, 1, 0,
 
160
                      0, 0, 0, 1 );
 
161
        // Note the Inverse of a rotation matrix is its Transpose.
 
162
        *this = Rot.Transpose() * Skw * Rot;
 
163
    }
 
164
}
 
165
 
 
166
//---------------------------------------------------------------------
 
167
/** Copy constructor.
 
168
 */
 
169
 
 
170
CqMatrix::CqMatrix( const CqMatrix &From )
 
171
{
 
172
    *this = From;
 
173
}
 
174
 
 
175
//---------------------------------------------------------------------
 
176
/** Constructor from a 2D float array.
 
177
 * \param From 2D float array to copy data from.
 
178
 */
 
179
 
 
180
CqMatrix::CqMatrix( TqFloat From[ 4 ][ 4 ] )
 
181
{
 
182
    *this = From;
 
183
}
 
184
 
 
185
 
 
186
//---------------------------------------------------------------------
 
187
/** Constructor from a float array.
 
188
 * \param From 1D float array to copy data from.
 
189
 */
 
190
 
 
191
CqMatrix::CqMatrix( TqFloat From[ 16 ] )
 
192
{
 
193
    *this = From;
 
194
}
 
195
 
 
196
//---------------------------------------------------------------------
 
197
/** Turn the matrix into an identity.
 
198
 */
 
199
 
 
200
void CqMatrix::Identity()
 
201
{
 
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;
 
214
 
 
215
    m_aaElement[ 0 ][ 0 ] =
 
216
        m_aaElement[ 1 ][ 1 ] =
 
217
            m_aaElement[ 2 ][ 2 ] =
 
218
                m_aaElement[ 3 ][ 3 ] = 1.0f;
 
219
 
 
220
    m_fIdentity = TqTrue;
 
221
}
 
222
 
 
223
 
 
224
//---------------------------------------------------------------------
 
225
/** Scale matrix uniformly in all three axes.
 
226
 * \param S     The amount to scale by.
 
227
 */
 
228
 
 
229
void CqMatrix::Scale( const TqFloat S )
 
230
{
 
231
    if ( S != 1.0f )
 
232
        Scale( S, S, S );
 
233
}
 
234
 
 
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.
 
240
 */
 
241
 
 
242
void CqMatrix::Scale( const TqFloat xs, const TqFloat ys, const TqFloat zs )
 
243
{
 
244
    CqMatrix Scale( xs, ys, zs );
 
245
 
 
246
    this->PreMultiply( Scale );
 
247
}
 
248
 
 
249
 
 
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.
 
254
 */
 
255
 
 
256
void CqMatrix::Rotate( const TqFloat Angle, const CqVector3D Axis )
 
257
{
 
258
    if ( Angle != 0.0f )
 
259
    {
 
260
        CqMatrix        R;
 
261
        R.Identity();
 
262
        CqVector3D      RotAxis = Axis;
 
263
        R.m_fIdentity = TqFalse;
 
264
 
 
265
        RotAxis.Unit();
 
266
 
 
267
        TqFloat s = static_cast<TqFloat>( sin( Angle ) );
 
268
        TqFloat c = static_cast<TqFloat>( cos( Angle ) );
 
269
        TqFloat t = 1.0f - c;
 
270
 
 
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;
 
274
 
 
275
        TqFloat txy = t * RotAxis.x() * RotAxis.y();
 
276
        TqFloat sz = s * RotAxis.z();
 
277
 
 
278
        R.m_aaElement[ 0 ][ 1 ] = txy + sz;
 
279
        R.m_aaElement[ 1 ][ 0 ] = txy - sz;
 
280
 
 
281
        TqFloat txz = t * RotAxis.x() * RotAxis.z();
 
282
        TqFloat sy = s * RotAxis.y();
 
283
 
 
284
        R.m_aaElement[ 0 ][ 2 ] = txz - sy;
 
285
        R.m_aaElement[ 2 ][ 0 ] = txz + sy;
 
286
 
 
287
        TqFloat tyz = t * RotAxis.y() * RotAxis.z();
 
288
        TqFloat sx = s * RotAxis.x();
 
289
 
 
290
        R.m_aaElement[ 1 ][ 2 ] = tyz + sx;
 
291
        R.m_aaElement[ 2 ][ 1 ] = tyz - sx;
 
292
 
 
293
        this->PreMultiply( R );
 
294
    }
 
295
}
 
296
 
 
297
 
 
298
//---------------------------------------------------------------------
 
299
/** Translates this matrix by a given vector.
 
300
 * \param Trans The vector by which to translate.
 
301
 */
 
302
 
 
303
void CqMatrix::Translate( const CqVector3D& Trans )
 
304
{
 
305
    CqMatrix matTrans( Trans );
 
306
    this->PreMultiply( matTrans );
 
307
}
 
308
 
 
309
 
 
310
 
 
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.
 
316
 */
 
317
 
 
318
void CqMatrix::Translate( const TqFloat xt, const TqFloat yt, const TqFloat zt )
 
319
{
 
320
    if ( xt != 0.0f || yt != 0.0f || zt != 0.0f )
 
321
        Translate( CqVector3D( xt, yt, zt ) );
 
322
}
 
323
 
 
324
 
 
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.
 
329
 */
 
330
 
 
331
void CqMatrix::ShearX( const TqFloat yh, const TqFloat zh )
 
332
{
 
333
    CqMatrix Shear;
 
334
    Shear.m_fIdentity = TqFalse;
 
335
 
 
336
    Shear.m_aaElement[ 0 ][ 1 ] = yh;
 
337
    Shear.m_aaElement[ 0 ][ 2 ] = zh;
 
338
 
 
339
    this->PreMultiply( Shear );
 
340
}
 
341
 
 
342
 
 
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.
 
347
 */
 
348
 
 
349
void CqMatrix::ShearY( const TqFloat xh, const TqFloat zh )
 
350
{
 
351
    CqMatrix Shear;
 
352
    Shear.m_fIdentity = TqFalse;
 
353
 
 
354
    Shear.m_aaElement[ 1 ][ 0 ] = xh;
 
355
    Shear.m_aaElement[ 1 ][ 2 ] = zh;
 
356
 
 
357
    this->PreMultiply( Shear );
 
358
}
 
359
 
 
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.
 
364
 */
 
365
 
 
366
void CqMatrix::ShearZ( const TqFloat xh, const TqFloat yh )
 
367
{
 
368
    CqMatrix Shear;
 
369
    Shear.m_fIdentity = TqFalse;
 
370
 
 
371
    Shear.m_aaElement[ 2 ][ 0 ] = xh;
 
372
    Shear.m_aaElement[ 2 ][ 1 ] = yh;
 
373
 
 
374
    this->PreMultiply( Shear );
 
375
}
 
376
 
 
377
//---------------------------------------------------------------------
 
378
/** Skew matrix
 
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.
 
386
 */
 
387
 
 
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 )
 
391
{
 
392
    CqMatrix Skew( angle, dx1, dy1, dz1, dx2, dy2, dz2 );
 
393
 
 
394
    this->PreMultiply( Skew );
 
395
}
 
396
 
 
397
//---------------------------------------------------------------------
 
398
/** Normalise the matrix, returning the homogenous part of the matrix to 1.
 
399
 */
 
400
 
 
401
void CqMatrix::Normalise()
 
402
{
 
403
    for ( TqInt i = 0; i < 4; i++ )
 
404
    {
 
405
        for ( TqInt j = 0; j < 4; j++ )
 
406
        {
 
407
            m_aaElement[ i ][ j ] /= m_aaElement[ 3 ][ 3 ];
 
408
        }
 
409
    }
 
410
}
 
411
 
 
412
 
 
413
//---------------------------------------------------------------------
 
414
/** Multiply two matrices together.
 
415
 * \param From The matrix to multiply with this matrix.
 
416
 * \return The resultant multiplied matrix.
 
417
 */
 
418
 
 
419
CqMatrix CqMatrix::operator*( const CqMatrix &From ) const
 
420
{
 
421
    CqMatrix Temp( *this );
 
422
    Temp *= From;
 
423
    return ( Temp );
 
424
}
 
425
 
 
426
 
 
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.
 
430
 */
 
431
 
 
432
CqMatrix &CqMatrix::operator*=( const CqMatrix &From )
 
433
{
 
434
    if ( m_fIdentity )
 
435
        return ( *this = From );
 
436
    else if ( From.m_fIdentity )
 
437
        return ( *this );
 
438
 
 
439
    CqMatrix A( *this );
 
440
 
 
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 ];
 
457
 
 
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 ];
 
474
 
 
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 ];
 
491
 
 
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 ];
 
508
 
 
509
    m_fIdentity = TqFalse;
 
510
    return ( *this );
 
511
}
 
512
 
 
513
//---------------------------------------------------------------------
 
514
/** Matrix multiplication of the form a = b * a.
 
515
 * \param From The matrix to multiply with this matrix.
 
516
 */
 
517
 
 
518
CqMatrix& CqMatrix::PreMultiply( const CqMatrix &From )
 
519
{
 
520
    if ( m_fIdentity )
 
521
        return ( *this = From );
 
522
    else if ( From.m_fIdentity )
 
523
        return ( *this );
 
524
 
 
525
    CqMatrix A( *this );
 
526
 
 
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 ];
 
543
 
 
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 ];
 
560
 
 
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 ];
 
577
 
 
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 ];
 
594
 
 
595
    m_fIdentity = TqFalse;
 
596
    return ( *this );
 
597
}
 
598
 
 
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.
 
603
 */
 
604
 
 
605
CqVector4D CqMatrix::PreMultiply( const CqVector4D &Vector ) const
 
606
{
 
607
    if ( m_fIdentity )
 
608
        return ( Vector );
 
609
 
 
610
    CqVector4D  Result;
 
611
 
 
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() );
 
616
 
 
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() );
 
621
 
 
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() );
 
626
 
 
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() );
 
631
 
 
632
    return ( Result );
 
633
}
 
634
 
 
635
 
 
636
 
 
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.
 
641
 */
 
642
 
 
643
CqMatrix CqMatrix::operator*( const TqFloat S ) const
 
644
{
 
645
    CqMatrix Temp( *this );
 
646
    Temp *= S;
 
647
    return ( Temp );
 
648
}
 
649
 
 
650
 
 
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.
 
655
 */
 
656
 
 
657
CqMatrix &CqMatrix::operator*=( const TqFloat S )
 
658
{
 
659
    CqMatrix ScaleMatrix( S, S, S );
 
660
 
 
661
    this->PreMultiply( ScaleMatrix );
 
662
 
 
663
    return ( *this );
 
664
}
 
665
 
 
666
 
 
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.
 
671
 */
 
672
 
 
673
CqVector4D CqMatrix::operator*( const CqVector4D &Vector ) const
 
674
{
 
675
    if ( m_fIdentity )
 
676
        return ( Vector );
 
677
 
 
678
    CqVector4D  Result;
 
679
 
 
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() );
 
684
 
 
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() );
 
689
 
 
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() );
 
694
 
 
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() );
 
699
 
 
700
    return ( Result );
 
701
}
 
702
 
 
703
 
 
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.
 
708
 */
 
709
 
 
710
CqVector3D CqMatrix::operator*( const CqVector3D &Vector ) const
 
711
{
 
712
    if ( m_fIdentity )
 
713
        return ( Vector );
 
714
 
 
715
    CqVector3D  Result;
 
716
 
 
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 ] );
 
721
 
 
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 );
 
726
 
 
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 );
 
731
 
 
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 );
 
736
 
 
737
 
 
738
    return ( Result );
 
739
}
 
740
 
 
741
 
 
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.
 
746
 */
 
747
 
 
748
CqMatrix CqMatrix::operator+( const CqVector4D &Vector ) const
 
749
{
 
750
    CqMatrix Temp( *this );
 
751
    Temp += Vector;
 
752
    return ( Temp );
 
753
}
 
754
 
 
755
 
 
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.
 
760
 */
 
761
 
 
762
CqMatrix &CqMatrix::operator+=( const CqVector4D &Vector )
 
763
{
 
764
    CqMatrix Trans( Vector );
 
765
 
 
766
    this->PreMultiply( Trans );
 
767
 
 
768
    return ( *this );
 
769
}
 
770
 
 
771
 
 
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.
 
776
 */
 
777
 
 
778
CqMatrix CqMatrix::operator-( const CqVector4D &Vector ) const
 
779
{
 
780
    CqMatrix Temp( *this );
 
781
    Temp -= Vector;
 
782
    return ( Temp );
 
783
}
 
784
 
 
785
 
 
786
//---------------------------------------------------------------------
 
787
/** Translate this matrix by 4D Vector.
 
788
 * \param Vector The vector to translate by.
 
789
 */
 
790
 
 
791
CqMatrix &CqMatrix::operator-=( const CqVector4D &Vector )
 
792
{
 
793
    CqVector4D Temp( Vector );
 
794
 
 
795
    Temp.x( -Temp.x() );
 
796
    Temp.y( -Temp.y() );
 
797
    Temp.z( -Temp.z() );
 
798
 
 
799
    CqMatrix Trans( Temp );
 
800
 
 
801
    this->PreMultiply( Trans );
 
802
 
 
803
    return ( *this );
 
804
}
 
805
 
 
806
 
 
807
//---------------------------------------------------------------------
 
808
/** Add two matrices.
 
809
 * \param From The matrix to add.
 
810
 * \return Result of adding From to this matrix.
 
811
 */
 
812
 
 
813
CqMatrix CqMatrix::operator+( const CqMatrix &From ) const
 
814
{
 
815
    CqMatrix Temp( *this );
 
816
    Temp += From;
 
817
    return ( Temp );
 
818
}
 
819
 
 
820
 
 
821
//---------------------------------------------------------------------
 
822
/** Add a given matrix to this matrix.
 
823
 * \param From The matrix to add.
 
824
 */
 
825
 
 
826
CqMatrix &CqMatrix::operator+=( const CqMatrix &From )
 
827
{
 
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 ];
 
844
 
 
845
    m_fIdentity = TqFalse;
 
846
 
 
847
    return ( *this );
 
848
}
 
849
 
 
850
 
 
851
//---------------------------------------------------------------------
 
852
/** Subtract two matrices.
 
853
 * \param From The matrix to subtract.
 
854
 * \return Result of subtracting From from this matrix.
 
855
 */
 
856
 
 
857
CqMatrix CqMatrix::operator-( const CqMatrix &From ) const
 
858
{
 
859
    CqMatrix Temp( *this );
 
860
    Temp -= From;
 
861
    return ( Temp );
 
862
}
 
863
 
 
864
 
 
865
//---------------------------------------------------------------------
 
866
/** Subtract a given matrix from this matrix.
 
867
 * \param From The matrix to subtract.
 
868
 */
 
869
 
 
870
CqMatrix &CqMatrix::operator-=( const CqMatrix &From )
 
871
{
 
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 ];
 
888
 
 
889
    m_fIdentity = TqFalse;
 
890
 
 
891
    return ( *this );
 
892
}
 
893
 
 
894
 
 
895
//---------------------------------------------------------------------
 
896
/** Copy function.
 
897
 * \param From Matrix to copy information from.
 
898
 */
 
899
 
 
900
CqMatrix &CqMatrix::operator=( const CqMatrix &From )
 
901
{
 
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 ];
 
918
 
 
919
    m_fIdentity = From.m_fIdentity;
 
920
 
 
921
    return ( *this );
 
922
}
 
923
 
 
924
//---------------------------------------------------------------------
 
925
/** Copy function.
 
926
 * \param From Renderman matrix to copy information from.
 
927
 */
 
928
 
 
929
CqMatrix &CqMatrix::operator=( TqFloat From[ 4 ][ 4 ] )
 
930
{
 
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 ];
 
947
 
 
948
    m_fIdentity = TqFalse;
 
949
 
 
950
    return ( *this );
 
951
}
 
952
 
 
953
//---------------------------------------------------------------------
 
954
/** Copy function.
 
955
 * \param From Renderman matrix to copy information from.
 
956
 */
 
957
 
 
958
CqMatrix &CqMatrix::operator=( TqFloat From[ 16 ] )
 
959
{
 
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 ];
 
976
 
 
977
    m_fIdentity = TqFalse;
 
978
 
 
979
    return ( *this );
 
980
}
 
981
 
 
982
 
 
983
//---------------------------------------------------------------------
 
984
/** Returns the inverse of this matrix using an algorithm from Graphics
 
985
 *  Gems IV (p554) - Gauss-Jordan elimination with partial pivoting
 
986
 */
 
987
 
 
988
CqMatrix CqMatrix::Inverse() const
 
989
{
 
990
    CqMatrix b;         // b evolves from identity into inverse(a)
 
991
    CqMatrix a( *this );        // a evolves from original matrix into identity
 
992
 
 
993
    if ( m_fIdentity )
 
994
    {
 
995
        b = *this;
 
996
    }
 
997
    else
 
998
    {
 
999
        b.Identity();
 
1000
        b.m_fIdentity = TqFalse;
 
1001
 
 
1002
        TqInt i;
 
1003
        TqInt j;
 
1004
        TqInt i1;
 
1005
 
 
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
 
1008
        {
 
1009
            i1 = j;
 
1010
            for ( i = j + 1; i < 4; i++ )
 
1011
            {
 
1012
                if ( fabs( a.m_aaElement[ i ][ j ] ) > fabs( a.m_aaElement[ i1 ][ j ] ) )
 
1013
                {
 
1014
                    i1 = i;
 
1015
                }
 
1016
            }
 
1017
 
 
1018
            if ( i1 != j )
 
1019
            {
 
1020
                // Swap rows i1 and j in a and b to put pivot on diagonal
 
1021
                TqFloat temp;
 
1022
 
 
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;
 
1035
 
 
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;
 
1048
            }
 
1049
 
 
1050
            // Scale row j to have a unit diagonal
 
1051
            if ( a.m_aaElement[ j ][ j ] == 0.0f )
 
1052
            {
 
1053
                // Can't invert a singular matrix!
 
1054
                //                              throw XssMatrix(MatrixErr_Singular, __LINE__, ssMakeWide(__FILE__));
 
1055
            }
 
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++ )
 
1063
            {
 
1064
                a.m_aaElement[ j ][ i1 ] *= scale;
 
1065
            }
 
1066
            a.m_aaElement[ j ][ j ] = 1.0f;
 
1067
 
 
1068
            // Eliminate off-diagonal elements in column j of a, doing identical ops to b
 
1069
            for ( i = 0; i < 4; i++ )
 
1070
            {
 
1071
                if ( i != j )
 
1072
                {
 
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 ];
 
1078
 
 
1079
                    // all elements to left of a[j][j] are zero
 
1080
                    // a[j][j] is 1.0
 
1081
                    for ( i1 = j + 1; i1 < 4; i1++ )
 
1082
                    {
 
1083
                        a.m_aaElement[ i ][ i1 ] -= scale * a.m_aaElement[ j ][ i1 ];
 
1084
                    }
 
1085
                    a.m_aaElement[ i ][ j ] = 0.0f;
 
1086
                }
 
1087
            }
 
1088
        }
 
1089
    }
 
1090
 
 
1091
    return b;
 
1092
}
 
1093
 
 
1094
//---------------------------------------------------------------------
 
1095
/** Returns the transpose of this matrix
 
1096
 */
 
1097
 
 
1098
CqMatrix CqMatrix::Transpose() const
 
1099
{
 
1100
    CqMatrix Temp;
 
1101
 
 
1102
    if ( m_fIdentity )
 
1103
    {
 
1104
        Temp = *this;
 
1105
    }
 
1106
    else
 
1107
    {
 
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 ];
 
1124
 
 
1125
        Temp.m_fIdentity = TqFalse;
 
1126
    }
 
1127
 
 
1128
    return ( Temp );
 
1129
}
 
1130
 
 
1131
 
 
1132
//---------------------------------------------------------------------
 
1133
/** A utility function, used by CqMatrix::GetDeterminant
 
1134
 * Calculates the determinant of a 2x2 matrix
 
1135
 */
 
1136
 
 
1137
static TqFloat det2x2( TqFloat a, TqFloat b, TqFloat c, TqFloat d )
 
1138
{
 
1139
    return a * d - b * c;
 
1140
}
 
1141
 
 
1142
//---------------------------------------------------------------------
 
1143
/** A utility function, used by CqMatrix::GetDeterminant
 
1144
 * Calculates the determinant of a 3x3 matrix
 
1145
 */
 
1146
 
 
1147
static TqFloat det3x3( TqFloat a1, TqFloat a2, TqFloat a3,
 
1148
                       TqFloat b1, TqFloat b2, TqFloat b3,
 
1149
                       TqFloat c1, TqFloat c2, TqFloat c3 )
 
1150
{
 
1151
    return a1 * det2x2( b2, b3, c2, c3 ) -
 
1152
           b1 * det2x2( a2, a3, c2, c3 ) +
 
1153
           c1 * det2x2( a2, a3, b2, b3 );
 
1154
}
 
1155
 
 
1156
 
 
1157
//---------------------------------------------------------------------
 
1158
/** Returns the determinant of this matrix using an algorithm from
 
1159
 * Graphics Gems I (p768)
 
1160
 */
 
1161
 
 
1162
TqFloat CqMatrix::Determinant() const
 
1163
{
 
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 ];
 
1169
 
 
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 ];
 
1174
 
 
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 ];
 
1179
 
 
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 ];
 
1184
 
 
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 );
 
1189
}
 
1190
 
 
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.
 
1196
 */
 
1197
 
 
1198
std::ostream &operator<<( std::ostream &Stream, const CqMatrix &Matrix )
 
1199
{
 
1200
    if ( !Matrix.fIdentity() )
 
1201
    {
 
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;
 
1218
    }
 
1219
    else
 
1220
    {
 
1221
        Stream <<
 
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;
 
1226
    }
 
1227
 
 
1228
    return ( Stream );
 
1229
}
 
1230
 
 
1231
 
 
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.
 
1237
 */
 
1238
 
 
1239
std::ostream &operator<<( std::ostream &Stream, CqMatrix &Matrix )
 
1240
{
 
1241
    if ( !Matrix.fIdentity() )
 
1242
    {
 
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;
 
1259
    }
 
1260
    else
 
1261
    {
 
1262
        Stream <<
 
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;
 
1267
    }
 
1268
 
 
1269
    return ( Stream );
 
1270
}
 
1271
 
 
1272
 
 
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.
 
1278
 */
 
1279
 
 
1280
CqMatrix operator*( TqFloat S, const CqMatrix& a )
 
1281
{
 
1282
    CqMatrix Temp( 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;
 
1287
 
 
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;
 
1292
 
 
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;
 
1297
 
 
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;
 
1302
    return ( Temp );
 
1303
}
 
1304
 
 
1305
 
 
1306
//---------------------------------------------------------------------
 
1307
/** Premultiply matrix by vector.
 
1308
 */
 
1309
 
 
1310
CqVector4D operator*( const CqVector4D &Vector, const CqMatrix& Matrix )
 
1311
{
 
1312
    return ( Matrix.PreMultiply( Vector ) );
 
1313
}
 
1314
 
 
1315
//---------------------------------------------------------------------
 
1316
 
 
1317
END_NAMESPACE( Aqsis )