Rumba C++ SDK
ImathMatrix.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
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
16 // distribution.
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.
20 //
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.
32 //
34 
35 
36 
37 #ifndef INCLUDED_IMATHMATRIX_H
38 #define INCLUDED_IMATHMATRIX_H
39 
40 //----------------------------------------------------------------
41 //
42 // 2D (3x3) and 3D (4x4) transformation matrix templates.
43 //
44 //----------------------------------------------------------------
45 
46 #include "ImathPlatform.h"
47 #include "ImathFun.h"
48 #include "ImathExc.h"
49 #include "ImathVec.h"
50 #include "ImathShear.h"
51 
52 #include <iostream>
53 #include <iomanip>
54 
55 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
56 // suppress exception specification warnings
57 #pragma warning(disable:4290)
58 #endif
59 
60 
61 namespace Imath {
62 
64 
65 
66 template <class T> class Matrix33
67 {
68  public:
69 
70  //-------------------
71  // Access to elements
72  //-------------------
73 
74  T x[3][3];
75 
76  T * operator [] (int i);
77  const T * operator [] (int i) const;
78 
79 
80  //-------------
81  // Constructors
82  //-------------
83 
85 
86  Matrix33 ();
87  // 1 0 0
88  // 0 1 0
89  // 0 0 1
90 
91  Matrix33 (T a);
92  // a a a
93  // a a a
94  // a a a
95 
96  Matrix33 (const T a[3][3]);
97  // a[0][0] a[0][1] a[0][2]
98  // a[1][0] a[1][1] a[1][2]
99  // a[2][0] a[2][1] a[2][2]
100 
101  Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i);
102 
103  // a b c
104  // d e f
105  // g h i
106 
107 
108  //--------------------------------
109  // Copy constructor and assignment
110  //--------------------------------
111 
112  Matrix33 (const Matrix33 &v);
113  template <class S> explicit Matrix33 (const Matrix33<S> &v);
114 
115  const Matrix33 & operator = (const Matrix33 &v);
116  const Matrix33 & operator = (T a);
117 
118 
119  //----------------------
120  // Compatibility with Sb
121  //----------------------
122 
123  T * getValue ();
124  const T * getValue () const;
125 
126  template <class S>
127  void getValue (Matrix33<S> &v) const;
128  template <class S>
129  Matrix33 & setValue (const Matrix33<S> &v);
130 
131  template <class S>
132  Matrix33 & setTheMatrix (const Matrix33<S> &v);
133 
134 
135  //---------
136  // Identity
137  //---------
138 
139  void makeIdentity();
140 
141 
142  //---------
143  // Equality
144  //---------
145 
146  bool operator == (const Matrix33 &v) const;
147  bool operator != (const Matrix33 &v) const;
148 
149  //-----------------------------------------------------------------------
150  // Compare two matrices and test if they are "approximately equal":
151  //
152  // equalWithAbsError (m, e)
153  //
154  // Returns true if the coefficients of this and m are the same with
155  // an absolute error of no more than e, i.e., for all i, j
156  //
157  // abs (this[i][j] - m[i][j]) <= e
158  //
159  // equalWithRelError (m, e)
160  //
161  // Returns true if the coefficients of this and m are the same with
162  // a relative error of no more than e, i.e., for all i, j
163  //
164  // abs (this[i] - v[i][j]) <= e * abs (this[i][j])
165  //-----------------------------------------------------------------------
166 
167  bool equalWithAbsError (const Matrix33<T> &v, T e) const;
168  bool equalWithRelError (const Matrix33<T> &v, T e) const;
169 
170 
171  //------------------------
172  // Component-wise addition
173  //------------------------
174 
175  const Matrix33 & operator += (const Matrix33 &v);
176  const Matrix33 & operator += (T a);
177  Matrix33 operator + (const Matrix33 &v) const;
178 
179 
180  //---------------------------
181  // Component-wise subtraction
182  //---------------------------
183 
184  const Matrix33 & operator -= (const Matrix33 &v);
185  const Matrix33 & operator -= (T a);
186  Matrix33 operator - (const Matrix33 &v) const;
187 
188 
189  //------------------------------------
190  // Component-wise multiplication by -1
191  //------------------------------------
192 
193  Matrix33 operator - () const;
194  const Matrix33 & negate ();
195 
196 
197  //------------------------------
198  // Component-wise multiplication
199  //------------------------------
200 
201  const Matrix33 & operator *= (T a);
202  Matrix33 operator * (T a) const;
203 
204 
205  //-----------------------------------
206  // Matrix-times-matrix multiplication
207  //-----------------------------------
208 
209  const Matrix33 & operator *= (const Matrix33 &v);
210  Matrix33 operator * (const Matrix33 &v) const;
211 
212 
213  //-----------------------------------------------------------------
214  // Vector-times-matrix multiplication; see also the "operator *"
215  // functions defined below.
216  //
217  // m.multVecMatrix(src,dst) implements a homogeneous transformation
218  // by computing Vec3 (src.x, src.y, 1) * m and dividing by the
219  // result's third element.
220  //
221  // m.multDirMatrix(src,dst) multiplies src by the upper left 2x2
222  // submatrix, ignoring the rest of matrix m.
223  //-----------------------------------------------------------------
224 
225  template <class S>
226  void multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const;
227 
228  template <class S>
229  void multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const;
230 
231 
232  //------------------------
233  // Component-wise division
234  //------------------------
235 
236  const Matrix33 & operator /= (T a);
237  Matrix33 operator / (T a) const;
238 
239 
240  //------------------
241  // Transposed matrix
242  //------------------
243 
244  const Matrix33 & transpose ();
245  Matrix33 transposed () const;
246 
247 
248  //------------------------------------------------------------
249  // Inverse matrix: If singExc is false, inverting a singular
250  // matrix produces an identity matrix. If singExc is true,
251  // inverting a singular matrix throws a SingMatrixExc.
252  //
253  // inverse() and invert() invert matrices using determinants;
254  // gjInverse() and gjInvert() use the Gauss-Jordan method.
255  //
256  // inverse() and invert() are significantly faster than
257  // gjInverse() and gjInvert(), but the results may be slightly
258  // less accurate.
259  //
260  //------------------------------------------------------------
261 
262  const Matrix33 & invert (bool singExc = false)
263  throw (Iex::MathExc);
264 
265  Matrix33<T> inverse (bool singExc = false) const
266  throw (Iex::MathExc);
267 
268  const Matrix33 & gjInvert (bool singExc = false)
269  throw (Iex::MathExc);
270 
271  Matrix33<T> gjInverse (bool singExc = false) const
272  throw (Iex::MathExc);
273 
274 
275  //-----------------------------------------
276  // Set matrix to rotation by r (in radians)
277  //-----------------------------------------
278 
279  template <class S>
280  const Matrix33 & setRotation (S r);
281 
282 
283  //-----------------------------
284  // Rotate the given matrix by r
285  //-----------------------------
286 
287  template <class S>
288  const Matrix33 & rotate (S r);
289 
290 
291  //--------------------------------------------
292  // Set matrix to scale by given uniform factor
293  //--------------------------------------------
294 
295  const Matrix33 & setScale (T s);
296 
297 
298  //------------------------------------
299  // Set matrix to scale by given vector
300  //------------------------------------
301 
302  template <class S>
303  const Matrix33 & setScale (const Vec2<S> &s);
304 
305 
306  //----------------------
307  // Scale the matrix by s
308  //----------------------
309 
310  template <class S>
311  const Matrix33 & scale (const Vec2<S> &s);
312 
313 
314  //------------------------------------------
315  // Set matrix to translation by given vector
316  //------------------------------------------
317 
318  template <class S>
319  const Matrix33 & setTranslation (const Vec2<S> &t);
320 
321 
322  //-----------------------------
323  // Return translation component
324  //-----------------------------
325 
326  Vec2<T> translation () const;
327 
328 
329  //--------------------------
330  // Translate the matrix by t
331  //--------------------------
332 
333  template <class S>
334  const Matrix33 & translate (const Vec2<S> &t);
335 
336 
337  //-----------------------------------------------------------
338  // Set matrix to shear x for each y coord. by given factor xy
339  //-----------------------------------------------------------
340 
341  template <class S>
342  const Matrix33 & setShear (const S &h);
343 
344 
345  //-------------------------------------------------------------
346  // Set matrix to shear x for each y coord. by given factor h[0]
347  // and to shear y for each x coord. by given factor h[1]
348  //-------------------------------------------------------------
349 
350  template <class S>
351  const Matrix33 & setShear (const Vec2<S> &h);
352 
353 
354  //-----------------------------------------------------------
355  // Shear the matrix in x for each y coord. by given factor xy
356  //-----------------------------------------------------------
357 
358  template <class S>
359  const Matrix33 & shear (const S &xy);
360 
361 
362  //-----------------------------------------------------------
363  // Shear the matrix in x for each y coord. by given factor xy
364  // and shear y for each x coord. by given factor yx
365  //-----------------------------------------------------------
366 
367  template <class S>
368  const Matrix33 & shear (const Vec2<S> &h);
369 
370 
371  //-------------------------------------------------
372  // Limitations of type T (see also class limits<T>)
373  //-------------------------------------------------
374 
375  static T baseTypeMin() {return limits<T>::min();}
376  static T baseTypeMax() {return limits<T>::max();}
377  static T baseTypeSmallest() {return limits<T>::smallest();}
378  static T baseTypeEpsilon() {return limits<T>::epsilon();}
379 
380  private:
381 
382  template <typename R, typename S>
383  struct isSameType
384  {
385  enum {value = 0};
386  };
387 
388  template <typename R>
389  struct isSameType<R, R>
390  {
391  enum {value = 1};
392  };
393 };
394 
395 
396 template <class T> class Matrix44
397 {
398  public:
399 
400  //-------------------
401  // Access to elements
402  //-------------------
403 
404  T x[4][4];
405 
406  T * operator [] (int i);
407  const T * operator [] (int i) const;
408 
409 
410  //-------------
411  // Constructors
412  //-------------
413 
415 
416  Matrix44 ();
417  // 1 0 0 0
418  // 0 1 0 0
419  // 0 0 1 0
420  // 0 0 0 1
421 
422  Matrix44 (T a);
423  // a a a a
424  // a a a a
425  // a a a a
426  // a a a a
427 
428  Matrix44 (const T a[4][4]) ;
429  // a[0][0] a[0][1] a[0][2] a[0][3]
430  // a[1][0] a[1][1] a[1][2] a[1][3]
431  // a[2][0] a[2][1] a[2][2] a[2][3]
432  // a[3][0] a[3][1] a[3][2] a[3][3]
433 
434  Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,
435  T i, T j, T k, T l, T m, T n, T o, T p);
436 
437  // a b c d
438  // e f g h
439  // i j k l
440  // m n o p
441 
443  // r r r 0
444  // r r r 0
445  // r r r 0
446  // t t t 1
447 
448 
449  //--------------------------------
450  // Copy constructor and assignment
451  //--------------------------------
452 
453  Matrix44 (const Matrix44 &v);
454  template <class S> explicit Matrix44 (const Matrix44<S> &v);
455 
456  const Matrix44 & operator = (const Matrix44 &v);
457  const Matrix44 & operator = (T a);
458 
459 
460  //----------------------
461  // Compatibility with Sb
462  //----------------------
463 
464  T * getValue ();
465  const T * getValue () const;
466 
467  template <class S>
468  void getValue (Matrix44<S> &v) const;
469  template <class S>
470  Matrix44 & setValue (const Matrix44<S> &v);
471 
472  template <class S>
473  Matrix44 & setTheMatrix (const Matrix44<S> &v);
474 
475  //---------
476  // Identity
477  //---------
478 
479  void makeIdentity();
480 
481 
482  //---------
483  // Equality
484  //---------
485 
486  bool operator == (const Matrix44 &v) const;
487  bool operator != (const Matrix44 &v) const;
488 
489  //-----------------------------------------------------------------------
490  // Compare two matrices and test if they are "approximately equal":
491  //
492  // equalWithAbsError (m, e)
493  //
494  // Returns true if the coefficients of this and m are the same with
495  // an absolute error of no more than e, i.e., for all i, j
496  //
497  // abs (this[i][j] - m[i][j]) <= e
498  //
499  // equalWithRelError (m, e)
500  //
501  // Returns true if the coefficients of this and m are the same with
502  // a relative error of no more than e, i.e., for all i, j
503  //
504  // abs (this[i] - v[i][j]) <= e * abs (this[i][j])
505  //-----------------------------------------------------------------------
506 
507  bool equalWithAbsError (const Matrix44<T> &v, T e) const;
508  bool equalWithRelError (const Matrix44<T> &v, T e) const;
509 
510 
511  //------------------------
512  // Component-wise addition
513  //------------------------
514 
515  const Matrix44 & operator += (const Matrix44 &v);
516  const Matrix44 & operator += (T a);
517  Matrix44 operator + (const Matrix44 &v) const;
518 
519 
520  //---------------------------
521  // Component-wise subtraction
522  //---------------------------
523 
524  const Matrix44 & operator -= (const Matrix44 &v);
525  const Matrix44 & operator -= (T a);
526  Matrix44 operator - (const Matrix44 &v) const;
527 
528 
529  //------------------------------------
530  // Component-wise multiplication by -1
531  //------------------------------------
532 
533  Matrix44 operator - () const;
534  const Matrix44 & negate ();
535 
536 
537  //------------------------------
538  // Component-wise multiplication
539  //------------------------------
540 
541  const Matrix44 & operator *= (T a);
542  Matrix44 operator * (T a) const;
543 
544 
545  //-----------------------------------
546  // Matrix-times-matrix multiplication
547  //-----------------------------------
548 
549  const Matrix44 & operator *= (const Matrix44 &v);
550  Matrix44 operator * (const Matrix44 &v) const;
551 
552  static void multiply (const Matrix44 &a, // assumes that
553  const Matrix44 &b, // &a != &c and
554  Matrix44 &c); // &b != &c.
555 
556 
557  //-----------------------------------------------------------------
558  // Vector-times-matrix multiplication; see also the "operator *"
559  // functions defined below.
560  //
561  // m.multVecMatrix(src,dst) implements a homogeneous transformation
562  // by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by
563  // the result's third element.
564  //
565  // m.multDirMatrix(src,dst) multiplies src by the upper left 3x3
566  // submatrix, ignoring the rest of matrix m.
567  //-----------------------------------------------------------------
568 
569  template <class S>
570  void multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const;
571 
572  template <class S>
573  void multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const;
574 
575 
576  //------------------------
577  // Component-wise division
578  //------------------------
579 
580  const Matrix44 & operator /= (T a);
581  Matrix44 operator / (T a) const;
582 
583 
584  //------------------
585  // Transposed matrix
586  //------------------
587 
588  const Matrix44 & transpose ();
589  Matrix44 transposed () const;
590 
591 
592  //------------------------------------------------------------
593  // Inverse matrix: If singExc is false, inverting a singular
594  // matrix produces an identity matrix. If singExc is true,
595  // inverting a singular matrix throws a SingMatrixExc.
596  //
597  // inverse() and invert() invert matrices using determinants;
598  // gjInverse() and gjInvert() use the Gauss-Jordan method.
599  //
600  // inverse() and invert() are significantly faster than
601  // gjInverse() and gjInvert(), but the results may be slightly
602  // less accurate.
603  //
604  //------------------------------------------------------------
605 
606  const Matrix44 & invert (bool singExc = false)
607  throw (Iex::MathExc);
608 
609  Matrix44<T> inverse (bool singExc = false) const
610  throw (Iex::MathExc);
611 
612  const Matrix44 & gjInvert (bool singExc = false)
613  throw (Iex::MathExc);
614 
615  Matrix44<T> gjInverse (bool singExc = false) const
616  throw (Iex::MathExc);
617 
618 
619  //--------------------------------------------------------
620  // Set matrix to rotation by XYZ euler angles (in radians)
621  //--------------------------------------------------------
622 
623  template <class S>
624  const Matrix44 & setEulerAngles (const Vec3<S>& r);
625 
626 
627  //--------------------------------------------------------
628  // Set matrix to rotation around given axis by given angle
629  //--------------------------------------------------------
630 
631  template <class S>
632  const Matrix44 & setAxisAngle (const Vec3<S>& ax, S ang);
633 
634 
635  //-------------------------------------------
636  // Rotate the matrix by XYZ euler angles in r
637  //-------------------------------------------
638 
639  template <class S>
640  const Matrix44 & rotate (const Vec3<S> &r);
641 
642 
643  //--------------------------------------------
644  // Set matrix to scale by given uniform factor
645  //--------------------------------------------
646 
647  const Matrix44 & setScale (T s);
648 
649 
650  //------------------------------------
651  // Set matrix to scale by given vector
652  //------------------------------------
653 
654  template <class S>
655  const Matrix44 & setScale (const Vec3<S> &s);
656 
657 
658  //----------------------
659  // Scale the matrix by s
660  //----------------------
661 
662  template <class S>
663  const Matrix44 & scale (const Vec3<S> &s);
664 
665 
666  //------------------------------------------
667  // Set matrix to translation by given vector
668  //------------------------------------------
669 
670  template <class S>
671  const Matrix44 & setTranslation (const Vec3<S> &t);
672 
673 
674  //-----------------------------
675  // Return translation component
676  //-----------------------------
677 
678  const Vec3<T> translation () const;
679 
680 
681  //--------------------------
682  // Translate the matrix by t
683  //--------------------------
684 
685  template <class S>
686  const Matrix44 & translate (const Vec3<S> &t);
687 
688 
689  //-------------------------------------------------------------
690  // Set matrix to shear by given vector h. The resulting matrix
691  // will shear x for each y coord. by a factor of h[0] ;
692  // will shear x for each z coord. by a factor of h[1] ;
693  // will shear y for each z coord. by a factor of h[2] .
694  //-------------------------------------------------------------
695 
696  template <class S>
697  const Matrix44 & setShear (const Vec3<S> &h);
698 
699 
700  //------------------------------------------------------------
701  // Set matrix to shear by given factors. The resulting matrix
702  // will shear x for each y coord. by a factor of h.xy ;
703  // will shear x for each z coord. by a factor of h.xz ;
704  // will shear y for each z coord. by a factor of h.yz ;
705  // will shear y for each x coord. by a factor of h.yx ;
706  // will shear z for each x coord. by a factor of h.zx ;
707  // will shear z for each y coord. by a factor of h.zy .
708  //------------------------------------------------------------
709 
710  template <class S>
711  const Matrix44 & setShear (const Shear6<S> &h);
712 
713 
714  //--------------------------------------------------------
715  // Shear the matrix by given vector. The composed matrix
716  // will be <shear> * <this>, where the shear matrix ...
717  // will shear x for each y coord. by a factor of h[0] ;
718  // will shear x for each z coord. by a factor of h[1] ;
719  // will shear y for each z coord. by a factor of h[2] .
720  //--------------------------------------------------------
721 
722  template <class S>
723  const Matrix44 & shear (const Vec3<S> &h);
724 
725 
726  //------------------------------------------------------------
727  // Shear the matrix by the given factors. The composed matrix
728  // will be <shear> * <this>, where the shear matrix ...
729  // will shear x for each y coord. by a factor of h.xy ;
730  // will shear x for each z coord. by a factor of h.xz ;
731  // will shear y for each z coord. by a factor of h.yz ;
732  // will shear y for each x coord. by a factor of h.yx ;
733  // will shear z for each x coord. by a factor of h.zx ;
734  // will shear z for each y coord. by a factor of h.zy .
735  //------------------------------------------------------------
736 
737  template <class S>
738  const Matrix44 & shear (const Shear6<S> &h);
739 
740 
741  //-------------------------------------------------
742  // Limitations of type T (see also class limits<T>)
743  //-------------------------------------------------
744 
745  static T baseTypeMin() {return limits<T>::min();}
746  static T baseTypeMax() {return limits<T>::max();}
747  static T baseTypeSmallest() {return limits<T>::smallest();}
748  static T baseTypeEpsilon() {return limits<T>::epsilon();}
749 
750  private:
751 
752  template <typename R, typename S>
753  struct isSameType
754  {
755  enum {value = 0};
756  };
757 
758  template <typename R>
759  struct isSameType<R, R>
760  {
761  enum {value = 1};
762  };
763 };
764 
765 
766 //--------------
767 // Stream output
768 //--------------
769 
770 template <class T>
771 std::ostream & operator << (std::ostream & s, const Matrix33<T> &m);
772 
773 template <class T>
774 std::ostream & operator << (std::ostream & s, const Matrix44<T> &m);
775 
776 
777 //---------------------------------------------
778 // Vector-times-matrix multiplication operators
779 //---------------------------------------------
780 
781 template <class S, class T>
782 const Vec2<S> & operator *= (Vec2<S> &v, const Matrix33<T> &m);
783 
784 template <class S, class T>
785 Vec2<S> operator * (const Vec2<S> &v, const Matrix33<T> &m);
786 
787 template <class S, class T>
788 const Vec3<S> & operator *= (Vec3<S> &v, const Matrix33<T> &m);
789 
790 template <class S, class T>
791 Vec3<S> operator * (const Vec3<S> &v, const Matrix33<T> &m);
792 
793 template <class S, class T>
794 const Vec3<S> & operator *= (Vec3<S> &v, const Matrix44<T> &m);
795 
796 template <class S, class T>
797 Vec3<S> operator * (const Vec3<S> &v, const Matrix44<T> &m);
798 
799 template <class S, class T>
800 const Vec4<S> & operator *= (Vec4<S> &v, const Matrix44<T> &m);
801 
802 template <class S, class T>
803 Vec4<S> operator * (const Vec4<S> &v, const Matrix44<T> &m);
804 
805 //-------------------------
806 // Typedefs for convenience
807 //-------------------------
808 
813 
814 
815 //---------------------------
816 // Implementation of Matrix33
817 //---------------------------
818 
819 template <class T>
820 inline T *
822 {
823  return x[i];
824 }
825 
826 template <class T>
827 inline const T *
829 {
830  return x[i];
831 }
832 
833 template <class T>
834 inline
836 {
837  memset (x, 0, sizeof (x));
838  x[0][0] = 1;
839  x[1][1] = 1;
840  x[2][2] = 1;
841 }
842 
843 template <class T>
844 inline
846 {
847  x[0][0] = a;
848  x[0][1] = a;
849  x[0][2] = a;
850  x[1][0] = a;
851  x[1][1] = a;
852  x[1][2] = a;
853  x[2][0] = a;
854  x[2][1] = a;
855  x[2][2] = a;
856 }
857 
858 template <class T>
859 inline
860 Matrix33<T>::Matrix33 (const T a[3][3])
861 {
862  memcpy (x, a, sizeof (x));
863 }
864 
865 template <class T>
866 inline
867 Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i)
868 {
869  x[0][0] = a;
870  x[0][1] = b;
871  x[0][2] = c;
872  x[1][0] = d;
873  x[1][1] = e;
874  x[1][2] = f;
875  x[2][0] = g;
876  x[2][1] = h;
877  x[2][2] = i;
878 }
879 
880 template <class T>
881 inline
883 {
884  memcpy (x, v.x, sizeof (x));
885 }
886 
887 template <class T>
888 template <class S>
889 inline
891 {
892  x[0][0] = T (v.x[0][0]);
893  x[0][1] = T (v.x[0][1]);
894  x[0][2] = T (v.x[0][2]);
895  x[1][0] = T (v.x[1][0]);
896  x[1][1] = T (v.x[1][1]);
897  x[1][2] = T (v.x[1][2]);
898  x[2][0] = T (v.x[2][0]);
899  x[2][1] = T (v.x[2][1]);
900  x[2][2] = T (v.x[2][2]);
901 }
902 
903 template <class T>
904 inline const Matrix33<T> &
906 {
907  memcpy (x, v.x, sizeof (x));
908  return *this;
909 }
910 
911 template <class T>
912 inline const Matrix33<T> &
914 {
915  x[0][0] = a;
916  x[0][1] = a;
917  x[0][2] = a;
918  x[1][0] = a;
919  x[1][1] = a;
920  x[1][2] = a;
921  x[2][0] = a;
922  x[2][1] = a;
923  x[2][2] = a;
924  return *this;
925 }
926 
927 template <class T>
928 inline T *
930 {
931  return (T *) &x[0][0];
932 }
933 
934 template <class T>
935 inline const T *
937 {
938  return (const T *) &x[0][0];
939 }
940 
941 template <class T>
942 template <class S>
943 inline void
945 {
946  if (isSameType<S,T>::value)
947  {
948  memcpy (v.x, x, sizeof (x));
949  }
950  else
951  {
952  v.x[0][0] = x[0][0];
953  v.x[0][1] = x[0][1];
954  v.x[0][2] = x[0][2];
955  v.x[1][0] = x[1][0];
956  v.x[1][1] = x[1][1];
957  v.x[1][2] = x[1][2];
958  v.x[2][0] = x[2][0];
959  v.x[2][1] = x[2][1];
960  v.x[2][2] = x[2][2];
961  }
962 }
963 
964 template <class T>
965 template <class S>
966 inline Matrix33<T> &
968 {
969  if (isSameType<S,T>::value)
970  {
971  memcpy (x, v.x, sizeof (x));
972  }
973  else
974  {
975  x[0][0] = v.x[0][0];
976  x[0][1] = v.x[0][1];
977  x[0][2] = v.x[0][2];
978  x[1][0] = v.x[1][0];
979  x[1][1] = v.x[1][1];
980  x[1][2] = v.x[1][2];
981  x[2][0] = v.x[2][0];
982  x[2][1] = v.x[2][1];
983  x[2][2] = v.x[2][2];
984  }
985 
986  return *this;
987 }
988 
989 template <class T>
990 template <class S>
991 inline Matrix33<T> &
993 {
994  if (isSameType<S,T>::value)
995  {
996  memcpy (x, v.x, sizeof (x));
997  }
998  else
999  {
1000  x[0][0] = v.x[0][0];
1001  x[0][1] = v.x[0][1];
1002  x[0][2] = v.x[0][2];
1003  x[1][0] = v.x[1][0];
1004  x[1][1] = v.x[1][1];
1005  x[1][2] = v.x[1][2];
1006  x[2][0] = v.x[2][0];
1007  x[2][1] = v.x[2][1];
1008  x[2][2] = v.x[2][2];
1009  }
1010 
1011  return *this;
1012 }
1013 
1014 template <class T>
1015 inline void
1017 {
1018  memset (x, 0, sizeof (x));
1019  x[0][0] = 1;
1020  x[1][1] = 1;
1021  x[2][2] = 1;
1022 }
1023 
1024 template <class T>
1025 bool
1027 {
1028  return x[0][0] == v.x[0][0] &&
1029  x[0][1] == v.x[0][1] &&
1030  x[0][2] == v.x[0][2] &&
1031  x[1][0] == v.x[1][0] &&
1032  x[1][1] == v.x[1][1] &&
1033  x[1][2] == v.x[1][2] &&
1034  x[2][0] == v.x[2][0] &&
1035  x[2][1] == v.x[2][1] &&
1036  x[2][2] == v.x[2][2];
1037 }
1038 
1039 template <class T>
1040 bool
1042 {
1043  return x[0][0] != v.x[0][0] ||
1044  x[0][1] != v.x[0][1] ||
1045  x[0][2] != v.x[0][2] ||
1046  x[1][0] != v.x[1][0] ||
1047  x[1][1] != v.x[1][1] ||
1048  x[1][2] != v.x[1][2] ||
1049  x[2][0] != v.x[2][0] ||
1050  x[2][1] != v.x[2][1] ||
1051  x[2][2] != v.x[2][2];
1052 }
1053 
1054 template <class T>
1055 bool
1057 {
1058  for (int i = 0; i < 3; i++)
1059  for (int j = 0; j < 3; j++)
1060  if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
1061  return false;
1062 
1063  return true;
1064 }
1065 
1066 template <class T>
1067 bool
1069 {
1070  for (int i = 0; i < 3; i++)
1071  for (int j = 0; j < 3; j++)
1072  if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
1073  return false;
1074 
1075  return true;
1076 }
1077 
1078 template <class T>
1079 const Matrix33<T> &
1081 {
1082  x[0][0] += v.x[0][0];
1083  x[0][1] += v.x[0][1];
1084  x[0][2] += v.x[0][2];
1085  x[1][0] += v.x[1][0];
1086  x[1][1] += v.x[1][1];
1087  x[1][2] += v.x[1][2];
1088  x[2][0] += v.x[2][0];
1089  x[2][1] += v.x[2][1];
1090  x[2][2] += v.x[2][2];
1091 
1092  return *this;
1093 }
1094 
1095 template <class T>
1096 const Matrix33<T> &
1098 {
1099  x[0][0] += a;
1100  x[0][1] += a;
1101  x[0][2] += a;
1102  x[1][0] += a;
1103  x[1][1] += a;
1104  x[1][2] += a;
1105  x[2][0] += a;
1106  x[2][1] += a;
1107  x[2][2] += a;
1108 
1109  return *this;
1110 }
1111 
1112 template <class T>
1115 {
1116  return Matrix33 (x[0][0] + v.x[0][0],
1117  x[0][1] + v.x[0][1],
1118  x[0][2] + v.x[0][2],
1119  x[1][0] + v.x[1][0],
1120  x[1][1] + v.x[1][1],
1121  x[1][2] + v.x[1][2],
1122  x[2][0] + v.x[2][0],
1123  x[2][1] + v.x[2][1],
1124  x[2][2] + v.x[2][2]);
1125 }
1126 
1127 template <class T>
1128 const Matrix33<T> &
1130 {
1131  x[0][0] -= v.x[0][0];
1132  x[0][1] -= v.x[0][1];
1133  x[0][2] -= v.x[0][2];
1134  x[1][0] -= v.x[1][0];
1135  x[1][1] -= v.x[1][1];
1136  x[1][2] -= v.x[1][2];
1137  x[2][0] -= v.x[2][0];
1138  x[2][1] -= v.x[2][1];
1139  x[2][2] -= v.x[2][2];
1140 
1141  return *this;
1142 }
1143 
1144 template <class T>
1145 const Matrix33<T> &
1147 {
1148  x[0][0] -= a;
1149  x[0][1] -= a;
1150  x[0][2] -= a;
1151  x[1][0] -= a;
1152  x[1][1] -= a;
1153  x[1][2] -= a;
1154  x[2][0] -= a;
1155  x[2][1] -= a;
1156  x[2][2] -= a;
1157 
1158  return *this;
1159 }
1160 
1161 template <class T>
1164 {
1165  return Matrix33 (x[0][0] - v.x[0][0],
1166  x[0][1] - v.x[0][1],
1167  x[0][2] - v.x[0][2],
1168  x[1][0] - v.x[1][0],
1169  x[1][1] - v.x[1][1],
1170  x[1][2] - v.x[1][2],
1171  x[2][0] - v.x[2][0],
1172  x[2][1] - v.x[2][1],
1173  x[2][2] - v.x[2][2]);
1174 }
1175 
1176 template <class T>
1179 {
1180  return Matrix33 (-x[0][0],
1181  -x[0][1],
1182  -x[0][2],
1183  -x[1][0],
1184  -x[1][1],
1185  -x[1][2],
1186  -x[2][0],
1187  -x[2][1],
1188  -x[2][2]);
1189 }
1190 
1191 template <class T>
1192 const Matrix33<T> &
1194 {
1195  x[0][0] = -x[0][0];
1196  x[0][1] = -x[0][1];
1197  x[0][2] = -x[0][2];
1198  x[1][0] = -x[1][0];
1199  x[1][1] = -x[1][1];
1200  x[1][2] = -x[1][2];
1201  x[2][0] = -x[2][0];
1202  x[2][1] = -x[2][1];
1203  x[2][2] = -x[2][2];
1204 
1205  return *this;
1206 }
1207 
1208 template <class T>
1209 const Matrix33<T> &
1211 {
1212  x[0][0] *= a;
1213  x[0][1] *= a;
1214  x[0][2] *= a;
1215  x[1][0] *= a;
1216  x[1][1] *= a;
1217  x[1][2] *= a;
1218  x[2][0] *= a;
1219  x[2][1] *= a;
1220  x[2][2] *= a;
1221 
1222  return *this;
1223 }
1224 
1225 template <class T>
1228 {
1229  return Matrix33 (x[0][0] * a,
1230  x[0][1] * a,
1231  x[0][2] * a,
1232  x[1][0] * a,
1233  x[1][1] * a,
1234  x[1][2] * a,
1235  x[2][0] * a,
1236  x[2][1] * a,
1237  x[2][2] * a);
1238 }
1239 
1240 template <class T>
1241 inline Matrix33<T>
1242 operator * (T a, const Matrix33<T> &v)
1243 {
1244  return v * a;
1245 }
1246 
1247 template <class T>
1248 const Matrix33<T> &
1250 {
1251  Matrix33 tmp (T (0));
1252 
1253  for (int i = 0; i < 3; i++)
1254  for (int j = 0; j < 3; j++)
1255  for (int k = 0; k < 3; k++)
1256  tmp.x[i][j] += x[i][k] * v.x[k][j];
1257 
1258  *this = tmp;
1259  return *this;
1260 }
1261 
1262 template <class T>
1265 {
1266  Matrix33 tmp (T (0));
1267 
1268  for (int i = 0; i < 3; i++)
1269  for (int j = 0; j < 3; j++)
1270  for (int k = 0; k < 3; k++)
1271  tmp.x[i][j] += x[i][k] * v.x[k][j];
1272 
1273  return tmp;
1274 }
1275 
1276 template <class T>
1277 template <class S>
1278 void
1280 {
1281  S a, b, w;
1282 
1283  a = src[0] * x[0][0] + src[1] * x[1][0] + x[2][0];
1284  b = src[0] * x[0][1] + src[1] * x[1][1] + x[2][1];
1285  w = src[0] * x[0][2] + src[1] * x[1][2] + x[2][2];
1286 
1287  dst.x = a / w;
1288  dst.y = b / w;
1289 }
1290 
1291 template <class T>
1292 template <class S>
1293 void
1295 {
1296  S a, b;
1297 
1298  a = src[0] * x[0][0] + src[1] * x[1][0];
1299  b = src[0] * x[0][1] + src[1] * x[1][1];
1300 
1301  dst.x = a;
1302  dst.y = b;
1303 }
1304 
1305 template <class T>
1306 const Matrix33<T> &
1308 {
1309  x[0][0] /= a;
1310  x[0][1] /= a;
1311  x[0][2] /= a;
1312  x[1][0] /= a;
1313  x[1][1] /= a;
1314  x[1][2] /= a;
1315  x[2][0] /= a;
1316  x[2][1] /= a;
1317  x[2][2] /= a;
1318 
1319  return *this;
1320 }
1321 
1322 template <class T>
1325 {
1326  return Matrix33 (x[0][0] / a,
1327  x[0][1] / a,
1328  x[0][2] / a,
1329  x[1][0] / a,
1330  x[1][1] / a,
1331  x[1][2] / a,
1332  x[2][0] / a,
1333  x[2][1] / a,
1334  x[2][2] / a);
1335 }
1336 
1337 template <class T>
1338 const Matrix33<T> &
1340 {
1341  Matrix33 tmp (x[0][0],
1342  x[1][0],
1343  x[2][0],
1344  x[0][1],
1345  x[1][1],
1346  x[2][1],
1347  x[0][2],
1348  x[1][2],
1349  x[2][2]);
1350  *this = tmp;
1351  return *this;
1352 }
1353 
1354 template <class T>
1357 {
1358  return Matrix33 (x[0][0],
1359  x[1][0],
1360  x[2][0],
1361  x[0][1],
1362  x[1][1],
1363  x[2][1],
1364  x[0][2],
1365  x[1][2],
1366  x[2][2]);
1367 }
1368 
1369 template <class T>
1370 const Matrix33<T> &
1371 Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
1372 {
1373  *this = gjInverse (singExc);
1374  return *this;
1375 }
1376 
1377 template <class T>
1379 Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
1380 {
1381  int i, j, k;
1382  Matrix33 s;
1383  Matrix33 t (*this);
1384 
1385  // Forward elimination
1386 
1387  for (i = 0; i < 2 ; i++)
1388  {
1389  int pivot = i;
1390 
1391  T pivotsize = t[i][i];
1392 
1393  if (pivotsize < 0)
1394  pivotsize = -pivotsize;
1395 
1396  for (j = i + 1; j < 3; j++)
1397  {
1398  T tmp = t[j][i];
1399 
1400  if (tmp < 0)
1401  tmp = -tmp;
1402 
1403  if (tmp > pivotsize)
1404  {
1405  pivot = j;
1406  pivotsize = tmp;
1407  }
1408  }
1409 
1410  if (pivotsize == 0)
1411  {
1412  if (singExc)
1413  throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
1414 
1415  return Matrix33();
1416  }
1417 
1418  if (pivot != i)
1419  {
1420  for (j = 0; j < 3; j++)
1421  {
1422  T tmp;
1423 
1424  tmp = t[i][j];
1425  t[i][j] = t[pivot][j];
1426  t[pivot][j] = tmp;
1427 
1428  tmp = s[i][j];
1429  s[i][j] = s[pivot][j];
1430  s[pivot][j] = tmp;
1431  }
1432  }
1433 
1434  for (j = i + 1; j < 3; j++)
1435  {
1436  T f = t[j][i] / t[i][i];
1437 
1438  for (k = 0; k < 3; k++)
1439  {
1440  t[j][k] -= f * t[i][k];
1441  s[j][k] -= f * s[i][k];
1442  }
1443  }
1444  }
1445 
1446  // Backward substitution
1447 
1448  for (i = 2; i >= 0; --i)
1449  {
1450  T f;
1451 
1452  if ((f = t[i][i]) == 0)
1453  {
1454  if (singExc)
1455  throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
1456 
1457  return Matrix33();
1458  }
1459 
1460  for (j = 0; j < 3; j++)
1461  {
1462  t[i][j] /= f;
1463  s[i][j] /= f;
1464  }
1465 
1466  for (j = 0; j < i; j++)
1467  {
1468  f = t[j][i];
1469 
1470  for (k = 0; k < 3; k++)
1471  {
1472  t[j][k] -= f * t[i][k];
1473  s[j][k] -= f * s[i][k];
1474  }
1475  }
1476  }
1477 
1478  return s;
1479 }
1480 
1481 template <class T>
1482 const Matrix33<T> &
1483 Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
1484 {
1485  *this = inverse (singExc);
1486  return *this;
1487 }
1488 
1489 template <class T>
1491 Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
1492 {
1493  if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
1494  {
1495  Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
1496  x[2][1] * x[0][2] - x[0][1] * x[2][2],
1497  x[0][1] * x[1][2] - x[1][1] * x[0][2],
1498 
1499  x[2][0] * x[1][2] - x[1][0] * x[2][2],
1500  x[0][0] * x[2][2] - x[2][0] * x[0][2],
1501  x[1][0] * x[0][2] - x[0][0] * x[1][2],
1502 
1503  x[1][0] * x[2][1] - x[2][0] * x[1][1],
1504  x[2][0] * x[0][1] - x[0][0] * x[2][1],
1505  x[0][0] * x[1][1] - x[1][0] * x[0][1]);
1506 
1507  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
1508 
1509  if (Imath::abs (r) >= 1)
1510  {
1511  for (int i = 0; i < 3; ++i)
1512  {
1513  for (int j = 0; j < 3; ++j)
1514  {
1515  s[i][j] /= r;
1516  }
1517  }
1518  }
1519  else
1520  {
1521  T mr = Imath::abs (r) / limits<T>::smallest();
1522 
1523  for (int i = 0; i < 3; ++i)
1524  {
1525  for (int j = 0; j < 3; ++j)
1526  {
1527  if (mr > Imath::abs (s[i][j]))
1528  {
1529  s[i][j] /= r;
1530  }
1531  else
1532  {
1533  if (singExc)
1534  throw SingMatrixExc ("Cannot invert "
1535  "singular matrix.");
1536  return Matrix33();
1537  }
1538  }
1539  }
1540  }
1541 
1542  return s;
1543  }
1544  else
1545  {
1546  Matrix33 s ( x[1][1],
1547  -x[0][1],
1548  0,
1549 
1550  -x[1][0],
1551  x[0][0],
1552  0,
1553 
1554  0,
1555  0,
1556  1);
1557 
1558  T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1559 
1560  if (Imath::abs (r) >= 1)
1561  {
1562  for (int i = 0; i < 2; ++i)
1563  {
1564  for (int j = 0; j < 2; ++j)
1565  {
1566  s[i][j] /= r;
1567  }
1568  }
1569  }
1570  else
1571  {
1572  T mr = Imath::abs (r) / limits<T>::smallest();
1573 
1574  for (int i = 0; i < 2; ++i)
1575  {
1576  for (int j = 0; j < 2; ++j)
1577  {
1578  if (mr > Imath::abs (s[i][j]))
1579  {
1580  s[i][j] /= r;
1581  }
1582  else
1583  {
1584  if (singExc)
1585  throw SingMatrixExc ("Cannot invert "
1586  "singular matrix.");
1587  return Matrix33();
1588  }
1589  }
1590  }
1591  }
1592 
1593  s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0];
1594  s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1];
1595 
1596  return s;
1597  }
1598 }
1599 
1600 template <class T>
1601 template <class S>
1602 const Matrix33<T> &
1604 {
1605  S cos_r, sin_r;
1606 
1607  cos_r = Math<T>::cos (r);
1608  sin_r = Math<T>::sin (r);
1609 
1610  x[0][0] = cos_r;
1611  x[0][1] = sin_r;
1612  x[0][2] = 0;
1613 
1614  x[1][0] = -sin_r;
1615  x[1][1] = cos_r;
1616  x[1][2] = 0;
1617 
1618  x[2][0] = 0;
1619  x[2][1] = 0;
1620  x[2][2] = 1;
1621 
1622  return *this;
1623 }
1624 
1625 template <class T>
1626 template <class S>
1627 const Matrix33<T> &
1629 {
1630  *this *= Matrix33<T>().setRotation (r);
1631  return *this;
1632 }
1633 
1634 template <class T>
1635 const Matrix33<T> &
1637 {
1638  memset (x, 0, sizeof (x));
1639  x[0][0] = s;
1640  x[1][1] = s;
1641  x[2][2] = 1;
1642 
1643  return *this;
1644 }
1645 
1646 template <class T>
1647 template <class S>
1648 const Matrix33<T> &
1650 {
1651  memset (x, 0, sizeof (x));
1652  x[0][0] = s[0];
1653  x[1][1] = s[1];
1654  x[2][2] = 1;
1655 
1656  return *this;
1657 }
1658 
1659 template <class T>
1660 template <class S>
1661 const Matrix33<T> &
1663 {
1664  x[0][0] *= s[0];
1665  x[0][1] *= s[0];
1666  x[0][2] *= s[0];
1667 
1668  x[1][0] *= s[1];
1669  x[1][1] *= s[1];
1670  x[1][2] *= s[1];
1671 
1672  return *this;
1673 }
1674 
1675 template <class T>
1676 template <class S>
1677 const Matrix33<T> &
1679 {
1680  x[0][0] = 1;
1681  x[0][1] = 0;
1682  x[0][2] = 0;
1683 
1684  x[1][0] = 0;
1685  x[1][1] = 1;
1686  x[1][2] = 0;
1687 
1688  x[2][0] = t[0];
1689  x[2][1] = t[1];
1690  x[2][2] = 1;
1691 
1692  return *this;
1693 }
1694 
1695 template <class T>
1696 inline Vec2<T>
1698 {
1699  return Vec2<T> (x[2][0], x[2][1]);
1700 }
1701 
1702 template <class T>
1703 template <class S>
1704 const Matrix33<T> &
1706 {
1707  x[2][0] += t[0] * x[0][0] + t[1] * x[1][0];
1708  x[2][1] += t[0] * x[0][1] + t[1] * x[1][1];
1709  x[2][2] += t[0] * x[0][2] + t[1] * x[1][2];
1710 
1711  return *this;
1712 }
1713 
1714 template <class T>
1715 template <class S>
1716 const Matrix33<T> &
1718 {
1719  x[0][0] = 1;
1720  x[0][1] = 0;
1721  x[0][2] = 0;
1722 
1723  x[1][0] = xy;
1724  x[1][1] = 1;
1725  x[1][2] = 0;
1726 
1727  x[2][0] = 0;
1728  x[2][1] = 0;
1729  x[2][2] = 1;
1730 
1731  return *this;
1732 }
1733 
1734 template <class T>
1735 template <class S>
1736 const Matrix33<T> &
1738 {
1739  x[0][0] = 1;
1740  x[0][1] = h[1];
1741  x[0][2] = 0;
1742 
1743  x[1][0] = h[0];
1744  x[1][1] = 1;
1745  x[1][2] = 0;
1746 
1747  x[2][0] = 0;
1748  x[2][1] = 0;
1749  x[2][2] = 1;
1750 
1751  return *this;
1752 }
1753 
1754 template <class T>
1755 template <class S>
1756 const Matrix33<T> &
1757 Matrix33<T>::shear (const S &xy)
1758 {
1759  //
1760  // In this case, we don't need a temp. copy of the matrix
1761  // because we never use a value on the RHS after we've
1762  // changed it on the LHS.
1763  //
1764 
1765  x[1][0] += xy * x[0][0];
1766  x[1][1] += xy * x[0][1];
1767  x[1][2] += xy * x[0][2];
1768 
1769  return *this;
1770 }
1771 
1772 template <class T>
1773 template <class S>
1774 const Matrix33<T> &
1776 {
1777  Matrix33<T> P (*this);
1778 
1779  x[0][0] = P[0][0] + h[1] * P[1][0];
1780  x[0][1] = P[0][1] + h[1] * P[1][1];
1781  x[0][2] = P[0][2] + h[1] * P[1][2];
1782 
1783  x[1][0] = P[1][0] + h[0] * P[0][0];
1784  x[1][1] = P[1][1] + h[0] * P[0][1];
1785  x[1][2] = P[1][2] + h[0] * P[0][2];
1786 
1787  return *this;
1788 }
1789 
1790 
1791 //---------------------------
1792 // Implementation of Matrix44
1793 //---------------------------
1794 
1795 template <class T>
1796 inline T *
1798 {
1799  return x[i];
1800 }
1801 
1802 template <class T>
1803 inline const T *
1805 {
1806  return x[i];
1807 }
1808 
1809 template <class T>
1810 inline
1812 {
1813  memset (x, 0, sizeof (x));
1814  x[0][0] = 1;
1815  x[1][1] = 1;
1816  x[2][2] = 1;
1817  x[3][3] = 1;
1818 }
1819 
1820 template <class T>
1821 inline
1823 {
1824  x[0][0] = a;
1825  x[0][1] = a;
1826  x[0][2] = a;
1827  x[0][3] = a;
1828  x[1][0] = a;
1829  x[1][1] = a;
1830  x[1][2] = a;
1831  x[1][3] = a;
1832  x[2][0] = a;
1833  x[2][1] = a;
1834  x[2][2] = a;
1835  x[2][3] = a;
1836  x[3][0] = a;
1837  x[3][1] = a;
1838  x[3][2] = a;
1839  x[3][3] = a;
1840 }
1841 
1842 template <class T>
1843 inline
1844 Matrix44<T>::Matrix44 (const T a[4][4])
1845 {
1846  memcpy (x, a, sizeof (x));
1847 }
1848 
1849 template <class T>
1850 inline
1851 Matrix44<T>::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,
1852  T i, T j, T k, T l, T m, T n, T o, T p)
1853 {
1854  x[0][0] = a;
1855  x[0][1] = b;
1856  x[0][2] = c;
1857  x[0][3] = d;
1858  x[1][0] = e;
1859  x[1][1] = f;
1860  x[1][2] = g;
1861  x[1][3] = h;
1862  x[2][0] = i;
1863  x[2][1] = j;
1864  x[2][2] = k;
1865  x[2][3] = l;
1866  x[3][0] = m;
1867  x[3][1] = n;
1868  x[3][2] = o;
1869  x[3][3] = p;
1870 }
1871 
1872 
1873 template <class T>
1874 inline
1876 {
1877  x[0][0] = r[0][0];
1878  x[0][1] = r[0][1];
1879  x[0][2] = r[0][2];
1880  x[0][3] = 0;
1881  x[1][0] = r[1][0];
1882  x[1][1] = r[1][1];
1883  x[1][2] = r[1][2];
1884  x[1][3] = 0;
1885  x[2][0] = r[2][0];
1886  x[2][1] = r[2][1];
1887  x[2][2] = r[2][2];
1888  x[2][3] = 0;
1889  x[3][0] = t[0];
1890  x[3][1] = t[1];
1891  x[3][2] = t[2];
1892  x[3][3] = 1;
1893 }
1894 
1895 template <class T>
1896 inline
1898 {
1899  x[0][0] = v.x[0][0];
1900  x[0][1] = v.x[0][1];
1901  x[0][2] = v.x[0][2];
1902  x[0][3] = v.x[0][3];
1903  x[1][0] = v.x[1][0];
1904  x[1][1] = v.x[1][1];
1905  x[1][2] = v.x[1][2];
1906  x[1][3] = v.x[1][3];
1907  x[2][0] = v.x[2][0];
1908  x[2][1] = v.x[2][1];
1909  x[2][2] = v.x[2][2];
1910  x[2][3] = v.x[2][3];
1911  x[3][0] = v.x[3][0];
1912  x[3][1] = v.x[3][1];
1913  x[3][2] = v.x[3][2];
1914  x[3][3] = v.x[3][3];
1915 }
1916 
1917 template <class T>
1918 template <class S>
1919 inline
1921 {
1922  x[0][0] = T (v.x[0][0]);
1923  x[0][1] = T (v.x[0][1]);
1924  x[0][2] = T (v.x[0][2]);
1925  x[0][3] = T (v.x[0][3]);
1926  x[1][0] = T (v.x[1][0]);
1927  x[1][1] = T (v.x[1][1]);
1928  x[1][2] = T (v.x[1][2]);
1929  x[1][3] = T (v.x[1][3]);
1930  x[2][0] = T (v.x[2][0]);
1931  x[2][1] = T (v.x[2][1]);
1932  x[2][2] = T (v.x[2][2]);
1933  x[2][3] = T (v.x[2][3]);
1934  x[3][0] = T (v.x[3][0]);
1935  x[3][1] = T (v.x[3][1]);
1936  x[3][2] = T (v.x[3][2]);
1937  x[3][3] = T (v.x[3][3]);
1938 }
1939 
1940 template <class T>
1941 inline const Matrix44<T> &
1943 {
1944  x[0][0] = v.x[0][0];
1945  x[0][1] = v.x[0][1];
1946  x[0][2] = v.x[0][2];
1947  x[0][3] = v.x[0][3];
1948  x[1][0] = v.x[1][0];
1949  x[1][1] = v.x[1][1];
1950  x[1][2] = v.x[1][2];
1951  x[1][3] = v.x[1][3];
1952  x[2][0] = v.x[2][0];
1953  x[2][1] = v.x[2][1];
1954  x[2][2] = v.x[2][2];
1955  x[2][3] = v.x[2][3];
1956  x[3][0] = v.x[3][0];
1957  x[3][1] = v.x[3][1];
1958  x[3][2] = v.x[3][2];
1959  x[3][3] = v.x[3][3];
1960  return *this;
1961 }
1962 
1963 template <class T>
1964 inline const Matrix44<T> &
1966 {
1967  x[0][0] = a;
1968  x[0][1] = a;
1969  x[0][2] = a;
1970  x[0][3] = a;
1971  x[1][0] = a;
1972  x[1][1] = a;
1973  x[1][2] = a;
1974  x[1][3] = a;
1975  x[2][0] = a;
1976  x[2][1] = a;
1977  x[2][2] = a;
1978  x[2][3] = a;
1979  x[3][0] = a;
1980  x[3][1] = a;
1981  x[3][2] = a;
1982  x[3][3] = a;
1983  return *this;
1984 }
1985 
1986 template <class T>
1987 inline T *
1989 {
1990  return (T *) &x[0][0];
1991 }
1992 
1993 template <class T>
1994 inline const T *
1996 {
1997  return (const T *) &x[0][0];
1998 }
1999 
2000 template <class T>
2001 template <class S>
2002 inline void
2004 {
2005  if (isSameType<S,T>::value)
2006  {
2007  memcpy (v.x, x, sizeof (x));
2008  }
2009  else
2010  {
2011  v.x[0][0] = x[0][0];
2012  v.x[0][1] = x[0][1];
2013  v.x[0][2] = x[0][2];
2014  v.x[0][3] = x[0][3];
2015  v.x[1][0] = x[1][0];
2016  v.x[1][1] = x[1][1];
2017  v.x[1][2] = x[1][2];
2018  v.x[1][3] = x[1][3];
2019  v.x[2][0] = x[2][0];
2020  v.x[2][1] = x[2][1];
2021  v.x[2][2] = x[2][2];
2022  v.x[2][3] = x[2][3];
2023  v.x[3][0] = x[3][0];
2024  v.x[3][1] = x[3][1];
2025  v.x[3][2] = x[3][2];
2026  v.x[3][3] = x[3][3];
2027  }
2028 }
2029 
2030 template <class T>
2031 template <class S>
2032 inline Matrix44<T> &
2034 {
2035  if (isSameType<S,T>::value)
2036  {
2037  memcpy (x, v.x, sizeof (x));
2038  }
2039  else
2040  {
2041  x[0][0] = v.x[0][0];
2042  x[0][1] = v.x[0][1];
2043  x[0][2] = v.x[0][2];
2044  x[0][3] = v.x[0][3];
2045  x[1][0] = v.x[1][0];
2046  x[1][1] = v.x[1][1];
2047  x[1][2] = v.x[1][2];
2048  x[1][3] = v.x[1][3];
2049  x[2][0] = v.x[2][0];
2050  x[2][1] = v.x[2][1];
2051  x[2][2] = v.x[2][2];
2052  x[2][3] = v.x[2][3];
2053  x[3][0] = v.x[3][0];
2054  x[3][1] = v.x[3][1];
2055  x[3][2] = v.x[3][2];
2056  x[3][3] = v.x[3][3];
2057  }
2058 
2059  return *this;
2060 }
2061 
2062 template <class T>
2063 template <class S>
2064 inline Matrix44<T> &
2066 {
2067  if (isSameType<S,T>::value)
2068  {
2069  memcpy (x, v.x, sizeof (x));
2070  }
2071  else
2072  {
2073  x[0][0] = v.x[0][0];
2074  x[0][1] = v.x[0][1];
2075  x[0][2] = v.x[0][2];
2076  x[0][3] = v.x[0][3];
2077  x[1][0] = v.x[1][0];
2078  x[1][1] = v.x[1][1];
2079  x[1][2] = v.x[1][2];
2080  x[1][3] = v.x[1][3];
2081  x[2][0] = v.x[2][0];
2082  x[2][1] = v.x[2][1];
2083  x[2][2] = v.x[2][2];
2084  x[2][3] = v.x[2][3];
2085  x[3][0] = v.x[3][0];
2086  x[3][1] = v.x[3][1];
2087  x[3][2] = v.x[3][2];
2088  x[3][3] = v.x[3][3];
2089  }
2090 
2091  return *this;
2092 }
2093 
2094 template <class T>
2095 inline void
2097 {
2098  memset (x, 0, sizeof (x));
2099  x[0][0] = 1;
2100  x[1][1] = 1;
2101  x[2][2] = 1;
2102  x[3][3] = 1;
2103 }
2104 
2105 template <class T>
2106 bool
2108 {
2109  return x[0][0] == v.x[0][0] &&
2110  x[0][1] == v.x[0][1] &&
2111  x[0][2] == v.x[0][2] &&
2112  x[0][3] == v.x[0][3] &&
2113  x[1][0] == v.x[1][0] &&
2114  x[1][1] == v.x[1][1] &&
2115  x[1][2] == v.x[1][2] &&
2116  x[1][3] == v.x[1][3] &&
2117  x[2][0] == v.x[2][0] &&
2118  x[2][1] == v.x[2][1] &&
2119  x[2][2] == v.x[2][2] &&
2120  x[2][3] == v.x[2][3] &&
2121  x[3][0] == v.x[3][0] &&
2122  x[3][1] == v.x[3][1] &&
2123  x[3][2] == v.x[3][2] &&
2124  x[3][3] == v.x[3][3];
2125 }
2126 
2127 template <class T>
2128 bool
2130 {
2131  return 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];
2147 }
2148 
2149 template <class T>
2150 bool
2152 {
2153  for (int i = 0; i < 4; i++)
2154  for (int j = 0; j < 4; j++)
2155  if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
2156  return false;
2157 
2158  return true;
2159 }
2160 
2161 template <class T>
2162 bool
2164 {
2165  for (int i = 0; i < 4; i++)
2166  for (int j = 0; j < 4; j++)
2167  if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
2168  return false;
2169 
2170  return true;
2171 }
2172 
2173 template <class T>
2174 const Matrix44<T> &
2176 {
2177  x[0][0] += v.x[0][0];
2178  x[0][1] += v.x[0][1];
2179  x[0][2] += v.x[0][2];
2180  x[0][3] += v.x[0][3];
2181  x[1][0] += v.x[1][0];
2182  x[1][1] += v.x[1][1];
2183  x[1][2] += v.x[1][2];
2184  x[1][3] += v.x[1][3];
2185  x[2][0] += v.x[2][0];
2186  x[2][1] += v.x[2][1];
2187  x[2][2] += v.x[2][2];
2188  x[2][3] += v.x[2][3];
2189  x[3][0] += v.x[3][0];
2190  x[3][1] += v.x[3][1];
2191  x[3][2] += v.x[3][2];
2192  x[3][3] += v.x[3][3];
2193 
2194  return *this;
2195 }
2196 
2197 template <class T>
2198 const Matrix44<T> &
2200 {
2201  x[0][0] += a;
2202  x[0][1] += a;
2203  x[0][2] += a;
2204  x[0][3] += a;
2205  x[1][0] += a;
2206  x[1][1] += a;
2207  x[1][2] += a;
2208  x[1][3] += a;
2209  x[2][0] += a;
2210  x[2][1] += a;
2211  x[2][2] += a;
2212  x[2][3] += a;
2213  x[3][0] += a;
2214  x[3][1] += a;
2215  x[3][2] += a;
2216  x[3][3] += a;
2217 
2218  return *this;
2219 }
2220 
2221 template <class T>
2224 {
2225  return Matrix44 (x[0][0] + v.x[0][0],
2226  x[0][1] + v.x[0][1],
2227  x[0][2] + v.x[0][2],
2228  x[0][3] + v.x[0][3],
2229  x[1][0] + v.x[1][0],
2230  x[1][1] + v.x[1][1],
2231  x[1][2] + v.x[1][2],
2232  x[1][3] + v.x[1][3],
2233  x[2][0] + v.x[2][0],
2234  x[2][1] + v.x[2][1],
2235  x[2][2] + v.x[2][2],
2236  x[2][3] + v.x[2][3],
2237  x[3][0] + v.x[3][0],
2238  x[3][1] + v.x[3][1],
2239  x[3][2] + v.x[3][2],
2240  x[3][3] + v.x[3][3]);
2241 }
2242 
2243 template <class T>
2244 const Matrix44<T> &
2246 {
2247  x[0][0] -= v.x[0][0];
2248  x[0][1] -= v.x[0][1];
2249  x[0][2] -= v.x[0][2];
2250  x[0][3] -= v.x[0][3];
2251  x[1][0] -= v.x[1][0];
2252  x[1][1] -= v.x[1][1];
2253  x[1][2] -= v.x[1][2];
2254  x[1][3] -= v.x[1][3];
2255  x[2][0] -= v.x[2][0];
2256  x[2][1] -= v.x[2][1];
2257  x[2][2] -= v.x[2][2];
2258  x[2][3] -= v.x[2][3];
2259  x[3][0] -= v.x[3][0];
2260  x[3][1] -= v.x[3][1];
2261  x[3][2] -= v.x[3][2];
2262  x[3][3] -= v.x[3][3];
2263 
2264  return *this;
2265 }
2266 
2267 template <class T>
2268 const Matrix44<T> &
2270 {
2271  x[0][0] -= a;
2272  x[0][1] -= a;
2273  x[0][2] -= a;
2274  x[0][3] -= a;
2275  x[1][0] -= a;
2276  x[1][1] -= a;
2277  x[1][2] -= a;
2278  x[1][3] -= a;
2279  x[2][0] -= a;
2280  x[2][1] -= a;
2281  x[2][2] -= a;
2282  x[2][3] -= a;
2283  x[3][0] -= a;
2284  x[3][1] -= a;
2285  x[3][2] -= a;
2286  x[3][3] -= a;
2287 
2288  return *this;
2289 }
2290 
2291 template <class T>
2294 {
2295  return Matrix44 (x[0][0] - v.x[0][0],
2296  x[0][1] - v.x[0][1],
2297  x[0][2] - v.x[0][2],
2298  x[0][3] - v.x[0][3],
2299  x[1][0] - v.x[1][0],
2300  x[1][1] - v.x[1][1],
2301  x[1][2] - v.x[1][2],
2302  x[1][3] - v.x[1][3],
2303  x[2][0] - v.x[2][0],
2304  x[2][1] - v.x[2][1],
2305  x[2][2] - v.x[2][2],
2306  x[2][3] - v.x[2][3],
2307  x[3][0] - v.x[3][0],
2308  x[3][1] - v.x[3][1],
2309  x[3][2] - v.x[3][2],
2310  x[3][3] - v.x[3][3]);
2311 }
2312 
2313 template <class T>
2316 {
2317  return Matrix44 (-x[0][0],
2318  -x[0][1],
2319  -x[0][2],
2320  -x[0][3],
2321  -x[1][0],
2322  -x[1][1],
2323  -x[1][2],
2324  -x[1][3],
2325  -x[2][0],
2326  -x[2][1],
2327  -x[2][2],
2328  -x[2][3],
2329  -x[3][0],
2330  -x[3][1],
2331  -x[3][2],
2332  -x[3][3]);
2333 }
2334 
2335 template <class T>
2336 const Matrix44<T> &
2338 {
2339  x[0][0] = -x[0][0];
2340  x[0][1] = -x[0][1];
2341  x[0][2] = -x[0][2];
2342  x[0][3] = -x[0][3];
2343  x[1][0] = -x[1][0];
2344  x[1][1] = -x[1][1];
2345  x[1][2] = -x[1][2];
2346  x[1][3] = -x[1][3];
2347  x[2][0] = -x[2][0];
2348  x[2][1] = -x[2][1];
2349  x[2][2] = -x[2][2];
2350  x[2][3] = -x[2][3];
2351  x[3][0] = -x[3][0];
2352  x[3][1] = -x[3][1];
2353  x[3][2] = -x[3][2];
2354  x[3][3] = -x[3][3];
2355 
2356  return *this;
2357 }
2358 
2359 template <class T>
2360 const Matrix44<T> &
2362 {
2363  x[0][0] *= a;
2364  x[0][1] *= a;
2365  x[0][2] *= a;
2366  x[0][3] *= a;
2367  x[1][0] *= a;
2368  x[1][1] *= a;
2369  x[1][2] *= a;
2370  x[1][3] *= a;
2371  x[2][0] *= a;
2372  x[2][1] *= a;
2373  x[2][2] *= a;
2374  x[2][3] *= a;
2375  x[3][0] *= a;
2376  x[3][1] *= a;
2377  x[3][2] *= a;
2378  x[3][3] *= a;
2379 
2380  return *this;
2381 }
2382 
2383 template <class T>
2386 {
2387  return Matrix44 (x[0][0] * a,
2388  x[0][1] * a,
2389  x[0][2] * a,
2390  x[0][3] * a,
2391  x[1][0] * a,
2392  x[1][1] * a,
2393  x[1][2] * a,
2394  x[1][3] * a,
2395  x[2][0] * a,
2396  x[2][1] * a,
2397  x[2][2] * a,
2398  x[2][3] * a,
2399  x[3][0] * a,
2400  x[3][1] * a,
2401  x[3][2] * a,
2402  x[3][3] * a);
2403 }
2404 
2405 template <class T>
2406 inline Matrix44<T>
2407 operator * (T a, const Matrix44<T> &v)
2408 {
2409  return v * a;
2410 }
2411 
2412 template <class T>
2413 inline const Matrix44<T> &
2415 {
2416  Matrix44 tmp (T (0));
2417 
2418  multiply (*this, v, tmp);
2419  *this = tmp;
2420  return *this;
2421 }
2422 
2423 template <class T>
2424 inline Matrix44<T>
2426 {
2427  Matrix44 tmp (T (0));
2428 
2429  multiply (*this, v, tmp);
2430  return tmp;
2431 }
2432 
2433 template <class T>
2434 void
2436  const Matrix44<T> &b,
2437  Matrix44<T> &c)
2438 {
2439  const T * IMATH_RESTRICT ap = &a.x[0][0];
2440  const T * IMATH_RESTRICT bp = &b.x[0][0];
2441  T * IMATH_RESTRICT cp = &c.x[0][0];
2442 
2443  T a0, a1, a2, a3;
2444 
2445  a0 = ap[0];
2446  a1 = ap[1];
2447  a2 = ap[2];
2448  a3 = ap[3];
2449 
2450  cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2451  cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2452  cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2453  cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2454 
2455  a0 = ap[4];
2456  a1 = ap[5];
2457  a2 = ap[6];
2458  a3 = ap[7];
2459 
2460  cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2461  cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2462  cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2463  cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2464 
2465  a0 = ap[8];
2466  a1 = ap[9];
2467  a2 = ap[10];
2468  a3 = ap[11];
2469 
2470  cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2471  cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2472  cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2473  cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2474 
2475  a0 = ap[12];
2476  a1 = ap[13];
2477  a2 = ap[14];
2478  a3 = ap[15];
2479 
2480  cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
2481  cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
2482  cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
2483  cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
2484 }
2485 
2486 template <class T> template <class S>
2487 void
2489 {
2490  S a, b, c, w;
2491 
2492  a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0] + x[3][0];
2493  b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1] + x[3][1];
2494  c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2] + x[3][2];
2495  w = src[0] * x[0][3] + src[1] * x[1][3] + src[2] * x[2][3] + x[3][3];
2496 
2497  dst.x = a / w;
2498  dst.y = b / w;
2499  dst.z = c / w;
2500 }
2501 
2502 template <class T> template <class S>
2503 void
2505 {
2506  S a, b, c;
2507 
2508  a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0];
2509  b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1];
2510  c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2];
2511 
2512  dst.x = a;
2513  dst.y = b;
2514  dst.z = c;
2515 }
2516 
2517 template <class T>
2518 const Matrix44<T> &
2520 {
2521  x[0][0] /= a;
2522  x[0][1] /= a;
2523  x[0][2] /= a;
2524  x[0][3] /= a;
2525  x[1][0] /= a;
2526  x[1][1] /= a;
2527  x[1][2] /= a;
2528  x[1][3] /= a;
2529  x[2][0] /= a;
2530  x[2][1] /= a;
2531  x[2][2] /= a;
2532  x[2][3] /= a;
2533  x[3][0] /= a;
2534  x[3][1] /= a;
2535  x[3][2] /= a;
2536  x[3][3] /= a;
2537 
2538  return *this;
2539 }
2540 
2541 template <class T>
2544 {
2545  return Matrix44 (x[0][0] / a,
2546  x[0][1] / a,
2547  x[0][2] / a,
2548  x[0][3] / a,
2549  x[1][0] / a,
2550  x[1][1] / a,
2551  x[1][2] / a,
2552  x[1][3] / a,
2553  x[2][0] / a,
2554  x[2][1] / a,
2555  x[2][2] / a,
2556  x[2][3] / a,
2557  x[3][0] / a,
2558  x[3][1] / a,
2559  x[3][2] / a,
2560  x[3][3] / a);
2561 }
2562 
2563 template <class T>
2564 const Matrix44<T> &
2566 {
2567  Matrix44 tmp (x[0][0],
2568  x[1][0],
2569  x[2][0],
2570  x[3][0],
2571  x[0][1],
2572  x[1][1],
2573  x[2][1],
2574  x[3][1],
2575  x[0][2],
2576  x[1][2],
2577  x[2][2],
2578  x[3][2],
2579  x[0][3],
2580  x[1][3],
2581  x[2][3],
2582  x[3][3]);
2583  *this = tmp;
2584  return *this;
2585 }
2586 
2587 template <class T>
2590 {
2591  return Matrix44 (x[0][0],
2592  x[1][0],
2593  x[2][0],
2594  x[3][0],
2595  x[0][1],
2596  x[1][1],
2597  x[2][1],
2598  x[3][1],
2599  x[0][2],
2600  x[1][2],
2601  x[2][2],
2602  x[3][2],
2603  x[0][3],
2604  x[1][3],
2605  x[2][3],
2606  x[3][3]);
2607 }
2608 
2609 template <class T>
2610 const Matrix44<T> &
2611 Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
2612 {
2613  *this = gjInverse (singExc);
2614  return *this;
2615 }
2616 
2617 template <class T>
2619 Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
2620 {
2621  int i, j, k;
2622  Matrix44 s;
2623  Matrix44 t (*this);
2624 
2625  // Forward elimination
2626 
2627  for (i = 0; i < 3 ; i++)
2628  {
2629  int pivot = i;
2630 
2631  T pivotsize = t[i][i];
2632 
2633  if (pivotsize < 0)
2634  pivotsize = -pivotsize;
2635 
2636  for (j = i + 1; j < 4; j++)
2637  {
2638  T tmp = t[j][i];
2639 
2640  if (tmp < 0)
2641  tmp = -tmp;
2642 
2643  if (tmp > pivotsize)
2644  {
2645  pivot = j;
2646  pivotsize = tmp;
2647  }
2648  }
2649 
2650  if (pivotsize == 0)
2651  {
2652  if (singExc)
2653  throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
2654 
2655  return Matrix44();
2656  }
2657 
2658  if (pivot != i)
2659  {
2660  for (j = 0; j < 4; j++)
2661  {
2662  T tmp;
2663 
2664  tmp = t[i][j];
2665  t[i][j] = t[pivot][j];
2666  t[pivot][j] = tmp;
2667 
2668  tmp = s[i][j];
2669  s[i][j] = s[pivot][j];
2670  s[pivot][j] = tmp;
2671  }
2672  }
2673 
2674  for (j = i + 1; j < 4; j++)
2675  {
2676  T f = t[j][i] / t[i][i];
2677 
2678  for (k = 0; k < 4; k++)
2679  {
2680  t[j][k] -= f * t[i][k];
2681  s[j][k] -= f * s[i][k];
2682  }
2683  }
2684  }
2685 
2686  // Backward substitution
2687 
2688  for (i = 3; i >= 0; --i)
2689  {
2690  T f;
2691 
2692  if ((f = t[i][i]) == 0)
2693  {
2694  if (singExc)
2695  throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
2696 
2697  return Matrix44();
2698  }
2699 
2700  for (j = 0; j < 4; j++)
2701  {
2702  t[i][j] /= f;
2703  s[i][j] /= f;
2704  }
2705 
2706  for (j = 0; j < i; j++)
2707  {
2708  f = t[j][i];
2709 
2710  for (k = 0; k < 4; k++)
2711  {
2712  t[j][k] -= f * t[i][k];
2713  s[j][k] -= f * s[i][k];
2714  }
2715  }
2716  }
2717 
2718  return s;
2719 }
2720 
2721 template <class T>
2722 const Matrix44<T> &
2723 Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
2724 {
2725  *this = inverse (singExc);
2726  return *this;
2727 }
2728 
2729 template <class T>
2731 Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
2732 {
2733  if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
2734  return gjInverse(singExc);
2735 
2736  Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2737  x[2][1] * x[0][2] - x[0][1] * x[2][2],
2738  x[0][1] * x[1][2] - x[1][1] * x[0][2],
2739  0,
2740 
2741  x[2][0] * x[1][2] - x[1][0] * x[2][2],
2742  x[0][0] * x[2][2] - x[2][0] * x[0][2],
2743  x[1][0] * x[0][2] - x[0][0] * x[1][2],
2744  0,
2745 
2746  x[1][0] * x[2][1] - x[2][0] * x[1][1],
2747  x[2][0] * x[0][1] - x[0][0] * x[2][1],
2748  x[0][0] * x[1][1] - x[1][0] * x[0][1],
2749  0,
2750 
2751  0,
2752  0,
2753  0,
2754  1);
2755 
2756  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
2757 
2758  if (Imath::abs (r) >= 1)
2759  {
2760  for (int i = 0; i < 3; ++i)
2761  {
2762  for (int j = 0; j < 3; ++j)
2763  {
2764  s[i][j] /= r;
2765  }
2766  }
2767  }
2768  else
2769  {
2770  T mr = Imath::abs (r) / limits<T>::smallest();
2771 
2772  for (int i = 0; i < 3; ++i)
2773  {
2774  for (int j = 0; j < 3; ++j)
2775  {
2776  if (mr > Imath::abs (s[i][j]))
2777  {
2778  s[i][j] /= r;
2779  }
2780  else
2781  {
2782  if (singExc)
2783  throw SingMatrixExc ("Cannot invert singular matrix.");
2784 
2785  return Matrix44();
2786  }
2787  }
2788  }
2789  }
2790 
2791  s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0];
2792  s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1];
2793  s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2];
2794 
2795  return s;
2796 }
2797 
2798 template <class T>
2799 template <class S>
2800 const Matrix44<T> &
2802 {
2803  S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
2804 
2805  cos_rz = Math<T>::cos (r[2]);
2806  cos_ry = Math<T>::cos (r[1]);
2807  cos_rx = Math<T>::cos (r[0]);
2808 
2809  sin_rz = Math<T>::sin (r[2]);
2810  sin_ry = Math<T>::sin (r[1]);
2811  sin_rx = Math<T>::sin (r[0]);
2812 
2813  x[0][0] = cos_rz * cos_ry;
2814  x[0][1] = sin_rz * cos_ry;
2815  x[0][2] = -sin_ry;
2816  x[0][3] = 0;
2817 
2818  x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
2819  x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
2820  x[1][2] = cos_ry * sin_rx;
2821  x[1][3] = 0;
2822 
2823  x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;
2824  x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;
2825  x[2][2] = cos_ry * cos_rx;
2826  x[2][3] = 0;
2827 
2828  x[3][0] = 0;
2829  x[3][1] = 0;
2830  x[3][2] = 0;
2831  x[3][3] = 1;
2832 
2833  return *this;
2834 }
2835 
2836 template <class T>
2837 template <class S>
2838 const Matrix44<T> &
2839 Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle)
2840 {
2841  Vec3<S> unit (axis.normalized());
2842  S sine = Math<T>::sin (angle);
2843  S cosine = Math<T>::cos (angle);
2844 
2845  x[0][0] = unit[0] * unit[0] * (1 - cosine) + cosine;
2846  x[0][1] = unit[0] * unit[1] * (1 - cosine) + unit[2] * sine;
2847  x[0][2] = unit[0] * unit[2] * (1 - cosine) - unit[1] * sine;
2848  x[0][3] = 0;
2849 
2850  x[1][0] = unit[0] * unit[1] * (1 - cosine) - unit[2] * sine;
2851  x[1][1] = unit[1] * unit[1] * (1 - cosine) + cosine;
2852  x[1][2] = unit[1] * unit[2] * (1 - cosine) + unit[0] * sine;
2853  x[1][3] = 0;
2854 
2855  x[2][0] = unit[0] * unit[2] * (1 - cosine) + unit[1] * sine;
2856  x[2][1] = unit[1] * unit[2] * (1 - cosine) - unit[0] * sine;
2857  x[2][2] = unit[2] * unit[2] * (1 - cosine) + cosine;
2858  x[2][3] = 0;
2859 
2860  x[3][0] = 0;
2861  x[3][1] = 0;
2862  x[3][2] = 0;
2863  x[3][3] = 1;
2864 
2865  return *this;
2866 }
2867 
2868 template <class T>
2869 template <class S>
2870 const Matrix44<T> &
2872 {
2873  S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
2874  S m00, m01, m02;
2875  S m10, m11, m12;
2876  S m20, m21, m22;
2877 
2878  cos_rz = Math<S>::cos (r[2]);
2879  cos_ry = Math<S>::cos (r[1]);
2880  cos_rx = Math<S>::cos (r[0]);
2881 
2882  sin_rz = Math<S>::sin (r[2]);
2883  sin_ry = Math<S>::sin (r[1]);
2884  sin_rx = Math<S>::sin (r[0]);
2885 
2886  m00 = cos_rz * cos_ry;
2887  m01 = sin_rz * cos_ry;
2888  m02 = -sin_ry;
2889  m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
2890  m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
2891  m12 = cos_ry * sin_rx;
2892  m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx;
2893  m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx;
2894  m22 = cos_ry * cos_rx;
2895 
2896  Matrix44<T> P (*this);
2897 
2898  x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02;
2899  x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02;
2900  x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02;
2901  x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02;
2902 
2903  x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12;
2904  x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12;
2905  x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12;
2906  x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12;
2907 
2908  x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22;
2909  x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22;
2910  x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22;
2911  x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22;
2912 
2913  return *this;
2914 }
2915 
2916 template <class T>
2917 const Matrix44<T> &
2919 {
2920  memset (x, 0, sizeof (x));
2921  x[0][0] = s;
2922  x[1][1] = s;
2923  x[2][2] = s;
2924  x[3][3] = 1;
2925 
2926  return *this;
2927 }
2928 
2929 template <class T>
2930 template <class S>
2931 const Matrix44<T> &
2933 {
2934  memset (x, 0, sizeof (x));
2935  x[0][0] = s[0];
2936  x[1][1] = s[1];
2937  x[2][2] = s[2];
2938  x[3][3] = 1;
2939 
2940  return *this;
2941 }
2942 
2943 template <class T>
2944 template <class S>
2945 const Matrix44<T> &
2947 {
2948  x[0][0] *= s[0];
2949  x[0][1] *= s[0];
2950  x[0][2] *= s[0];
2951  x[0][3] *= s[0];
2952 
2953  x[1][0] *= s[1];
2954  x[1][1] *= s[1];
2955  x[1][2] *= s[1];
2956  x[1][3] *= s[1];
2957 
2958  x[2][0] *= s[2];
2959  x[2][1] *= s[2];
2960  x[2][2] *= s[2];
2961  x[2][3] *= s[2];
2962 
2963  return *this;
2964 }
2965 
2966 template <class T>
2967 template <class S>
2968 const Matrix44<T> &
2970 {
2971  x[0][0] = 1;
2972  x[0][1] = 0;
2973  x[0][2] = 0;
2974  x[0][3] = 0;
2975 
2976  x[1][0] = 0;
2977  x[1][1] = 1;
2978  x[1][2] = 0;
2979  x[1][3] = 0;
2980 
2981  x[2][0] = 0;
2982  x[2][1] = 0;
2983  x[2][2] = 1;
2984  x[2][3] = 0;
2985 
2986  x[3][0] = t[0];
2987  x[3][1] = t[1];
2988  x[3][2] = t[2];
2989  x[3][3] = 1;
2990 
2991  return *this;
2992 }
2993 
2994 template <class T>
2995 inline const Vec3<T>
2997 {
2998  return Vec3<T> (x[3][0], x[3][1], x[3][2]);
2999 }
3000 
3001 template <class T>
3002 template <class S>
3003 const Matrix44<T> &
3005 {
3006  x[3][0] += t[0] * x[0][0] + t[1] * x[1][0] + t[2] * x[2][0];
3007  x[3][1] += t[0] * x[0][1] + t[1] * x[1][1] + t[2] * x[2][1];
3008  x[3][2] += t[0] * x[0][2] + t[1] * x[1][2] + t[2] * x[2][2];
3009  x[3][3] += t[0] * x[0][3] + t[1] * x[1][3] + t[2] * x[2][3];
3010 
3011  return *this;
3012 }
3013 
3014 template <class T>
3015 template <class S>
3016 const Matrix44<T> &
3018 {
3019  x[0][0] = 1;
3020  x[0][1] = 0;
3021  x[0][2] = 0;
3022  x[0][3] = 0;
3023 
3024  x[1][0] = h[0];
3025  x[1][1] = 1;
3026  x[1][2] = 0;
3027  x[1][3] = 0;
3028 
3029  x[2][0] = h[1];
3030  x[2][1] = h[2];
3031  x[2][2] = 1;
3032  x[2][3] = 0;
3033 
3034  x[3][0] = 0;
3035  x[3][1] = 0;
3036  x[3][2] = 0;
3037  x[3][3] = 1;
3038 
3039  return *this;
3040 }
3041 
3042 template <class T>
3043 template <class S>
3044 const Matrix44<T> &
3046 {
3047  x[0][0] = 1;
3048  x[0][1] = h.yx;
3049  x[0][2] = h.zx;
3050  x[0][3] = 0;
3051 
3052  x[1][0] = h.xy;
3053  x[1][1] = 1;
3054  x[1][2] = h.zy;
3055  x[1][3] = 0;
3056 
3057  x[2][0] = h.xz;
3058  x[2][1] = h.yz;
3059  x[2][2] = 1;
3060  x[2][3] = 0;
3061 
3062  x[3][0] = 0;
3063  x[3][1] = 0;
3064  x[3][2] = 0;
3065  x[3][3] = 1;
3066 
3067  return *this;
3068 }
3069 
3070 template <class T>
3071 template <class S>
3072 const Matrix44<T> &
3074 {
3075  //
3076  // In this case, we don't need a temp. copy of the matrix
3077  // because we never use a value on the RHS after we've
3078  // changed it on the LHS.
3079  //
3080 
3081  for (int i=0; i < 4; i++)
3082  {
3083  x[2][i] += h[1] * x[0][i] + h[2] * x[1][i];
3084  x[1][i] += h[0] * x[0][i];
3085  }
3086 
3087  return *this;
3088 }
3089 
3090 template <class T>
3091 template <class S>
3092 const Matrix44<T> &
3094 {
3095  Matrix44<T> P (*this);
3096 
3097  for (int i=0; i < 4; i++)
3098  {
3099  x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i];
3100  x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i];
3101  x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i];
3102  }
3103 
3104  return *this;
3105 }
3106 
3107 
3108 //--------------------------------
3109 // Implementation of stream output
3110 //--------------------------------
3111 
3112 template <class T>
3113 std::ostream &
3114 operator << (std::ostream &s, const Matrix33<T> &m)
3115 {
3116  std::ios_base::fmtflags oldFlags = s.flags();
3117  int width;
3118 
3119  if (s.flags() & std::ios_base::fixed)
3120  {
3121  s.setf (std::ios_base::showpoint);
3122  width = s.precision() + 5;
3123  }
3124  else
3125  {
3126  s.setf (std::ios_base::scientific);
3127  s.setf (std::ios_base::showpoint);
3128  width = s.precision() + 8;
3129  }
3130 
3131  s << "(" << std::setw (width) << m[0][0] <<
3132  " " << std::setw (width) << m[0][1] <<
3133  " " << std::setw (width) << m[0][2] << "\n" <<
3134 
3135  " " << std::setw (width) << m[1][0] <<
3136  " " << std::setw (width) << m[1][1] <<
3137  " " << std::setw (width) << m[1][2] << "\n" <<
3138 
3139  " " << std::setw (width) << m[2][0] <<
3140  " " << std::setw (width) << m[2][1] <<
3141  " " << std::setw (width) << m[2][2] << ")\n";
3142 
3143  s.flags (oldFlags);
3144  return s;
3145 }
3146 
3147 template <class T>
3148 std::ostream &
3149 operator << (std::ostream &s, const Matrix44<T> &m)
3150 {
3151  std::ios_base::fmtflags oldFlags = s.flags();
3152  int width;
3153 
3154  if (s.flags() & std::ios_base::fixed)
3155  {
3156  s.setf (std::ios_base::showpoint);
3157  width = s.precision() + 5;
3158  }
3159  else
3160  {
3161  s.setf (std::ios_base::scientific);
3162  s.setf (std::ios_base::showpoint);
3163  width = s.precision() + 8;
3164  }
3165 
3166  s << "(" << std::setw (width) << m[0][0] <<
3167  " " << std::setw (width) << m[0][1] <<
3168  " " << std::setw (width) << m[0][2] <<
3169  " " << std::setw (width) << m[0][3] << "\n" <<
3170 
3171  " " << std::setw (width) << m[1][0] <<
3172  " " << std::setw (width) << m[1][1] <<
3173  " " << std::setw (width) << m[1][2] <<
3174  " " << std::setw (width) << m[1][3] << "\n" <<
3175 
3176  " " << std::setw (width) << m[2][0] <<
3177  " " << std::setw (width) << m[2][1] <<
3178  " " << std::setw (width) << m[2][2] <<
3179  " " << std::setw (width) << m[2][3] << "\n" <<
3180 
3181  " " << std::setw (width) << m[3][0] <<
3182  " " << std::setw (width) << m[3][1] <<
3183  " " << std::setw (width) << m[3][2] <<
3184  " " << std::setw (width) << m[3][3] << ")\n";
3185 
3186  s.flags (oldFlags);
3187  return s;
3188 }
3189 
3190 
3191 //---------------------------------------------------------------
3192 // Implementation of vector-times-matrix multiplication operators
3193 //---------------------------------------------------------------
3194 
3195 template <class S, class T>
3196 inline const Vec2<S> &
3198 {
3199  S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
3200  S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
3201  S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
3202 
3203  v.x = x / w;
3204  v.y = y / w;
3205 
3206  return v;
3207 }
3208 
3209 template <class S, class T>
3210 inline Vec2<S>
3211 operator * (const Vec2<S> &v, const Matrix33<T> &m)
3212 {
3213  S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
3214  S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
3215  S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
3216 
3217  return Vec2<S> (x / w, y / w);
3218 }
3219 
3220 
3221 template <class S, class T>
3222 inline const Vec3<S> &
3224 {
3225  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
3226  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
3227  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
3228 
3229  v.x = x;
3230  v.y = y;
3231  v.z = z;
3232 
3233  return v;
3234 }
3235 
3236 template <class S, class T>
3237 inline Vec3<S>
3238 operator * (const Vec3<S> &v, const Matrix33<T> &m)
3239 {
3240  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
3241  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
3242  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
3243 
3244  return Vec3<S> (x, y, z);
3245 }
3246 
3247 
3248 template <class S, class T>
3249 inline const Vec3<S> &
3251 {
3252  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
3253  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
3254  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
3255  S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
3256 
3257  v.x = x / w;
3258  v.y = y / w;
3259  v.z = z / w;
3260 
3261  return v;
3262 }
3263 
3264 template <class S, class T>
3265 inline Vec3<S>
3266 operator * (const Vec3<S> &v, const Matrix44<T> &m)
3267 {
3268  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
3269  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
3270  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
3271  S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
3272 
3273  return Vec3<S> (x / w, y / w, z / w);
3274 }
3275 
3276 
3277 template <class S, class T>
3278 inline const Vec4<S> &
3280 {
3281  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
3282  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
3283  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
3284  S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
3285 
3286  v.x = x;
3287  v.y = y;
3288  v.z = z;
3289  v.w = w;
3290 
3291  return v;
3292 }
3293 
3294 template <class S, class T>
3295 inline Vec4<S>
3296 operator * (const Vec4<S> &v, const Matrix44<T> &m)
3297 {
3298  S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
3299  S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
3300  S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
3301  S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
3302 
3303  return Vec4<S> (x, y, z, w);
3304 }
3305 
3306 } // namespace Imath
3307 
3308 
3309 
3310 #endif
const Matrix33 & invert(bool singExc=false)
Definition: ImathMatrix.h:1483
T x
Definition: ImathVec.h:76
static T baseTypeMin()
Definition: ImathMatrix.h:375
Uninitialized
Definition: ImathMatrix.h:63
Matrix44()
Definition: ImathMatrix.h:1811
Matrix33(Uninitialized)
Definition: ImathMatrix.h:84
Definition: ImathShear.h:59
const Matrix33 & shear(const S &xy)
const Vec3< T > translation() const
Definition: ImathMatrix.h:2996
const Matrix33 & operator*=(T a)
Definition: ImathMatrix.h:1210
Matrix33 operator+(const Matrix33 &v) const
Definition: ImathMatrix.h:1114
T y
Definition: ImathVec.h:76
Vec2< T > translation() const
Definition: ImathMatrix.h:1697
Definition: ImathFrame.h:42
const Matrix33 & rotate(S r)
Definition: ImathFrame.h:43
T * operator[](int i)
Definition: ImathMatrix.h:821
Matrix44 operator-() const
Definition: ImathMatrix.h:2315
const Matrix44 & scale(const Vec3< S > &s)
Matrix33 & setValue(const Matrix33< S > &v)
T xy
Definition: ImathShear.h:67
const Matrix44 & rotate(const Vec3< S > &r)
Matrix44 & setTheMatrix(const Matrix44< S > &v)
Matrix44< T > inverse(bool singExc=false) const
Definition: ImathMatrix.h:2731
Definition: ImathMatrix.h:63
const Matrix44 & setAxisAngle(const Vec3< S > &ax, S ang)
static T min()
T * getValue()
Definition: ImathMatrix.h:1988
static T baseTypeMax()
Definition: ImathMatrix.h:746
bool operator!=(const Matrix44 &v) const
Definition: ImathMatrix.h:2129
const Matrix44 & operator-=(const Matrix44 &v)
Definition: ImathMatrix.h:2245
bool equalWithRelError(const Matrix44< T > &v, T e) const
Definition: ImathMatrix.h:2163
const Matrix33 & transpose()
Definition: ImathMatrix.h:1339
const Matrix33 & operator/=(T a)
Definition: ImathMatrix.h:1307
const Matrix33 & setRotation(S r)
Definition: ImathVec.h:63
const Matrix44 & translate(const Vec3< S > &t)
const Matrix44 & operator*=(T a)
Definition: ImathMatrix.h:2361
T abs(T a)
Definition: ImathFun.h:53
const Matrix44 & operator/=(T a)
Definition: ImathMatrix.h:2519
Matrix44< double > M44d
Definition: ImathMatrix.h:812
const Matrix44 & shear(const Vec3< S > &h)
Definition: ImathMatrix.h:66
T xz
Definition: ImathShear.h:67
#define IMATH_RESTRICT
Definition: ImathPlatform.h:108
Matrix33 & setTheMatrix(const Matrix33< S > &v)
const Matrix44 & gjInvert(bool singExc=false)
Definition: ImathMatrix.h:2611
const Matrix33 & operator+=(const Matrix33 &v)
Definition: ImathMatrix.h:1080
const Matrix33 & translate(const Vec2< S > &t)
T * getValue()
Definition: ImathMatrix.h:929
Matrix33< float > M33f
Definition: ImathMatrix.h:809
T x
Definition: ImathVec.h:274
bool equalWithAbsError(T x1, T x2, T e)
Definition: ImathMath.h:191
T y
Definition: ImathVec.h:274
Matrix33< T > gjInverse(bool singExc=false) const
Definition: ImathMatrix.h:1379
static T cos(T x)
Definition: ImathMath.h:97
Matrix33 operator-() const
Definition: ImathMatrix.h:1178
Matrix33 operator/(T a) const
Definition: ImathMatrix.h:1324
T * operator[](int i)
Definition: ImathMatrix.h:1797
bool operator==(const Matrix33 &v) const
Definition: ImathMatrix.h:1026
T z
Definition: ImathVec.h:274
void makeIdentity()
Definition: ImathMatrix.h:1016
const Matrix44 & setEulerAngles(const Vec3< S > &r)
static T smallest()
Vec3< T > normalized() const
Definition: ImathVec.h:1730
static T baseTypeMax()
Definition: ImathMatrix.h:376
Matrix33 transposed() const
Definition: ImathMatrix.h:1356
bool equalWithRelError(T x1, T x2, T e)
Definition: ImathMath.h:199
void multDirMatrix(const Vec2< S > &src, Vec2< S > &dst) const
Definition: ImathMatrix.h:1294
Matrix44(Uninitialized)
Definition: ImathMatrix.h:414
const Matrix44 & invert(bool singExc=false)
Definition: ImathMatrix.h:2723
const Matrix33 & scale(const Vec2< S > &s)
const Matrix33 & setTranslation(const Vec2< S > &t)
Definition: ImathVec.h:61
static void multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &c)
Definition: ImathMatrix.h:2435
T zx
Definition: ImathShear.h:67
Matrix44 operator/(T a) const
Definition: ImathMatrix.h:2543
void multVecMatrix(const Vec2< S > &src, Vec2< S > &dst) const
Definition: ImathMatrix.h:1279
T x
Definition: ImathVec.h:487
Matrix44 & setValue(const Matrix44< S > &v)
bool operator==(const Matrix44 &v) const
Definition: ImathMatrix.h:2107
const Matrix33 & setScale(T s)
Definition: ImathMatrix.h:1636
static T baseTypeMin()
Definition: ImathMatrix.h:745
static T max()
const Matrix44 & operator+=(const Matrix44 &v)
Definition: ImathMatrix.h:2175
Matrix33()
Definition: ImathMatrix.h:835
bool operator!=(const Matrix33 &v) const
Definition: ImathMatrix.h:1041
static T baseTypeEpsilon()
Definition: ImathMatrix.h:378
const Matrix33 & operator=(const Matrix33 &v)
Definition: ImathMatrix.h:905
T yz
Definition: ImathShear.h:67
bool equalWithRelError(const Matrix33< T > &v, T e) const
Definition: ImathMatrix.h:1068
Matrix44 operator*(T a) const
Definition: ImathMatrix.h:2385
const Matrix44 & setTranslation(const Vec3< S > &t)
Definition: ImathBox.h:67
static T epsilon()
T y
Definition: ImathVec.h:487
T zy
Definition: ImathShear.h:67
const Matrix33 & setShear(const S &h)
T z
Definition: ImathVec.h:487
bool equalWithAbsError(const Matrix33< T > &v, T e) const
Definition: ImathMatrix.h:1056
bool equalWithAbsError(const Matrix44< T > &v, T e) const
Definition: ImathMatrix.h:2151
Matrix33< double > M33d
Definition: ImathMatrix.h:810
Matrix33< T > inverse(bool singExc=false) const
Definition: ImathMatrix.h:1491
static T baseTypeSmallest()
Definition: ImathMatrix.h:747
T w
Definition: ImathVec.h:487
Color4< T > operator*(S a, const Color4< T > &v)
Definition: ImathColor.h:727
const Matrix44 & negate()
Definition: ImathMatrix.h:2337
static T sin(T x)
Definition: ImathMath.h:98
Matrix44 transposed() const
Definition: ImathMatrix.h:2589
const Matrix44 & setShear(const Vec3< S > &h)
Matrix44< T > gjInverse(bool singExc=false) const
Definition: ImathMatrix.h:2619
Matrix44< float > M44f
Definition: ImathMatrix.h:811
const Matrix44 & operator=(const Matrix44 &v)
Definition: ImathMatrix.h:1942
const Matrix33 & negate()
Definition: ImathMatrix.h:1193
const Matrix44 & transpose()
Definition: ImathMatrix.h:2565
static T baseTypeSmallest()
Definition: ImathMatrix.h:377
const Vec2< S > & operator*=(Vec2< S > &v, const Matrix33< T > &m)
Definition: ImathMatrix.h:3197
void multDirMatrix(const Vec3< S > &src, Vec3< S > &dst) const
Definition: ImathMatrix.h:2504
Matrix44 operator+(const Matrix44 &v) const
Definition: ImathMatrix.h:2223
void makeIdentity()
Definition: ImathMatrix.h:2096
static T baseTypeEpsilon()
Definition: ImathMatrix.h:748
void multVecMatrix(const Vec3< S > &src, Vec3< S > &dst) const
Definition: ImathMatrix.h:2488
T x[4][4]
Definition: ImathMatrix.h:404
const Matrix33 & gjInvert(bool singExc=false)
Definition: ImathMatrix.h:1371
const Matrix33 & operator-=(const Matrix33 &v)
Definition: ImathMatrix.h:1129
const Matrix44 & setScale(T s)
Definition: ImathMatrix.h:2918
Matrix33 operator*(T a) const
Definition: ImathMatrix.h:1227
T yx
Definition: ImathShear.h:67
T x[3][3]
Definition: ImathMatrix.h:74