1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
///////////////////////////////////////////////////////////////////////////
37
#ifndef INCLUDED_IMATHMATRIX_H
38
#define INCLUDED_IMATHMATRIX_H
40
//----------------------------------------------------------------
42
// 2D (3x3) and 3D (4x4) transformation matrix templates.
44
//----------------------------------------------------------------
46
#include "ImathPlatform.h"
50
#include "ImathShear.h"
57
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
58
// suppress exception specification warnings
59
#pragma warning(disable:4290)
65
enum Uninitialized {UNINITIALIZED};
68
template <class T> class Matrix33
78
T * operator [] (int i);
79
const T * operator [] (int i) const;
86
Matrix33 (Uninitialized) {}
98
Matrix33 (const T a[3][3]);
99
// a[0][0] a[0][1] a[0][2]
100
// a[1][0] a[1][1] a[1][2]
101
// a[2][0] a[2][1] a[2][2]
103
Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i);
110
//--------------------------------
111
// Copy constructor and assignment
112
//--------------------------------
114
Matrix33 (const Matrix33 &v);
115
template <class S> explicit Matrix33 (const Matrix33<S> &v);
117
const Matrix33 & operator = (const Matrix33 &v);
118
const Matrix33 & operator = (T a);
121
//----------------------
122
// Compatibility with Sb
123
//----------------------
126
const T * getValue () const;
129
void getValue (Matrix33<S> &v) const;
131
Matrix33 & setValue (const Matrix33<S> &v);
134
Matrix33 & setTheMatrix (const Matrix33<S> &v);
148
bool operator == (const Matrix33 &v) const;
149
bool operator != (const Matrix33 &v) const;
151
//-----------------------------------------------------------------------
152
// Compare two matrices and test if they are "approximately equal":
154
// equalWithAbsError (m, e)
156
// Returns true if the coefficients of this and m are the same with
157
// an absolute error of no more than e, i.e., for all i, j
159
// abs (this[i][j] - m[i][j]) <= e
161
// equalWithRelError (m, e)
163
// Returns true if the coefficients of this and m are the same with
164
// a relative error of no more than e, i.e., for all i, j
166
// abs (this[i] - v[i][j]) <= e * abs (this[i][j])
167
//-----------------------------------------------------------------------
169
bool equalWithAbsError (const Matrix33<T> &v, T e) const;
170
bool equalWithRelError (const Matrix33<T> &v, T e) const;
173
//------------------------
174
// Component-wise addition
175
//------------------------
177
const Matrix33 & operator += (const Matrix33 &v);
178
const Matrix33 & operator += (T a);
179
Matrix33 operator + (const Matrix33 &v) const;
182
//---------------------------
183
// Component-wise subtraction
184
//---------------------------
186
const Matrix33 & operator -= (const Matrix33 &v);
187
const Matrix33 & operator -= (T a);
188
Matrix33 operator - (const Matrix33 &v) const;
191
//------------------------------------
192
// Component-wise multiplication by -1
193
//------------------------------------
195
Matrix33 operator - () const;
196
const Matrix33 & negate ();
199
//------------------------------
200
// Component-wise multiplication
201
//------------------------------
203
const Matrix33 & operator *= (T a);
204
Matrix33 operator * (T a) const;
207
//-----------------------------------
208
// Matrix-times-matrix multiplication
209
//-----------------------------------
211
const Matrix33 & operator *= (const Matrix33 &v);
212
Matrix33 operator * (const Matrix33 &v) const;
215
//-----------------------------------------------------------------
216
// Vector-times-matrix multiplication; see also the "operator *"
217
// functions defined below.
219
// m.multVecMatrix(src,dst) implements a homogeneous transformation
220
// by computing Vec3 (src.x, src.y, 1) * m and dividing by the
221
// result's third element.
223
// m.multDirMatrix(src,dst) multiplies src by the upper left 2x2
224
// submatrix, ignoring the rest of matrix m.
225
//-----------------------------------------------------------------
228
void multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const;
231
void multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const;
234
//------------------------
235
// Component-wise division
236
//------------------------
238
const Matrix33 & operator /= (T a);
239
Matrix33 operator / (T a) const;
246
const Matrix33 & transpose ();
247
Matrix33 transposed () const;
250
//------------------------------------------------------------
251
// Inverse matrix: If singExc is false, inverting a singular
252
// matrix produces an identity matrix. If singExc is true,
253
// inverting a singular matrix throws a SingMatrixExc.
255
// inverse() and invert() invert matrices using determinants;
256
// gjInverse() and gjInvert() use the Gauss-Jordan method.
258
// inverse() and invert() are significantly faster than
259
// gjInverse() and gjInvert(), but the results may be slightly
262
//------------------------------------------------------------
264
const Matrix33 & invert (bool singExc = false)
265
throw (Iex::MathExc);
267
Matrix33<T> inverse (bool singExc = false) const
268
throw (Iex::MathExc);
270
const Matrix33 & gjInvert (bool singExc = false)
271
throw (Iex::MathExc);
273
Matrix33<T> gjInverse (bool singExc = false) const
274
throw (Iex::MathExc);
277
//------------------------------------------------
278
// Calculate the matrix minor of the (r,c) element
279
//------------------------------------------------
281
T minorOf (const int r, const int c) const;
283
//---------------------------------------------------
284
// Build a minor using the specified rows and columns
285
//---------------------------------------------------
287
T fastMinor (const int r0, const int r1,
288
const int c0, const int c1) const;
294
T determinant() const;
296
//-----------------------------------------
297
// Set matrix to rotation by r (in radians)
298
//-----------------------------------------
301
const Matrix33 & setRotation (S r);
304
//-----------------------------
305
// Rotate the given matrix by r
306
//-----------------------------
309
const Matrix33 & rotate (S r);
312
//--------------------------------------------
313
// Set matrix to scale by given uniform factor
314
//--------------------------------------------
316
const Matrix33 & setScale (T s);
319
//------------------------------------
320
// Set matrix to scale by given vector
321
//------------------------------------
324
const Matrix33 & setScale (const Vec2<S> &s);
327
//----------------------
328
// Scale the matrix by s
329
//----------------------
332
const Matrix33 & scale (const Vec2<S> &s);
335
//------------------------------------------
336
// Set matrix to translation by given vector
337
//------------------------------------------
340
const Matrix33 & setTranslation (const Vec2<S> &t);
343
//-----------------------------
344
// Return translation component
345
//-----------------------------
347
Vec2<T> translation () const;
350
//--------------------------
351
// Translate the matrix by t
352
//--------------------------
355
const Matrix33 & translate (const Vec2<S> &t);
358
//-----------------------------------------------------------
359
// Set matrix to shear x for each y coord. by given factor xy
360
//-----------------------------------------------------------
363
const Matrix33 & setShear (const S &h);
366
//-------------------------------------------------------------
367
// Set matrix to shear x for each y coord. by given factor h[0]
368
// and to shear y for each x coord. by given factor h[1]
369
//-------------------------------------------------------------
372
const Matrix33 & setShear (const Vec2<S> &h);
375
//-----------------------------------------------------------
376
// Shear the matrix in x for each y coord. by given factor xy
377
//-----------------------------------------------------------
380
const Matrix33 & shear (const S &xy);
383
//-----------------------------------------------------------
384
// Shear the matrix in x for each y coord. by given factor xy
385
// and shear y for each x coord. by given factor yx
386
//-----------------------------------------------------------
389
const Matrix33 & shear (const Vec2<S> &h);
392
//--------------------------------------------------------
393
// Number of the row and column dimensions, since
394
// Matrix33 is a square matrix.
395
//--------------------------------------------------------
397
static unsigned int dimensions() {return 3;}
400
//-------------------------------------------------
401
// Limitations of type T (see also class limits<T>)
402
//-------------------------------------------------
404
static T baseTypeMin() {return limits<T>::min();}
405
static T baseTypeMax() {return limits<T>::max();}
406
static T baseTypeSmallest() {return limits<T>::smallest();}
407
static T baseTypeEpsilon() {return limits<T>::epsilon();}
410
typedef Vec3<T> BaseVecType;
414
template <typename R, typename S>
420
template <typename R>
421
struct isSameType<R, R>
428
template <class T> class Matrix44
432
//-------------------
433
// Access to elements
434
//-------------------
438
T * operator [] (int i);
439
const T * operator [] (int i) const;
446
Matrix44 (Uninitialized) {}
460
Matrix44 (const T a[4][4]) ;
461
// a[0][0] a[0][1] a[0][2] a[0][3]
462
// a[1][0] a[1][1] a[1][2] a[1][3]
463
// a[2][0] a[2][1] a[2][2] a[2][3]
464
// a[3][0] a[3][1] a[3][2] a[3][3]
466
Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,
467
T i, T j, T k, T l, T m, T n, T o, T p);
474
Matrix44 (Matrix33<T> r, Vec3<T> t);
481
//--------------------------------
482
// Copy constructor and assignment
483
//--------------------------------
485
Matrix44 (const Matrix44 &v);
486
template <class S> explicit Matrix44 (const Matrix44<S> &v);
488
const Matrix44 & operator = (const Matrix44 &v);
489
const Matrix44 & operator = (T a);
492
//----------------------
493
// Compatibility with Sb
494
//----------------------
497
const T * getValue () const;
500
void getValue (Matrix44<S> &v) const;
502
Matrix44 & setValue (const Matrix44<S> &v);
505
Matrix44 & setTheMatrix (const Matrix44<S> &v);
518
bool operator == (const Matrix44 &v) const;
519
bool operator != (const Matrix44 &v) const;
521
//-----------------------------------------------------------------------
522
// Compare two matrices and test if they are "approximately equal":
524
// equalWithAbsError (m, e)
526
// Returns true if the coefficients of this and m are the same with
527
// an absolute error of no more than e, i.e., for all i, j
529
// abs (this[i][j] - m[i][j]) <= e
531
// equalWithRelError (m, e)
533
// Returns true if the coefficients of this and m are the same with
534
// a relative error of no more than e, i.e., for all i, j
536
// abs (this[i] - v[i][j]) <= e * abs (this[i][j])
537
//-----------------------------------------------------------------------
539
bool equalWithAbsError (const Matrix44<T> &v, T e) const;
540
bool equalWithRelError (const Matrix44<T> &v, T e) const;
543
//------------------------
544
// Component-wise addition
545
//------------------------
547
const Matrix44 & operator += (const Matrix44 &v);
548
const Matrix44 & operator += (T a);
549
Matrix44 operator + (const Matrix44 &v) const;
552
//---------------------------
553
// Component-wise subtraction
554
//---------------------------
556
const Matrix44 & operator -= (const Matrix44 &v);
557
const Matrix44 & operator -= (T a);
558
Matrix44 operator - (const Matrix44 &v) const;
561
//------------------------------------
562
// Component-wise multiplication by -1
563
//------------------------------------
565
Matrix44 operator - () const;
566
const Matrix44 & negate ();
569
//------------------------------
570
// Component-wise multiplication
571
//------------------------------
573
const Matrix44 & operator *= (T a);
574
Matrix44 operator * (T a) const;
577
//-----------------------------------
578
// Matrix-times-matrix multiplication
579
//-----------------------------------
581
const Matrix44 & operator *= (const Matrix44 &v);
582
Matrix44 operator * (const Matrix44 &v) const;
584
static void multiply (const Matrix44 &a, // assumes that
585
const Matrix44 &b, // &a != &c and
586
Matrix44 &c); // &b != &c.
589
//-----------------------------------------------------------------
590
// Vector-times-matrix multiplication; see also the "operator *"
591
// functions defined below.
593
// m.multVecMatrix(src,dst) implements a homogeneous transformation
594
// by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by
595
// the result's third element.
597
// m.multDirMatrix(src,dst) multiplies src by the upper left 3x3
598
// submatrix, ignoring the rest of matrix m.
599
//-----------------------------------------------------------------
602
void multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const;
605
void multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const;
608
//------------------------
609
// Component-wise division
610
//------------------------
612
const Matrix44 & operator /= (T a);
613
Matrix44 operator / (T a) const;
620
const Matrix44 & transpose ();
621
Matrix44 transposed () const;
624
//------------------------------------------------------------
625
// Inverse matrix: If singExc is false, inverting a singular
626
// matrix produces an identity matrix. If singExc is true,
627
// inverting a singular matrix throws a SingMatrixExc.
629
// inverse() and invert() invert matrices using determinants;
630
// gjInverse() and gjInvert() use the Gauss-Jordan method.
632
// inverse() and invert() are significantly faster than
633
// gjInverse() and gjInvert(), but the results may be slightly
636
//------------------------------------------------------------
638
const Matrix44 & invert (bool singExc = false)
639
throw (Iex::MathExc);
641
Matrix44<T> inverse (bool singExc = false) const
642
throw (Iex::MathExc);
644
const Matrix44 & gjInvert (bool singExc = false)
645
throw (Iex::MathExc);
647
Matrix44<T> gjInverse (bool singExc = false) const
648
throw (Iex::MathExc);
651
//------------------------------------------------
652
// Calculate the matrix minor of the (r,c) element
653
//------------------------------------------------
655
T minorOf (const int r, const int c) const;
657
//---------------------------------------------------
658
// Build a minor using the specified rows and columns
659
//---------------------------------------------------
661
T fastMinor (const int r0, const int r1, const int r2,
662
const int c0, const int c1, const int c2) const;
668
T determinant() const;
670
//--------------------------------------------------------
671
// Set matrix to rotation by XYZ euler angles (in radians)
672
//--------------------------------------------------------
675
const Matrix44 & setEulerAngles (const Vec3<S>& r);
678
//--------------------------------------------------------
679
// Set matrix to rotation around given axis by given angle
680
//--------------------------------------------------------
683
const Matrix44 & setAxisAngle (const Vec3<S>& ax, S ang);
686
//-------------------------------------------
687
// Rotate the matrix by XYZ euler angles in r
688
//-------------------------------------------
691
const Matrix44 & rotate (const Vec3<S> &r);
694
//--------------------------------------------
695
// Set matrix to scale by given uniform factor
696
//--------------------------------------------
698
const Matrix44 & setScale (T s);
701
//------------------------------------
702
// Set matrix to scale by given vector
703
//------------------------------------
706
const Matrix44 & setScale (const Vec3<S> &s);
709
//----------------------
710
// Scale the matrix by s
711
//----------------------
714
const Matrix44 & scale (const Vec3<S> &s);
717
//------------------------------------------
718
// Set matrix to translation by given vector
719
//------------------------------------------
722
const Matrix44 & setTranslation (const Vec3<S> &t);
725
//-----------------------------
726
// Return translation component
727
//-----------------------------
729
const Vec3<T> translation () const;
732
//--------------------------
733
// Translate the matrix by t
734
//--------------------------
737
const Matrix44 & translate (const Vec3<S> &t);
740
//-------------------------------------------------------------
741
// Set matrix to shear by given vector h. The resulting matrix
742
// will shear x for each y coord. by a factor of h[0] ;
743
// will shear x for each z coord. by a factor of h[1] ;
744
// will shear y for each z coord. by a factor of h[2] .
745
//-------------------------------------------------------------
748
const Matrix44 & setShear (const Vec3<S> &h);
751
//------------------------------------------------------------
752
// Set matrix to shear by given factors. The resulting matrix
753
// will shear x for each y coord. by a factor of h.xy ;
754
// will shear x for each z coord. by a factor of h.xz ;
755
// will shear y for each z coord. by a factor of h.yz ;
756
// will shear y for each x coord. by a factor of h.yx ;
757
// will shear z for each x coord. by a factor of h.zx ;
758
// will shear z for each y coord. by a factor of h.zy .
759
//------------------------------------------------------------
762
const Matrix44 & setShear (const Shear6<S> &h);
765
//--------------------------------------------------------
766
// Shear the matrix by given vector. The composed matrix
767
// will be <shear> * <this>, where the shear matrix ...
768
// will shear x for each y coord. by a factor of h[0] ;
769
// will shear x for each z coord. by a factor of h[1] ;
770
// will shear y for each z coord. by a factor of h[2] .
771
//--------------------------------------------------------
774
const Matrix44 & shear (const Vec3<S> &h);
776
//--------------------------------------------------------
777
// Number of the row and column dimensions, since
778
// Matrix44 is a square matrix.
779
//--------------------------------------------------------
781
static unsigned int dimensions() {return 4;}
784
//------------------------------------------------------------
785
// Shear the matrix by the given factors. The composed matrix
786
// will be <shear> * <this>, where the shear matrix ...
787
// will shear x for each y coord. by a factor of h.xy ;
788
// will shear x for each z coord. by a factor of h.xz ;
789
// will shear y for each z coord. by a factor of h.yz ;
790
// will shear y for each x coord. by a factor of h.yx ;
791
// will shear z for each x coord. by a factor of h.zx ;
792
// will shear z for each y coord. by a factor of h.zy .
793
//------------------------------------------------------------
796
const Matrix44 & shear (const Shear6<S> &h);
799
//-------------------------------------------------
800
// Limitations of type T (see also class limits<T>)
801
//-------------------------------------------------
803
static T baseTypeMin() {return limits<T>::min();}
804
static T baseTypeMax() {return limits<T>::max();}
805
static T baseTypeSmallest() {return limits<T>::smallest();}
806
static T baseTypeEpsilon() {return limits<T>::epsilon();}
809
typedef Vec4<T> BaseVecType;
813
template <typename R, typename S>
819
template <typename R>
820
struct isSameType<R, R>
832
std::ostream & operator << (std::ostream & s, const Matrix33<T> &m);
835
std::ostream & operator << (std::ostream & s, const Matrix44<T> &m);
838
//---------------------------------------------
839
// Vector-times-matrix multiplication operators
840
//---------------------------------------------
842
template <class S, class T>
843
const Vec2<S> & operator *= (Vec2<S> &v, const Matrix33<T> &m);
845
template <class S, class T>
846
Vec2<S> operator * (const Vec2<S> &v, const Matrix33<T> &m);
848
template <class S, class T>
849
const Vec3<S> & operator *= (Vec3<S> &v, const Matrix33<T> &m);
851
template <class S, class T>
852
Vec3<S> operator * (const Vec3<S> &v, const Matrix33<T> &m);
854
template <class S, class T>
855
const Vec3<S> & operator *= (Vec3<S> &v, const Matrix44<T> &m);
857
template <class S, class T>
858
Vec3<S> operator * (const Vec3<S> &v, const Matrix44<T> &m);
860
template <class S, class T>
861
const Vec4<S> & operator *= (Vec4<S> &v, const Matrix44<T> &m);
863
template <class S, class T>
864
Vec4<S> operator * (const Vec4<S> &v, const Matrix44<T> &m);
866
//-------------------------
867
// Typedefs for convenience
868
//-------------------------
870
typedef Matrix33 <float> M33f;
871
typedef Matrix33 <double> M33d;
872
typedef Matrix44 <float> M44f;
873
typedef Matrix44 <double> M44d;
876
//---------------------------
877
// Implementation of Matrix33
878
//---------------------------
882
Matrix33<T>::operator [] (int i)
889
Matrix33<T>::operator [] (int i) const
896
Matrix33<T>::Matrix33 ()
898
memset (x, 0, sizeof (x));
906
Matrix33<T>::Matrix33 (T a)
921
Matrix33<T>::Matrix33 (const T a[3][3])
923
memcpy (x, a, sizeof (x));
928
Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i)
943
Matrix33<T>::Matrix33 (const Matrix33 &v)
945
memcpy (x, v.x, sizeof (x));
951
Matrix33<T>::Matrix33 (const Matrix33<S> &v)
953
x[0][0] = T (v.x[0][0]);
954
x[0][1] = T (v.x[0][1]);
955
x[0][2] = T (v.x[0][2]);
956
x[1][0] = T (v.x[1][0]);
957
x[1][1] = T (v.x[1][1]);
958
x[1][2] = T (v.x[1][2]);
959
x[2][0] = T (v.x[2][0]);
960
x[2][1] = T (v.x[2][1]);
961
x[2][2] = T (v.x[2][2]);
965
inline const Matrix33<T> &
966
Matrix33<T>::operator = (const Matrix33 &v)
968
memcpy (x, v.x, sizeof (x));
973
inline const Matrix33<T> &
974
Matrix33<T>::operator = (T a)
990
Matrix33<T>::getValue ()
992
return (T *) &x[0][0];
997
Matrix33<T>::getValue () const
999
return (const T *) &x[0][0];
1005
Matrix33<T>::getValue (Matrix33<S> &v) const
1007
if (isSameType<S,T>::value)
1009
memcpy (v.x, x, sizeof (x));
1013
v.x[0][0] = x[0][0];
1014
v.x[0][1] = x[0][1];
1015
v.x[0][2] = x[0][2];
1016
v.x[1][0] = x[1][0];
1017
v.x[1][1] = x[1][1];
1018
v.x[1][2] = x[1][2];
1019
v.x[2][0] = x[2][0];
1020
v.x[2][1] = x[2][1];
1021
v.x[2][2] = x[2][2];
1027
inline Matrix33<T> &
1028
Matrix33<T>::setValue (const Matrix33<S> &v)
1030
if (isSameType<S,T>::value)
1032
memcpy (x, v.x, sizeof (x));
1036
x[0][0] = v.x[0][0];
1037
x[0][1] = v.x[0][1];
1038
x[0][2] = v.x[0][2];
1039
x[1][0] = v.x[1][0];
1040
x[1][1] = v.x[1][1];
1041
x[1][2] = v.x[1][2];
1042
x[2][0] = v.x[2][0];
1043
x[2][1] = v.x[2][1];
1044
x[2][2] = v.x[2][2];
1052
inline Matrix33<T> &
1053
Matrix33<T>::setTheMatrix (const Matrix33<S> &v)
1055
if (isSameType<S,T>::value)
1057
memcpy (x, v.x, sizeof (x));
1061
x[0][0] = v.x[0][0];
1062
x[0][1] = v.x[0][1];
1063
x[0][2] = v.x[0][2];
1064
x[1][0] = v.x[1][0];
1065
x[1][1] = v.x[1][1];
1066
x[1][2] = v.x[1][2];
1067
x[2][0] = v.x[2][0];
1068
x[2][1] = v.x[2][1];
1069
x[2][2] = v.x[2][2];
1077
Matrix33<T>::makeIdentity()
1079
memset (x, 0, sizeof (x));
1087
Matrix33<T>::operator == (const Matrix33 &v) const
1089
return x[0][0] == v.x[0][0] &&
1090
x[0][1] == v.x[0][1] &&
1091
x[0][2] == v.x[0][2] &&
1092
x[1][0] == v.x[1][0] &&
1093
x[1][1] == v.x[1][1] &&
1094
x[1][2] == v.x[1][2] &&
1095
x[2][0] == v.x[2][0] &&
1096
x[2][1] == v.x[2][1] &&
1097
x[2][2] == v.x[2][2];
1102
Matrix33<T>::operator != (const Matrix33 &v) const
1104
return x[0][0] != v.x[0][0] ||
1105
x[0][1] != v.x[0][1] ||
1106
x[0][2] != v.x[0][2] ||
1107
x[1][0] != v.x[1][0] ||
1108
x[1][1] != v.x[1][1] ||
1109
x[1][2] != v.x[1][2] ||
1110
x[2][0] != v.x[2][0] ||
1111
x[2][1] != v.x[2][1] ||
1112
x[2][2] != v.x[2][2];
1117
Matrix33<T>::equalWithAbsError (const Matrix33<T> &m, T e) const
1119
for (int i = 0; i < 3; i++)
1120
for (int j = 0; j < 3; j++)
1121
if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
1129
Matrix33<T>::equalWithRelError (const Matrix33<T> &m, T e) const
1131
for (int i = 0; i < 3; i++)
1132
for (int j = 0; j < 3; j++)
1133
if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
1141
Matrix33<T>::operator += (const Matrix33<T> &v)
1143
x[0][0] += v.x[0][0];
1144
x[0][1] += v.x[0][1];
1145
x[0][2] += v.x[0][2];
1146
x[1][0] += v.x[1][0];
1147
x[1][1] += v.x[1][1];
1148
x[1][2] += v.x[1][2];
1149
x[2][0] += v.x[2][0];
1150
x[2][1] += v.x[2][1];
1151
x[2][2] += v.x[2][2];
1158
Matrix33<T>::operator += (T a)
1175
Matrix33<T>::operator + (const Matrix33<T> &v) const
1177
return Matrix33 (x[0][0] + v.x[0][0],
1178
x[0][1] + v.x[0][1],
1179
x[0][2] + v.x[0][2],
1180
x[1][0] + v.x[1][0],
1181
x[1][1] + v.x[1][1],
1182
x[1][2] + v.x[1][2],
1183
x[2][0] + v.x[2][0],
1184
x[2][1] + v.x[2][1],
1185
x[2][2] + v.x[2][2]);
1190
Matrix33<T>::operator -= (const Matrix33<T> &v)
1192
x[0][0] -= v.x[0][0];
1193
x[0][1] -= v.x[0][1];
1194
x[0][2] -= v.x[0][2];
1195
x[1][0] -= v.x[1][0];
1196
x[1][1] -= v.x[1][1];
1197
x[1][2] -= v.x[1][2];
1198
x[2][0] -= v.x[2][0];
1199
x[2][1] -= v.x[2][1];
1200
x[2][2] -= v.x[2][2];
1207
Matrix33<T>::operator -= (T a)
1224
Matrix33<T>::operator - (const Matrix33<T> &v) const
1226
return Matrix33 (x[0][0] - v.x[0][0],
1227
x[0][1] - v.x[0][1],
1228
x[0][2] - v.x[0][2],
1229
x[1][0] - v.x[1][0],
1230
x[1][1] - v.x[1][1],
1231
x[1][2] - v.x[1][2],
1232
x[2][0] - v.x[2][0],
1233
x[2][1] - v.x[2][1],
1234
x[2][2] - v.x[2][2]);
1239
Matrix33<T>::operator - () const
1241
return Matrix33 (-x[0][0],
1254
Matrix33<T>::negate ()
1271
Matrix33<T>::operator *= (T a)
1288
Matrix33<T>::operator * (T a) const
1290
return Matrix33 (x[0][0] * a,
1303
operator * (T a, const Matrix33<T> &v)
1310
Matrix33<T>::operator *= (const Matrix33<T> &v)
1312
Matrix33 tmp (T (0));
1314
for (int i = 0; i < 3; i++)
1315
for (int j = 0; j < 3; j++)
1316
for (int k = 0; k < 3; k++)
1317
tmp.x[i][j] += x[i][k] * v.x[k][j];
1325
Matrix33<T>::operator * (const Matrix33<T> &v) const
1327
Matrix33 tmp (T (0));
1329
for (int i = 0; i < 3; i++)
1330
for (int j = 0; j < 3; j++)
1331
for (int k = 0; k < 3; k++)
1332
tmp.x[i][j] += x[i][k] * v.x[k][j];
1340
Matrix33<T>::multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const
1344
a = src[0] * x[0][0] + src[1] * x[1][0] + x[2][0];
1345
b = src[0] * x[0][1] + src[1] * x[1][1] + x[2][1];
1346
w = src[0] * x[0][2] + src[1] * x[1][2] + x[2][2];
1355
Matrix33<T>::multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const
1359
a = src[0] * x[0][0] + src[1] * x[1][0];
1360
b = src[0] * x[0][1] + src[1] * x[1][1];
1368
Matrix33<T>::operator /= (T a)
1385
Matrix33<T>::operator / (T a) const
1387
return Matrix33 (x[0][0] / a,
1400
Matrix33<T>::transpose ()
1402
Matrix33 tmp (x[0][0],
1417
Matrix33<T>::transposed () const
1419
return Matrix33 (x[0][0],
1432
Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
1434
*this = gjInverse (singExc);
1440
Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
1446
// Forward elimination
1448
for (i = 0; i < 2 ; i++)
1452
T pivotsize = t[i][i];
1455
pivotsize = -pivotsize;
1457
for (j = i + 1; j < 3; j++)
1464
if (tmp > pivotsize)
1474
throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
1481
for (j = 0; j < 3; j++)
1486
t[i][j] = t[pivot][j];
1490
s[i][j] = s[pivot][j];
1495
for (j = i + 1; j < 3; j++)
1497
T f = t[j][i] / t[i][i];
1499
for (k = 0; k < 3; k++)
1501
t[j][k] -= f * t[i][k];
1502
s[j][k] -= f * s[i][k];
1507
// Backward substitution
1509
for (i = 2; i >= 0; --i)
1513
if ((f = t[i][i]) == 0)
1516
throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
1521
for (j = 0; j < 3; j++)
1527
for (j = 0; j < i; j++)
1531
for (k = 0; k < 3; k++)
1533
t[j][k] -= f * t[i][k];
1534
s[j][k] -= f * s[i][k];
1544
Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
1546
*this = inverse (singExc);
1552
Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
1554
if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
1556
Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
1557
x[2][1] * x[0][2] - x[0][1] * x[2][2],
1558
x[0][1] * x[1][2] - x[1][1] * x[0][2],
1560
x[2][0] * x[1][2] - x[1][0] * x[2][2],
1561
x[0][0] * x[2][2] - x[2][0] * x[0][2],
1562
x[1][0] * x[0][2] - x[0][0] * x[1][2],
1564
x[1][0] * x[2][1] - x[2][0] * x[1][1],
1565
x[2][0] * x[0][1] - x[0][0] * x[2][1],
1566
x[0][0] * x[1][1] - x[1][0] * x[0][1]);
1568
T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
1570
if (Imath::abs (r) >= 1)
1572
for (int i = 0; i < 3; ++i)
1574
for (int j = 0; j < 3; ++j)
1582
T mr = Imath::abs (r) / limits<T>::smallest();
1584
for (int i = 0; i < 3; ++i)
1586
for (int j = 0; j < 3; ++j)
1588
if (mr > Imath::abs (s[i][j]))
1595
throw SingMatrixExc ("Cannot invert "
1596
"singular matrix.");
1607
Matrix33 s ( x[1][1],
1619
T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1621
if (Imath::abs (r) >= 1)
1623
for (int i = 0; i < 2; ++i)
1625
for (int j = 0; j < 2; ++j)
1633
T mr = Imath::abs (r) / limits<T>::smallest();
1635
for (int i = 0; i < 2; ++i)
1637
for (int j = 0; j < 2; ++j)
1639
if (mr > Imath::abs (s[i][j]))
1646
throw SingMatrixExc ("Cannot invert "
1647
"singular matrix.");
1654
s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0];
1655
s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1];
1663
Matrix33<T>::minorOf (const int r, const int c) const
1665
int r0 = 0 + (r < 1 ? 1 : 0);
1666
int r1 = 1 + (r < 2 ? 1 : 0);
1667
int c0 = 0 + (c < 1 ? 1 : 0);
1668
int c1 = 1 + (c < 2 ? 1 : 0);
1670
return x[r0][c0]*x[r1][c1] - x[r1][c0]*x[r0][c1];
1675
Matrix33<T>::fastMinor( const int r0, const int r1,
1676
const int c0, const int c1) const
1678
return x[r0][c0]*x[r1][c1] - x[r0][c1]*x[r1][c0];
1683
Matrix33<T>::determinant () const
1685
return x[0][0]*(x[1][1]*x[2][2] - x[1][2]*x[2][1]) +
1686
x[0][1]*(x[1][2]*x[2][0] - x[1][0]*x[2][2]) +
1687
x[0][2]*(x[1][0]*x[2][1] - x[1][1]*x[2][0]);
1693
Matrix33<T>::setRotation (S r)
1697
cos_r = Math<T>::cos (r);
1698
sin_r = Math<T>::sin (r);
1718
Matrix33<T>::rotate (S r)
1720
*this *= Matrix33<T>().setRotation (r);
1726
Matrix33<T>::setScale (T s)
1728
memset (x, 0, sizeof (x));
1739
Matrix33<T>::setScale (const Vec2<S> &s)
1741
memset (x, 0, sizeof (x));
1752
Matrix33<T>::scale (const Vec2<S> &s)
1768
Matrix33<T>::setTranslation (const Vec2<S> &t)
1787
Matrix33<T>::translation () const
1789
return Vec2<T> (x[2][0], x[2][1]);
1795
Matrix33<T>::translate (const Vec2<S> &t)
1797
x[2][0] += t[0] * x[0][0] + t[1] * x[1][0];
1798
x[2][1] += t[0] * x[0][1] + t[1] * x[1][1];
1799
x[2][2] += t[0] * x[0][2] + t[1] * x[1][2];
1807
Matrix33<T>::setShear (const S &xy)
1827
Matrix33<T>::setShear (const Vec2<S> &h)
1847
Matrix33<T>::shear (const S &xy)
1850
// In this case, we don't need a temp. copy of the matrix
1851
// because we never use a value on the RHS after we've
1852
// changed it on the LHS.
1855
x[1][0] += xy * x[0][0];
1856
x[1][1] += xy * x[0][1];
1857
x[1][2] += xy * x[0][2];
1865
Matrix33<T>::shear (const Vec2<S> &h)
1867
Matrix33<T> P (*this);
1869
x[0][0] = P[0][0] + h[1] * P[1][0];
1870
x[0][1] = P[0][1] + h[1] * P[1][1];
1871
x[0][2] = P[0][2] + h[1] * P[1][2];
1873
x[1][0] = P[1][0] + h[0] * P[0][0];
1874
x[1][1] = P[1][1] + h[0] * P[0][1];
1875
x[1][2] = P[1][2] + h[0] * P[0][2];
1881
//---------------------------
1882
// Implementation of Matrix44
1883
//---------------------------
1887
Matrix44<T>::operator [] (int i)
1894
Matrix44<T>::operator [] (int i) const
1901
Matrix44<T>::Matrix44 ()
1903
memset (x, 0, sizeof (x));
1912
Matrix44<T>::Matrix44 (T a)
1934
Matrix44<T>::Matrix44 (const T a[4][4])
1936
memcpy (x, a, sizeof (x));
1941
Matrix44<T>::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,
1942
T i, T j, T k, T l, T m, T n, T o, T p)
1965
Matrix44<T>::Matrix44 (Matrix33<T> r, Vec3<T> t)
1987
Matrix44<T>::Matrix44 (const Matrix44 &v)
1989
x[0][0] = v.x[0][0];
1990
x[0][1] = v.x[0][1];
1991
x[0][2] = v.x[0][2];
1992
x[0][3] = v.x[0][3];
1993
x[1][0] = v.x[1][0];
1994
x[1][1] = v.x[1][1];
1995
x[1][2] = v.x[1][2];
1996
x[1][3] = v.x[1][3];
1997
x[2][0] = v.x[2][0];
1998
x[2][1] = v.x[2][1];
1999
x[2][2] = v.x[2][2];
2000
x[2][3] = v.x[2][3];
2001
x[3][0] = v.x[3][0];
2002
x[3][1] = v.x[3][1];
2003
x[3][2] = v.x[3][2];
2004
x[3][3] = v.x[3][3];
2010
Matrix44<T>::Matrix44 (const Matrix44<S> &v)
2012
x[0][0] = T (v.x[0][0]);
2013
x[0][1] = T (v.x[0][1]);
2014
x[0][2] = T (v.x[0][2]);
2015
x[0][3] = T (v.x[0][3]);
2016
x[1][0] = T (v.x[1][0]);
2017
x[1][1] = T (v.x[1][1]);
2018
x[1][2] = T (v.x[1][2]);
2019
x[1][3] = T (v.x[1][3]);
2020
x[2][0] = T (v.x[2][0]);
2021
x[2][1] = T (v.x[2][1]);
2022
x[2][2] = T (v.x[2][2]);
2023
x[2][3] = T (v.x[2][3]);
2024
x[3][0] = T (v.x[3][0]);
2025
x[3][1] = T (v.x[3][1]);
2026
x[3][2] = T (v.x[3][2]);
2027
x[3][3] = T (v.x[3][3]);
2031
inline const Matrix44<T> &
2032
Matrix44<T>::operator = (const Matrix44 &v)
2034
x[0][0] = v.x[0][0];
2035
x[0][1] = v.x[0][1];
2036
x[0][2] = v.x[0][2];
2037
x[0][3] = v.x[0][3];
2038
x[1][0] = v.x[1][0];
2039
x[1][1] = v.x[1][1];
2040
x[1][2] = v.x[1][2];
2041
x[1][3] = v.x[1][3];
2042
x[2][0] = v.x[2][0];
2043
x[2][1] = v.x[2][1];
2044
x[2][2] = v.x[2][2];
2045
x[2][3] = v.x[2][3];
2046
x[3][0] = v.x[3][0];
2047
x[3][1] = v.x[3][1];
2048
x[3][2] = v.x[3][2];
2049
x[3][3] = v.x[3][3];
2054
inline const Matrix44<T> &
2055
Matrix44<T>::operator = (T a)
2078
Matrix44<T>::getValue ()
2080
return (T *) &x[0][0];
2085
Matrix44<T>::getValue () const
2087
return (const T *) &x[0][0];
2093
Matrix44<T>::getValue (Matrix44<S> &v) const
2095
if (isSameType<S,T>::value)
2097
memcpy (v.x, x, sizeof (x));
2101
v.x[0][0] = x[0][0];
2102
v.x[0][1] = x[0][1];
2103
v.x[0][2] = x[0][2];
2104
v.x[0][3] = x[0][3];
2105
v.x[1][0] = x[1][0];
2106
v.x[1][1] = x[1][1];
2107
v.x[1][2] = x[1][2];
2108
v.x[1][3] = x[1][3];
2109
v.x[2][0] = x[2][0];
2110
v.x[2][1] = x[2][1];
2111
v.x[2][2] = x[2][2];
2112
v.x[2][3] = x[2][3];
2113
v.x[3][0] = x[3][0];
2114
v.x[3][1] = x[3][1];
2115
v.x[3][2] = x[3][2];
2116
v.x[3][3] = x[3][3];
2122
inline Matrix44<T> &
2123
Matrix44<T>::setValue (const Matrix44<S> &v)
2125
if (isSameType<S,T>::value)
2127
memcpy (x, v.x, sizeof (x));
2131
x[0][0] = v.x[0][0];
2132
x[0][1] = v.x[0][1];
2133
x[0][2] = v.x[0][2];
2134
x[0][3] = v.x[0][3];
2135
x[1][0] = v.x[1][0];
2136
x[1][1] = v.x[1][1];
2137
x[1][2] = v.x[1][2];
2138
x[1][3] = v.x[1][3];
2139
x[2][0] = v.x[2][0];
2140
x[2][1] = v.x[2][1];
2141
x[2][2] = v.x[2][2];
2142
x[2][3] = v.x[2][3];
2143
x[3][0] = v.x[3][0];
2144
x[3][1] = v.x[3][1];
2145
x[3][2] = v.x[3][2];
2146
x[3][3] = v.x[3][3];
2154
inline Matrix44<T> &
2155
Matrix44<T>::setTheMatrix (const Matrix44<S> &v)
2157
if (isSameType<S,T>::value)
2159
memcpy (x, v.x, sizeof (x));
2163
x[0][0] = v.x[0][0];
2164
x[0][1] = v.x[0][1];
2165
x[0][2] = v.x[0][2];
2166
x[0][3] = v.x[0][3];
2167
x[1][0] = v.x[1][0];
2168
x[1][1] = v.x[1][1];
2169
x[1][2] = v.x[1][2];
2170
x[1][3] = v.x[1][3];
2171
x[2][0] = v.x[2][0];
2172
x[2][1] = v.x[2][1];
2173
x[2][2] = v.x[2][2];
2174
x[2][3] = v.x[2][3];
2175
x[3][0] = v.x[3][0];
2176
x[3][1] = v.x[3][1];
2177
x[3][2] = v.x[3][2];
2178
x[3][3] = v.x[3][3];
2186
Matrix44<T>::makeIdentity()
2188
memset (x, 0, sizeof (x));
2197
Matrix44<T>::operator == (const Matrix44 &v) const
2199
return x[0][0] == v.x[0][0] &&
2200
x[0][1] == v.x[0][1] &&
2201
x[0][2] == v.x[0][2] &&
2202
x[0][3] == v.x[0][3] &&
2203
x[1][0] == v.x[1][0] &&
2204
x[1][1] == v.x[1][1] &&
2205
x[1][2] == v.x[1][2] &&
2206
x[1][3] == v.x[1][3] &&
2207
x[2][0] == v.x[2][0] &&
2208
x[2][1] == v.x[2][1] &&
2209
x[2][2] == v.x[2][2] &&
2210
x[2][3] == v.x[2][3] &&
2211
x[3][0] == v.x[3][0] &&
2212
x[3][1] == v.x[3][1] &&
2213
x[3][2] == v.x[3][2] &&
2214
x[3][3] == v.x[3][3];
2219
Matrix44<T>::operator != (const Matrix44 &v) const
2221
return x[0][0] != v.x[0][0] ||
2222
x[0][1] != v.x[0][1] ||
2223
x[0][2] != v.x[0][2] ||
2224
x[0][3] != v.x[0][3] ||
2225
x[1][0] != v.x[1][0] ||
2226
x[1][1] != v.x[1][1] ||
2227
x[1][2] != v.x[1][2] ||
2228
x[1][3] != v.x[1][3] ||
2229
x[2][0] != v.x[2][0] ||
2230
x[2][1] != v.x[2][1] ||
2231
x[2][2] != v.x[2][2] ||
2232
x[2][3] != v.x[2][3] ||
2233
x[3][0] != v.x[3][0] ||
2234
x[3][1] != v.x[3][1] ||
2235
x[3][2] != v.x[3][2] ||
2236
x[3][3] != v.x[3][3];
2241
Matrix44<T>::equalWithAbsError (const Matrix44<T> &m, T e) const
2243
for (int i = 0; i < 4; i++)
2244
for (int j = 0; j < 4; j++)
2245
if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
2253
Matrix44<T>::equalWithRelError (const Matrix44<T> &m, T e) const
2255
for (int i = 0; i < 4; i++)
2256
for (int j = 0; j < 4; j++)
2257
if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
2265
Matrix44<T>::operator += (const Matrix44<T> &v)
2267
x[0][0] += v.x[0][0];
2268
x[0][1] += v.x[0][1];
2269
x[0][2] += v.x[0][2];
2270
x[0][3] += v.x[0][3];
2271
x[1][0] += v.x[1][0];
2272
x[1][1] += v.x[1][1];
2273
x[1][2] += v.x[1][2];
2274
x[1][3] += v.x[1][3];
2275
x[2][0] += v.x[2][0];
2276
x[2][1] += v.x[2][1];
2277
x[2][2] += v.x[2][2];
2278
x[2][3] += v.x[2][3];
2279
x[3][0] += v.x[3][0];
2280
x[3][1] += v.x[3][1];
2281
x[3][2] += v.x[3][2];
2282
x[3][3] += v.x[3][3];
2289
Matrix44<T>::operator += (T a)
2313
Matrix44<T>::operator + (const Matrix44<T> &v) const
2315
return Matrix44 (x[0][0] + v.x[0][0],
2316
x[0][1] + v.x[0][1],
2317
x[0][2] + v.x[0][2],
2318
x[0][3] + v.x[0][3],
2319
x[1][0] + v.x[1][0],
2320
x[1][1] + v.x[1][1],
2321
x[1][2] + v.x[1][2],
2322
x[1][3] + v.x[1][3],
2323
x[2][0] + v.x[2][0],
2324
x[2][1] + v.x[2][1],
2325
x[2][2] + v.x[2][2],
2326
x[2][3] + v.x[2][3],
2327
x[3][0] + v.x[3][0],
2328
x[3][1] + v.x[3][1],
2329
x[3][2] + v.x[3][2],
2330
x[3][3] + v.x[3][3]);
2335
Matrix44<T>::operator -= (const Matrix44<T> &v)
2337
x[0][0] -= v.x[0][0];
2338
x[0][1] -= v.x[0][1];
2339
x[0][2] -= v.x[0][2];
2340
x[0][3] -= v.x[0][3];
2341
x[1][0] -= v.x[1][0];
2342
x[1][1] -= v.x[1][1];
2343
x[1][2] -= v.x[1][2];
2344
x[1][3] -= v.x[1][3];
2345
x[2][0] -= v.x[2][0];
2346
x[2][1] -= v.x[2][1];
2347
x[2][2] -= v.x[2][2];
2348
x[2][3] -= v.x[2][3];
2349
x[3][0] -= v.x[3][0];
2350
x[3][1] -= v.x[3][1];
2351
x[3][2] -= v.x[3][2];
2352
x[3][3] -= v.x[3][3];
2359
Matrix44<T>::operator -= (T a)
2383
Matrix44<T>::operator - (const Matrix44<T> &v) const
2385
return Matrix44 (x[0][0] - v.x[0][0],
2386
x[0][1] - v.x[0][1],
2387
x[0][2] - v.x[0][2],
2388
x[0][3] - v.x[0][3],
2389
x[1][0] - v.x[1][0],
2390
x[1][1] - v.x[1][1],
2391
x[1][2] - v.x[1][2],
2392
x[1][3] - v.x[1][3],
2393
x[2][0] - v.x[2][0],
2394
x[2][1] - v.x[2][1],
2395
x[2][2] - v.x[2][2],
2396
x[2][3] - v.x[2][3],
2397
x[3][0] - v.x[3][0],
2398
x[3][1] - v.x[3][1],
2399
x[3][2] - v.x[3][2],
2400
x[3][3] - v.x[3][3]);
2405
Matrix44<T>::operator - () const
2407
return Matrix44 (-x[0][0],
2427
Matrix44<T>::negate ()
2451
Matrix44<T>::operator *= (T a)
2475
Matrix44<T>::operator * (T a) const
2477
return Matrix44 (x[0][0] * a,
2497
operator * (T a, const Matrix44<T> &v)
2503
inline const Matrix44<T> &
2504
Matrix44<T>::operator *= (const Matrix44<T> &v)
2506
Matrix44 tmp (T (0));
2508
multiply (*this, v, tmp);
2515
Matrix44<T>::operator * (const Matrix44<T> &v) const
2517
Matrix44 tmp (T (0));
2519
multiply (*this, v, tmp);
2525
Matrix44<T>::multiply (const Matrix44<T> &a,
2526
const Matrix44<T> &b,
2529
register const T * IMATH_RESTRICT ap = &a.x[0][0];
2530
register const T * IMATH_RESTRICT bp = &b.x[0][0];
2531
register T * IMATH_RESTRICT cp = &c.x[0][0];
2533
register T a0, a1, a2, a3;
2540
cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2541
cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2542
cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2543
cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2550
cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2551
cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2552
cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2553
cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2560
cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2561
cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2562
cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2563
cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2570
cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2571
cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2572
cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2573
cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2576
template <class T> template <class S>
2578
Matrix44<T>::multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const
2582
a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0] + x[3][0];
2583
b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1] + x[3][1];
2584
c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2] + x[3][2];
2585
w = src[0] * x[0][3] + src[1] * x[1][3] + src[2] * x[2][3] + x[3][3];
2592
template <class T> template <class S>
2594
Matrix44<T>::multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const
2598
a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0];
2599
b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1];
2600
c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2];
2609
Matrix44<T>::operator /= (T a)
2633
Matrix44<T>::operator / (T a) const
2635
return Matrix44 (x[0][0] / a,
2655
Matrix44<T>::transpose ()
2657
Matrix44 tmp (x[0][0],
2679
Matrix44<T>::transposed () const
2681
return Matrix44 (x[0][0],
2701
Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
2703
*this = gjInverse (singExc);
2709
Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
2715
// Forward elimination
2717
for (i = 0; i < 3 ; i++)
2721
T pivotsize = t[i][i];
2724
pivotsize = -pivotsize;
2726
for (j = i + 1; j < 4; j++)
2733
if (tmp > pivotsize)
2743
throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
2750
for (j = 0; j < 4; j++)
2755
t[i][j] = t[pivot][j];
2759
s[i][j] = s[pivot][j];
2764
for (j = i + 1; j < 4; j++)
2766
T f = t[j][i] / t[i][i];
2768
for (k = 0; k < 4; k++)
2770
t[j][k] -= f * t[i][k];
2771
s[j][k] -= f * s[i][k];
2776
// Backward substitution
2778
for (i = 3; i >= 0; --i)
2782
if ((f = t[i][i]) == 0)
2785
throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
2790
for (j = 0; j < 4; j++)
2796
for (j = 0; j < i; j++)
2800
for (k = 0; k < 4; k++)
2802
t[j][k] -= f * t[i][k];
2803
s[j][k] -= f * s[i][k];
2813
Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
2815
*this = inverse (singExc);
2821
Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
2823
if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
2824
return gjInverse(singExc);
2826
Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2827
x[2][1] * x[0][2] - x[0][1] * x[2][2],
2828
x[0][1] * x[1][2] - x[1][1] * x[0][2],
2831
x[2][0] * x[1][2] - x[1][0] * x[2][2],
2832
x[0][0] * x[2][2] - x[2][0] * x[0][2],
2833
x[1][0] * x[0][2] - x[0][0] * x[1][2],
2836
x[1][0] * x[2][1] - x[2][0] * x[1][1],
2837
x[2][0] * x[0][1] - x[0][0] * x[2][1],
2838
x[0][0] * x[1][1] - x[1][0] * x[0][1],
2846
T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
2848
if (Imath::abs (r) >= 1)
2850
for (int i = 0; i < 3; ++i)
2852
for (int j = 0; j < 3; ++j)
2860
T mr = Imath::abs (r) / limits<T>::smallest();
2862
for (int i = 0; i < 3; ++i)
2864
for (int j = 0; j < 3; ++j)
2866
if (mr > Imath::abs (s[i][j]))
2873
throw SingMatrixExc ("Cannot invert singular matrix.");
2881
s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0];
2882
s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1];
2883
s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2];
2890
Matrix44<T>::fastMinor( const int r0, const int r1, const int r2,
2891
const int c0, const int c1, const int c2) const
2893
return x[r0][c0] * (x[r1][c1]*x[r2][c2] - x[r1][c2]*x[r2][c1])
2894
+ x[r0][c1] * (x[r1][c2]*x[r2][c0] - x[r1][c0]*x[r2][c2])
2895
+ x[r0][c2] * (x[r1][c0]*x[r2][c1] - x[r1][c1]*x[r2][c0]);
2900
Matrix44<T>::minorOf (const int r, const int c) const
2902
int r0 = 0 + (r < 1 ? 1 : 0);
2903
int r1 = 1 + (r < 2 ? 1 : 0);
2904
int r2 = 2 + (r < 3 ? 1 : 0);
2905
int c0 = 0 + (c < 1 ? 1 : 0);
2906
int c1 = 1 + (c < 2 ? 1 : 0);
2907
int c2 = 2 + (c < 3 ? 1 : 0);
2909
Matrix33<T> working (x[r0][c0],x[r1][c0],x[r2][c0],
2910
x[r0][c1],x[r1][c1],x[r2][c1],
2911
x[r0][c2],x[r1][c2],x[r2][c2]);
2913
return working.determinant();
2918
Matrix44<T>::determinant () const
2922
if (x[0][3] != 0.) sum -= x[0][3] * fastMinor(1,2,3,0,1,2);
2923
if (x[1][3] != 0.) sum += x[1][3] * fastMinor(0,2,3,0,1,2);
2924
if (x[2][3] != 0.) sum -= x[2][3] * fastMinor(0,1,3,0,1,2);
2925
if (x[3][3] != 0.) sum += x[3][3] * fastMinor(0,1,2,0,1,2);
2933
Matrix44<T>::setEulerAngles (const Vec3<S>& r)
2935
S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
2937
cos_rz = Math<T>::cos (r[2]);
2938
cos_ry = Math<T>::cos (r[1]);
2939
cos_rx = Math<T>::cos (r[0]);
2941
sin_rz = Math<T>::sin (r[2]);
2942
sin_ry = Math<T>::sin (r[1]);
2943
sin_rx = Math<T>::sin (r[0]);
2945
x[0][0] = cos_rz * cos_ry;
2946
x[0][1] = sin_rz * cos_ry;
2950
x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
2951
x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
2952
x[1][2] = cos_ry * sin_rx;
2955
x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;
2956
x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;
2957
x[2][2] = cos_ry * cos_rx;
2971
Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle)
2973
Vec3<S> unit (axis.normalized());
2974
S sine = Math<T>::sin (angle);
2975
S cosine = Math<T>::cos (angle);
2977
x[0][0] = unit[0] * unit[0] * (1 - cosine) + cosine;
2978
x[0][1] = unit[0] * unit[1] * (1 - cosine) + unit[2] * sine;
2979
x[0][2] = unit[0] * unit[2] * (1 - cosine) - unit[1] * sine;
2982
x[1][0] = unit[0] * unit[1] * (1 - cosine) - unit[2] * sine;
2983
x[1][1] = unit[1] * unit[1] * (1 - cosine) + cosine;
2984
x[1][2] = unit[1] * unit[2] * (1 - cosine) + unit[0] * sine;
2987
x[2][0] = unit[0] * unit[2] * (1 - cosine) + unit[1] * sine;
2988
x[2][1] = unit[1] * unit[2] * (1 - cosine) - unit[0] * sine;
2989
x[2][2] = unit[2] * unit[2] * (1 - cosine) + cosine;
3003
Matrix44<T>::rotate (const Vec3<S> &r)
3005
S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
3010
cos_rz = Math<S>::cos (r[2]);
3011
cos_ry = Math<S>::cos (r[1]);
3012
cos_rx = Math<S>::cos (r[0]);
3014
sin_rz = Math<S>::sin (r[2]);
3015
sin_ry = Math<S>::sin (r[1]);
3016
sin_rx = Math<S>::sin (r[0]);
3018
m00 = cos_rz * cos_ry;
3019
m01 = sin_rz * cos_ry;
3021
m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
3022
m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
3023
m12 = cos_ry * sin_rx;
3024
m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx;
3025
m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx;
3026
m22 = cos_ry * cos_rx;
3028
Matrix44<T> P (*this);
3030
x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02;
3031
x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02;
3032
x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02;
3033
x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02;
3035
x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12;
3036
x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12;
3037
x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12;
3038
x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12;
3040
x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22;
3041
x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22;
3042
x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22;
3043
x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22;
3050
Matrix44<T>::setScale (T s)
3052
memset (x, 0, sizeof (x));
3064
Matrix44<T>::setScale (const Vec3<S> &s)
3066
memset (x, 0, sizeof (x));
3078
Matrix44<T>::scale (const Vec3<S> &s)
3101
Matrix44<T>::setTranslation (const Vec3<S> &t)
3127
inline const Vec3<T>
3128
Matrix44<T>::translation () const
3130
return Vec3<T> (x[3][0], x[3][1], x[3][2]);
3136
Matrix44<T>::translate (const Vec3<S> &t)
3138
x[3][0] += t[0] * x[0][0] + t[1] * x[1][0] + t[2] * x[2][0];
3139
x[3][1] += t[0] * x[0][1] + t[1] * x[1][1] + t[2] * x[2][1];
3140
x[3][2] += t[0] * x[0][2] + t[1] * x[1][2] + t[2] * x[2][2];
3141
x[3][3] += t[0] * x[0][3] + t[1] * x[1][3] + t[2] * x[2][3];
3149
Matrix44<T>::setShear (const Vec3<S> &h)
3177
Matrix44<T>::setShear (const Shear6<S> &h)
3205
Matrix44<T>::shear (const Vec3<S> &h)
3208
// In this case, we don't need a temp. copy of the matrix
3209
// because we never use a value on the RHS after we've
3210
// changed it on the LHS.
3213
for (int i=0; i < 4; i++)
3215
x[2][i] += h[1] * x[0][i] + h[2] * x[1][i];
3216
x[1][i] += h[0] * x[0][i];
3225
Matrix44<T>::shear (const Shear6<S> &h)
3227
Matrix44<T> P (*this);
3229
for (int i=0; i < 4; i++)
3231
x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i];
3232
x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i];
3233
x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i];
3240
//--------------------------------
3241
// Implementation of stream output
3242
//--------------------------------
3246
operator << (std::ostream &s, const Matrix33<T> &m)
3248
std::ios_base::fmtflags oldFlags = s.flags();
3251
if (s.flags() & std::ios_base::fixed)
3253
s.setf (std::ios_base::showpoint);
3254
width = s.precision() + 5;
3258
s.setf (std::ios_base::scientific);
3259
s.setf (std::ios_base::showpoint);
3260
width = s.precision() + 8;
3263
s << "(" << std::setw (width) << m[0][0] <<
3264
" " << std::setw (width) << m[0][1] <<
3265
" " << std::setw (width) << m[0][2] << "\n" <<
3267
" " << std::setw (width) << m[1][0] <<
3268
" " << std::setw (width) << m[1][1] <<
3269
" " << std::setw (width) << m[1][2] << "\n" <<
3271
" " << std::setw (width) << m[2][0] <<
3272
" " << std::setw (width) << m[2][1] <<
3273
" " << std::setw (width) << m[2][2] << ")\n";
3281
operator << (std::ostream &s, const Matrix44<T> &m)
3283
std::ios_base::fmtflags oldFlags = s.flags();
3286
if (s.flags() & std::ios_base::fixed)
3288
s.setf (std::ios_base::showpoint);
3289
width = s.precision() + 5;
3293
s.setf (std::ios_base::scientific);
3294
s.setf (std::ios_base::showpoint);
3295
width = s.precision() + 8;
3298
s << "(" << std::setw (width) << m[0][0] <<
3299
" " << std::setw (width) << m[0][1] <<
3300
" " << std::setw (width) << m[0][2] <<
3301
" " << std::setw (width) << m[0][3] << "\n" <<
3303
" " << std::setw (width) << m[1][0] <<
3304
" " << std::setw (width) << m[1][1] <<
3305
" " << std::setw (width) << m[1][2] <<
3306
" " << std::setw (width) << m[1][3] << "\n" <<
3308
" " << std::setw (width) << m[2][0] <<
3309
" " << std::setw (width) << m[2][1] <<
3310
" " << std::setw (width) << m[2][2] <<
3311
" " << std::setw (width) << m[2][3] << "\n" <<
3313
" " << std::setw (width) << m[3][0] <<
3314
" " << std::setw (width) << m[3][1] <<
3315
" " << std::setw (width) << m[3][2] <<
3316
" " << std::setw (width) << m[3][3] << ")\n";
3323
//---------------------------------------------------------------
3324
// Implementation of vector-times-matrix multiplication operators
3325
//---------------------------------------------------------------
3327
template <class S, class T>
3328
inline const Vec2<S> &
3329
operator *= (Vec2<S> &v, const Matrix33<T> &m)
3331
S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
3332
S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
3333
S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
3341
template <class S, class T>
3343
operator * (const Vec2<S> &v, const Matrix33<T> &m)
3345
S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
3346
S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
3347
S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
3349
return Vec2<S> (x / w, y / w);
3353
template <class S, class T>
3354
inline const Vec3<S> &
3355
operator *= (Vec3<S> &v, const Matrix33<T> &m)
3357
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
3358
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
3359
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
3368
template <class S, class T>
3370
operator * (const Vec3<S> &v, const Matrix33<T> &m)
3372
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
3373
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
3374
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
3376
return Vec3<S> (x, y, z);
3380
template <class S, class T>
3381
inline const Vec3<S> &
3382
operator *= (Vec3<S> &v, const Matrix44<T> &m)
3384
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
3385
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
3386
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
3387
S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
3396
template <class S, class T>
3398
operator * (const Vec3<S> &v, const Matrix44<T> &m)
3400
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
3401
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
3402
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
3403
S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
3405
return Vec3<S> (x / w, y / w, z / w);
3409
template <class S, class T>
3410
inline const Vec4<S> &
3411
operator *= (Vec4<S> &v, const Matrix44<T> &m)
3413
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
3414
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
3415
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
3416
S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
3426
template <class S, class T>
3428
operator * (const Vec4<S> &v, const Matrix44<T> &m)
3430
S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
3431
S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
3432
S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
3433
S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
3435
return Vec4<S> (x, y, z, w);
3438
} // namespace Imath