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