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