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