Path: blob/master/3rdparty/openexr/Imath/ImathMatrix.h
16337 views
///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////33343536#ifndef INCLUDED_IMATHMATRIX_H37#define INCLUDED_IMATHMATRIX_H3839//----------------------------------------------------------------40//41// 2D (3x3) and 3D (4x4) transformation matrix templates.42//43//----------------------------------------------------------------4445#include "ImathPlatform.h"46#include "ImathFun.h"47#include "ImathExc.h"48#include "ImathVec.h"49#include "ImathShear.h"5051#include <cstring>52#include <iostream>53#include <iomanip>54#include <string.h>5556#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER57// suppress exception specification warnings58#pragma warning(disable:4290)59#endif606162namespace Imath {6364enum Uninitialized {UNINITIALIZED};656667template <class T> class Matrix3368{69public:7071//-------------------72// Access to elements73//-------------------7475T x[3][3];7677T * operator [] (int i);78const T * operator [] (int i) const;798081//-------------82// Constructors83//-------------8485Matrix33 (Uninitialized) {}8687Matrix33 ();88// 1 0 089// 0 1 090// 0 0 19192Matrix33 (T a);93// a a a94// a a a95// a a a9697Matrix33 (const T a[3][3]);98// a[0][0] a[0][1] a[0][2]99// a[1][0] a[1][1] a[1][2]100// a[2][0] a[2][1] a[2][2]101102Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i);103104// a b c105// d e f106// g h i107108109//--------------------------------110// Copy constructor and assignment111//--------------------------------112113Matrix33 (const Matrix33 &v);114template <class S> explicit Matrix33 (const Matrix33<S> &v);115116const Matrix33 & operator = (const Matrix33 &v);117const Matrix33 & operator = (T a);118119120//----------------------121// Compatibility with Sb122//----------------------123124T * getValue ();125const T * getValue () const;126127template <class S>128void getValue (Matrix33<S> &v) const;129template <class S>130Matrix33 & setValue (const Matrix33<S> &v);131132template <class S>133Matrix33 & setTheMatrix (const Matrix33<S> &v);134135136//---------137// Identity138//---------139140void makeIdentity();141142143//---------144// Equality145//---------146147bool operator == (const Matrix33 &v) const;148bool operator != (const Matrix33 &v) const;149150//-----------------------------------------------------------------------151// Compare two matrices and test if they are "approximately equal":152//153// equalWithAbsError (m, e)154//155// Returns true if the coefficients of this and m are the same with156// an absolute error of no more than e, i.e., for all i, j157//158// abs (this[i][j] - m[i][j]) <= e159//160// equalWithRelError (m, e)161//162// Returns true if the coefficients of this and m are the same with163// a relative error of no more than e, i.e., for all i, j164//165// abs (this[i] - v[i][j]) <= e * abs (this[i][j])166//-----------------------------------------------------------------------167168bool equalWithAbsError (const Matrix33<T> &v, T e) const;169bool equalWithRelError (const Matrix33<T> &v, T e) const;170171172//------------------------173// Component-wise addition174//------------------------175176const Matrix33 & operator += (const Matrix33 &v);177const Matrix33 & operator += (T a);178Matrix33 operator + (const Matrix33 &v) const;179180181//---------------------------182// Component-wise subtraction183//---------------------------184185const Matrix33 & operator -= (const Matrix33 &v);186const Matrix33 & operator -= (T a);187Matrix33 operator - (const Matrix33 &v) const;188189190//------------------------------------191// Component-wise multiplication by -1192//------------------------------------193194Matrix33 operator - () const;195const Matrix33 & negate ();196197198//------------------------------199// Component-wise multiplication200//------------------------------201202const Matrix33 & operator *= (T a);203Matrix33 operator * (T a) const;204205206//-----------------------------------207// Matrix-times-matrix multiplication208//-----------------------------------209210const Matrix33 & operator *= (const Matrix33 &v);211Matrix33 operator * (const Matrix33 &v) const;212213214//-----------------------------------------------------------------215// Vector-times-matrix multiplication; see also the "operator *"216// functions defined below.217//218// m.multVecMatrix(src,dst) implements a homogeneous transformation219// by computing Vec3 (src.x, src.y, 1) * m and dividing by the220// result's third element.221//222// m.multDirMatrix(src,dst) multiplies src by the upper left 2x2223// submatrix, ignoring the rest of matrix m.224//-----------------------------------------------------------------225226template <class S>227void multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const;228229template <class S>230void multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const;231232233//------------------------234// Component-wise division235//------------------------236237const Matrix33 & operator /= (T a);238Matrix33 operator / (T a) const;239240241//------------------242// Transposed matrix243//------------------244245const Matrix33 & transpose ();246Matrix33 transposed () const;247248249//------------------------------------------------------------250// Inverse matrix: If singExc is false, inverting a singular251// matrix produces an identity matrix. If singExc is true,252// inverting a singular matrix throws a SingMatrixExc.253//254// inverse() and invert() invert matrices using determinants;255// gjInverse() and gjInvert() use the Gauss-Jordan method.256//257// inverse() and invert() are significantly faster than258// gjInverse() and gjInvert(), but the results may be slightly259// less accurate.260//261//------------------------------------------------------------262263const Matrix33 & invert (bool singExc = false)264throw (Iex::MathExc);265266Matrix33<T> inverse (bool singExc = false) const267throw (Iex::MathExc);268269const Matrix33 & gjInvert (bool singExc = false)270throw (Iex::MathExc);271272Matrix33<T> gjInverse (bool singExc = false) const273throw (Iex::MathExc);274275276//------------------------------------------------277// Calculate the matrix minor of the (r,c) element278//------------------------------------------------279280T minorOf (const int r, const int c) const;281282//---------------------------------------------------283// Build a minor using the specified rows and columns284//---------------------------------------------------285286T fastMinor (const int r0, const int r1,287const int c0, const int c1) const;288289//------------290// Determinant291//------------292293T determinant() const;294295//-----------------------------------------296// Set matrix to rotation by r (in radians)297//-----------------------------------------298299template <class S>300const Matrix33 & setRotation (S r);301302303//-----------------------------304// Rotate the given matrix by r305//-----------------------------306307template <class S>308const Matrix33 & rotate (S r);309310311//--------------------------------------------312// Set matrix to scale by given uniform factor313//--------------------------------------------314315const Matrix33 & setScale (T s);316317318//------------------------------------319// Set matrix to scale by given vector320//------------------------------------321322template <class S>323const Matrix33 & setScale (const Vec2<S> &s);324325326//----------------------327// Scale the matrix by s328//----------------------329330template <class S>331const Matrix33 & scale (const Vec2<S> &s);332333334//------------------------------------------335// Set matrix to translation by given vector336//------------------------------------------337338template <class S>339const Matrix33 & setTranslation (const Vec2<S> &t);340341342//-----------------------------343// Return translation component344//-----------------------------345346Vec2<T> translation () const;347348349//--------------------------350// Translate the matrix by t351//--------------------------352353template <class S>354const Matrix33 & translate (const Vec2<S> &t);355356357//-----------------------------------------------------------358// Set matrix to shear x for each y coord. by given factor xy359//-----------------------------------------------------------360361template <class S>362const Matrix33 & setShear (const S &h);363364365//-------------------------------------------------------------366// Set matrix to shear x for each y coord. by given factor h[0]367// and to shear y for each x coord. by given factor h[1]368//-------------------------------------------------------------369370template <class S>371const Matrix33 & setShear (const Vec2<S> &h);372373374//-----------------------------------------------------------375// Shear the matrix in x for each y coord. by given factor xy376//-----------------------------------------------------------377378template <class S>379const Matrix33 & shear (const S &xy);380381382//-----------------------------------------------------------383// Shear the matrix in x for each y coord. by given factor xy384// and shear y for each x coord. by given factor yx385//-----------------------------------------------------------386387template <class S>388const Matrix33 & shear (const Vec2<S> &h);389390391//--------------------------------------------------------392// Number of the row and column dimensions, since393// Matrix33 is a square matrix.394//--------------------------------------------------------395396static unsigned int dimensions() {return 3;}397398399//-------------------------------------------------400// Limitations of type T (see also class limits<T>)401//-------------------------------------------------402403static T baseTypeMin() {return limits<T>::min();}404static T baseTypeMax() {return limits<T>::max();}405static T baseTypeSmallest() {return limits<T>::smallest();}406static T baseTypeEpsilon() {return limits<T>::epsilon();}407408typedef T BaseType;409typedef Vec3<T> BaseVecType;410411private:412413template <typename R, typename S>414struct isSameType415{416enum {value = 0};417};418419template <typename R>420struct isSameType<R, R>421{422enum {value = 1};423};424};425426427template <class T> class Matrix44428{429public:430431//-------------------432// Access to elements433//-------------------434435T x[4][4];436437T * operator [] (int i);438const T * operator [] (int i) const;439440441//-------------442// Constructors443//-------------444445Matrix44 (Uninitialized) {}446447Matrix44 ();448// 1 0 0 0449// 0 1 0 0450// 0 0 1 0451// 0 0 0 1452453Matrix44 (T a);454// a a a a455// a a a a456// a a a a457// a a a a458459Matrix44 (const T a[4][4]) ;460// a[0][0] a[0][1] a[0][2] a[0][3]461// a[1][0] a[1][1] a[1][2] a[1][3]462// a[2][0] a[2][1] a[2][2] a[2][3]463// a[3][0] a[3][1] a[3][2] a[3][3]464465Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,466T i, T j, T k, T l, T m, T n, T o, T p);467468// a b c d469// e f g h470// i j k l471// m n o p472473Matrix44 (Matrix33<T> r, Vec3<T> t);474// r r r 0475// r r r 0476// r r r 0477// t t t 1478479480//--------------------------------481// Copy constructor and assignment482//--------------------------------483484Matrix44 (const Matrix44 &v);485template <class S> explicit Matrix44 (const Matrix44<S> &v);486487const Matrix44 & operator = (const Matrix44 &v);488const Matrix44 & operator = (T a);489490491//----------------------492// Compatibility with Sb493//----------------------494495T * getValue ();496const T * getValue () const;497498template <class S>499void getValue (Matrix44<S> &v) const;500template <class S>501Matrix44 & setValue (const Matrix44<S> &v);502503template <class S>504Matrix44 & setTheMatrix (const Matrix44<S> &v);505506//---------507// Identity508//---------509510void makeIdentity();511512513//---------514// Equality515//---------516517bool operator == (const Matrix44 &v) const;518bool operator != (const Matrix44 &v) const;519520//-----------------------------------------------------------------------521// Compare two matrices and test if they are "approximately equal":522//523// equalWithAbsError (m, e)524//525// Returns true if the coefficients of this and m are the same with526// an absolute error of no more than e, i.e., for all i, j527//528// abs (this[i][j] - m[i][j]) <= e529//530// equalWithRelError (m, e)531//532// Returns true if the coefficients of this and m are the same with533// a relative error of no more than e, i.e., for all i, j534//535// abs (this[i] - v[i][j]) <= e * abs (this[i][j])536//-----------------------------------------------------------------------537538bool equalWithAbsError (const Matrix44<T> &v, T e) const;539bool equalWithRelError (const Matrix44<T> &v, T e) const;540541542//------------------------543// Component-wise addition544//------------------------545546const Matrix44 & operator += (const Matrix44 &v);547const Matrix44 & operator += (T a);548Matrix44 operator + (const Matrix44 &v) const;549550551//---------------------------552// Component-wise subtraction553//---------------------------554555const Matrix44 & operator -= (const Matrix44 &v);556const Matrix44 & operator -= (T a);557Matrix44 operator - (const Matrix44 &v) const;558559560//------------------------------------561// Component-wise multiplication by -1562//------------------------------------563564Matrix44 operator - () const;565const Matrix44 & negate ();566567568//------------------------------569// Component-wise multiplication570//------------------------------571572const Matrix44 & operator *= (T a);573Matrix44 operator * (T a) const;574575576//-----------------------------------577// Matrix-times-matrix multiplication578//-----------------------------------579580const Matrix44 & operator *= (const Matrix44 &v);581Matrix44 operator * (const Matrix44 &v) const;582583static void multiply (const Matrix44 &a, // assumes that584const Matrix44 &b, // &a != &c and585Matrix44 &c); // &b != &c.586587588//-----------------------------------------------------------------589// Vector-times-matrix multiplication; see also the "operator *"590// functions defined below.591//592// m.multVecMatrix(src,dst) implements a homogeneous transformation593// by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by594// the result's third element.595//596// m.multDirMatrix(src,dst) multiplies src by the upper left 3x3597// submatrix, ignoring the rest of matrix m.598//-----------------------------------------------------------------599600template <class S>601void multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const;602603template <class S>604void multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const;605606607//------------------------608// Component-wise division609//------------------------610611const Matrix44 & operator /= (T a);612Matrix44 operator / (T a) const;613614615//------------------616// Transposed matrix617//------------------618619const Matrix44 & transpose ();620Matrix44 transposed () const;621622623//------------------------------------------------------------624// Inverse matrix: If singExc is false, inverting a singular625// matrix produces an identity matrix. If singExc is true,626// inverting a singular matrix throws a SingMatrixExc.627//628// inverse() and invert() invert matrices using determinants;629// gjInverse() and gjInvert() use the Gauss-Jordan method.630//631// inverse() and invert() are significantly faster than632// gjInverse() and gjInvert(), but the results may be slightly633// less accurate.634//635//------------------------------------------------------------636637const Matrix44 & invert (bool singExc = false)638throw (Iex::MathExc);639640Matrix44<T> inverse (bool singExc = false) const641throw (Iex::MathExc);642643const Matrix44 & gjInvert (bool singExc = false)644throw (Iex::MathExc);645646Matrix44<T> gjInverse (bool singExc = false) const647throw (Iex::MathExc);648649650//------------------------------------------------651// Calculate the matrix minor of the (r,c) element652//------------------------------------------------653654T minorOf (const int r, const int c) const;655656//---------------------------------------------------657// Build a minor using the specified rows and columns658//---------------------------------------------------659660T fastMinor (const int r0, const int r1, const int r2,661const int c0, const int c1, const int c2) const;662663//------------664// Determinant665//------------666667T determinant() const;668669//--------------------------------------------------------670// Set matrix to rotation by XYZ euler angles (in radians)671//--------------------------------------------------------672673template <class S>674const Matrix44 & setEulerAngles (const Vec3<S>& r);675676677//--------------------------------------------------------678// Set matrix to rotation around given axis by given angle679//--------------------------------------------------------680681template <class S>682const Matrix44 & setAxisAngle (const Vec3<S>& ax, S ang);683684685//-------------------------------------------686// Rotate the matrix by XYZ euler angles in r687//-------------------------------------------688689template <class S>690const Matrix44 & rotate (const Vec3<S> &r);691692693//--------------------------------------------694// Set matrix to scale by given uniform factor695//--------------------------------------------696697const Matrix44 & setScale (T s);698699700//------------------------------------701// Set matrix to scale by given vector702//------------------------------------703704template <class S>705const Matrix44 & setScale (const Vec3<S> &s);706707708//----------------------709// Scale the matrix by s710//----------------------711712template <class S>713const Matrix44 & scale (const Vec3<S> &s);714715716//------------------------------------------717// Set matrix to translation by given vector718//------------------------------------------719720template <class S>721const Matrix44 & setTranslation (const Vec3<S> &t);722723724//-----------------------------725// Return translation component726//-----------------------------727728const Vec3<T> translation () const;729730731//--------------------------732// Translate the matrix by t733//--------------------------734735template <class S>736const Matrix44 & translate (const Vec3<S> &t);737738739//-------------------------------------------------------------740// Set matrix to shear by given vector h. The resulting matrix741// will shear x for each y coord. by a factor of h[0] ;742// will shear x for each z coord. by a factor of h[1] ;743// will shear y for each z coord. by a factor of h[2] .744//-------------------------------------------------------------745746template <class S>747const Matrix44 & setShear (const Vec3<S> &h);748749750//------------------------------------------------------------751// Set matrix to shear by given factors. The resulting matrix752// will shear x for each y coord. by a factor of h.xy ;753// will shear x for each z coord. by a factor of h.xz ;754// will shear y for each z coord. by a factor of h.yz ;755// will shear y for each x coord. by a factor of h.yx ;756// will shear z for each x coord. by a factor of h.zx ;757// will shear z for each y coord. by a factor of h.zy .758//------------------------------------------------------------759760template <class S>761const Matrix44 & setShear (const Shear6<S> &h);762763764//--------------------------------------------------------765// Shear the matrix by given vector. The composed matrix766// will be <shear> * <this>, where the shear matrix ...767// will shear x for each y coord. by a factor of h[0] ;768// will shear x for each z coord. by a factor of h[1] ;769// will shear y for each z coord. by a factor of h[2] .770//--------------------------------------------------------771772template <class S>773const Matrix44 & shear (const Vec3<S> &h);774775//--------------------------------------------------------776// Number of the row and column dimensions, since777// Matrix44 is a square matrix.778//--------------------------------------------------------779780static unsigned int dimensions() {return 4;}781782783//------------------------------------------------------------784// Shear the matrix by the given factors. The composed matrix785// will be <shear> * <this>, where the shear matrix ...786// will shear x for each y coord. by a factor of h.xy ;787// will shear x for each z coord. by a factor of h.xz ;788// will shear y for each z coord. by a factor of h.yz ;789// will shear y for each x coord. by a factor of h.yx ;790// will shear z for each x coord. by a factor of h.zx ;791// will shear z for each y coord. by a factor of h.zy .792//------------------------------------------------------------793794template <class S>795const Matrix44 & shear (const Shear6<S> &h);796797798//-------------------------------------------------799// Limitations of type T (see also class limits<T>)800//-------------------------------------------------801802static T baseTypeMin() {return limits<T>::min();}803static T baseTypeMax() {return limits<T>::max();}804static T baseTypeSmallest() {return limits<T>::smallest();}805static T baseTypeEpsilon() {return limits<T>::epsilon();}806807typedef T BaseType;808typedef Vec4<T> BaseVecType;809810private:811812template <typename R, typename S>813struct isSameType814{815enum {value = 0};816};817818template <typename R>819struct isSameType<R, R>820{821enum {value = 1};822};823};824825826//--------------827// Stream output828//--------------829830template <class T>831std::ostream & operator << (std::ostream & s, const Matrix33<T> &m);832833template <class T>834std::ostream & operator << (std::ostream & s, const Matrix44<T> &m);835836837//---------------------------------------------838// Vector-times-matrix multiplication operators839//---------------------------------------------840841template <class S, class T>842const Vec2<S> & operator *= (Vec2<S> &v, const Matrix33<T> &m);843844template <class S, class T>845Vec2<S> operator * (const Vec2<S> &v, const Matrix33<T> &m);846847template <class S, class T>848const Vec3<S> & operator *= (Vec3<S> &v, const Matrix33<T> &m);849850template <class S, class T>851Vec3<S> operator * (const Vec3<S> &v, const Matrix33<T> &m);852853template <class S, class T>854const Vec3<S> & operator *= (Vec3<S> &v, const Matrix44<T> &m);855856template <class S, class T>857Vec3<S> operator * (const Vec3<S> &v, const Matrix44<T> &m);858859template <class S, class T>860const Vec4<S> & operator *= (Vec4<S> &v, const Matrix44<T> &m);861862template <class S, class T>863Vec4<S> operator * (const Vec4<S> &v, const Matrix44<T> &m);864865//-------------------------866// Typedefs for convenience867//-------------------------868869typedef Matrix33 <float> M33f;870typedef Matrix33 <double> M33d;871typedef Matrix44 <float> M44f;872typedef Matrix44 <double> M44d;873874875//---------------------------876// Implementation of Matrix33877//---------------------------878879template <class T>880inline T *881Matrix33<T>::operator [] (int i)882{883return x[i];884}885886template <class T>887inline const T *888Matrix33<T>::operator [] (int i) const889{890return x[i];891}892893template <class T>894inline895Matrix33<T>::Matrix33 ()896{897memset (x, 0, sizeof (x));898x[0][0] = 1;899x[1][1] = 1;900x[2][2] = 1;901}902903template <class T>904inline905Matrix33<T>::Matrix33 (T a)906{907x[0][0] = a;908x[0][1] = a;909x[0][2] = a;910x[1][0] = a;911x[1][1] = a;912x[1][2] = a;913x[2][0] = a;914x[2][1] = a;915x[2][2] = a;916}917918template <class T>919inline920Matrix33<T>::Matrix33 (const T a[3][3])921{922memcpy (x, a, sizeof (x));923}924925template <class T>926inline927Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i)928{929x[0][0] = a;930x[0][1] = b;931x[0][2] = c;932x[1][0] = d;933x[1][1] = e;934x[1][2] = f;935x[2][0] = g;936x[2][1] = h;937x[2][2] = i;938}939940template <class T>941inline942Matrix33<T>::Matrix33 (const Matrix33 &v)943{944memcpy (x, v.x, sizeof (x));945}946947template <class T>948template <class S>949inline950Matrix33<T>::Matrix33 (const Matrix33<S> &v)951{952x[0][0] = T (v.x[0][0]);953x[0][1] = T (v.x[0][1]);954x[0][2] = T (v.x[0][2]);955x[1][0] = T (v.x[1][0]);956x[1][1] = T (v.x[1][1]);957x[1][2] = T (v.x[1][2]);958x[2][0] = T (v.x[2][0]);959x[2][1] = T (v.x[2][1]);960x[2][2] = T (v.x[2][2]);961}962963template <class T>964inline const Matrix33<T> &965Matrix33<T>::operator = (const Matrix33 &v)966{967memcpy (x, v.x, sizeof (x));968return *this;969}970971template <class T>972inline const Matrix33<T> &973Matrix33<T>::operator = (T a)974{975x[0][0] = a;976x[0][1] = a;977x[0][2] = a;978x[1][0] = a;979x[1][1] = a;980x[1][2] = a;981x[2][0] = a;982x[2][1] = a;983x[2][2] = a;984return *this;985}986987template <class T>988inline T *989Matrix33<T>::getValue ()990{991return (T *) &x[0][0];992}993994template <class T>995inline const T *996Matrix33<T>::getValue () const997{998return (const T *) &x[0][0];999}10001001template <class T>1002template <class S>1003inline void1004Matrix33<T>::getValue (Matrix33<S> &v) const1005{1006if (isSameType<S,T>::value)1007{1008memcpy (v.x, x, sizeof (x));1009}1010else1011{1012v.x[0][0] = x[0][0];1013v.x[0][1] = x[0][1];1014v.x[0][2] = x[0][2];1015v.x[1][0] = x[1][0];1016v.x[1][1] = x[1][1];1017v.x[1][2] = x[1][2];1018v.x[2][0] = x[2][0];1019v.x[2][1] = x[2][1];1020v.x[2][2] = x[2][2];1021}1022}10231024template <class T>1025template <class S>1026inline Matrix33<T> &1027Matrix33<T>::setValue (const Matrix33<S> &v)1028{1029if (isSameType<S,T>::value)1030{1031memcpy (x, v.x, sizeof (x));1032}1033else1034{1035x[0][0] = v.x[0][0];1036x[0][1] = v.x[0][1];1037x[0][2] = v.x[0][2];1038x[1][0] = v.x[1][0];1039x[1][1] = v.x[1][1];1040x[1][2] = v.x[1][2];1041x[2][0] = v.x[2][0];1042x[2][1] = v.x[2][1];1043x[2][2] = v.x[2][2];1044}10451046return *this;1047}10481049template <class T>1050template <class S>1051inline Matrix33<T> &1052Matrix33<T>::setTheMatrix (const Matrix33<S> &v)1053{1054if (isSameType<S,T>::value)1055{1056memcpy (x, v.x, sizeof (x));1057}1058else1059{1060x[0][0] = v.x[0][0];1061x[0][1] = v.x[0][1];1062x[0][2] = v.x[0][2];1063x[1][0] = v.x[1][0];1064x[1][1] = v.x[1][1];1065x[1][2] = v.x[1][2];1066x[2][0] = v.x[2][0];1067x[2][1] = v.x[2][1];1068x[2][2] = v.x[2][2];1069}10701071return *this;1072}10731074template <class T>1075inline void1076Matrix33<T>::makeIdentity()1077{1078memset (x, 0, sizeof (x));1079x[0][0] = 1;1080x[1][1] = 1;1081x[2][2] = 1;1082}10831084template <class T>1085bool1086Matrix33<T>::operator == (const Matrix33 &v) const1087{1088return x[0][0] == v.x[0][0] &&1089x[0][1] == v.x[0][1] &&1090x[0][2] == v.x[0][2] &&1091x[1][0] == v.x[1][0] &&1092x[1][1] == v.x[1][1] &&1093x[1][2] == v.x[1][2] &&1094x[2][0] == v.x[2][0] &&1095x[2][1] == v.x[2][1] &&1096x[2][2] == v.x[2][2];1097}10981099template <class T>1100bool1101Matrix33<T>::operator != (const Matrix33 &v) const1102{1103return x[0][0] != v.x[0][0] ||1104x[0][1] != v.x[0][1] ||1105x[0][2] != v.x[0][2] ||1106x[1][0] != v.x[1][0] ||1107x[1][1] != v.x[1][1] ||1108x[1][2] != v.x[1][2] ||1109x[2][0] != v.x[2][0] ||1110x[2][1] != v.x[2][1] ||1111x[2][2] != v.x[2][2];1112}11131114template <class T>1115bool1116Matrix33<T>::equalWithAbsError (const Matrix33<T> &m, T e) const1117{1118for (int i = 0; i < 3; i++)1119for (int j = 0; j < 3; j++)1120if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))1121return false;11221123return true;1124}11251126template <class T>1127bool1128Matrix33<T>::equalWithRelError (const Matrix33<T> &m, T e) const1129{1130for (int i = 0; i < 3; i++)1131for (int j = 0; j < 3; j++)1132if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))1133return false;11341135return true;1136}11371138template <class T>1139const Matrix33<T> &1140Matrix33<T>::operator += (const Matrix33<T> &v)1141{1142x[0][0] += v.x[0][0];1143x[0][1] += v.x[0][1];1144x[0][2] += v.x[0][2];1145x[1][0] += v.x[1][0];1146x[1][1] += v.x[1][1];1147x[1][2] += v.x[1][2];1148x[2][0] += v.x[2][0];1149x[2][1] += v.x[2][1];1150x[2][2] += v.x[2][2];11511152return *this;1153}11541155template <class T>1156const Matrix33<T> &1157Matrix33<T>::operator += (T a)1158{1159x[0][0] += a;1160x[0][1] += a;1161x[0][2] += a;1162x[1][0] += a;1163x[1][1] += a;1164x[1][2] += a;1165x[2][0] += a;1166x[2][1] += a;1167x[2][2] += a;11681169return *this;1170}11711172template <class T>1173Matrix33<T>1174Matrix33<T>::operator + (const Matrix33<T> &v) const1175{1176return Matrix33 (x[0][0] + v.x[0][0],1177x[0][1] + v.x[0][1],1178x[0][2] + v.x[0][2],1179x[1][0] + v.x[1][0],1180x[1][1] + v.x[1][1],1181x[1][2] + v.x[1][2],1182x[2][0] + v.x[2][0],1183x[2][1] + v.x[2][1],1184x[2][2] + v.x[2][2]);1185}11861187template <class T>1188const Matrix33<T> &1189Matrix33<T>::operator -= (const Matrix33<T> &v)1190{1191x[0][0] -= v.x[0][0];1192x[0][1] -= v.x[0][1];1193x[0][2] -= v.x[0][2];1194x[1][0] -= v.x[1][0];1195x[1][1] -= v.x[1][1];1196x[1][2] -= v.x[1][2];1197x[2][0] -= v.x[2][0];1198x[2][1] -= v.x[2][1];1199x[2][2] -= v.x[2][2];12001201return *this;1202}12031204template <class T>1205const Matrix33<T> &1206Matrix33<T>::operator -= (T a)1207{1208x[0][0] -= a;1209x[0][1] -= a;1210x[0][2] -= a;1211x[1][0] -= a;1212x[1][1] -= a;1213x[1][2] -= a;1214x[2][0] -= a;1215x[2][1] -= a;1216x[2][2] -= a;12171218return *this;1219}12201221template <class T>1222Matrix33<T>1223Matrix33<T>::operator - (const Matrix33<T> &v) const1224{1225return Matrix33 (x[0][0] - v.x[0][0],1226x[0][1] - v.x[0][1],1227x[0][2] - v.x[0][2],1228x[1][0] - v.x[1][0],1229x[1][1] - v.x[1][1],1230x[1][2] - v.x[1][2],1231x[2][0] - v.x[2][0],1232x[2][1] - v.x[2][1],1233x[2][2] - v.x[2][2]);1234}12351236template <class T>1237Matrix33<T>1238Matrix33<T>::operator - () const1239{1240return Matrix33 (-x[0][0],1241-x[0][1],1242-x[0][2],1243-x[1][0],1244-x[1][1],1245-x[1][2],1246-x[2][0],1247-x[2][1],1248-x[2][2]);1249}12501251template <class T>1252const Matrix33<T> &1253Matrix33<T>::negate ()1254{1255x[0][0] = -x[0][0];1256x[0][1] = -x[0][1];1257x[0][2] = -x[0][2];1258x[1][0] = -x[1][0];1259x[1][1] = -x[1][1];1260x[1][2] = -x[1][2];1261x[2][0] = -x[2][0];1262x[2][1] = -x[2][1];1263x[2][2] = -x[2][2];12641265return *this;1266}12671268template <class T>1269const Matrix33<T> &1270Matrix33<T>::operator *= (T a)1271{1272x[0][0] *= a;1273x[0][1] *= a;1274x[0][2] *= a;1275x[1][0] *= a;1276x[1][1] *= a;1277x[1][2] *= a;1278x[2][0] *= a;1279x[2][1] *= a;1280x[2][2] *= a;12811282return *this;1283}12841285template <class T>1286Matrix33<T>1287Matrix33<T>::operator * (T a) const1288{1289return Matrix33 (x[0][0] * a,1290x[0][1] * a,1291x[0][2] * a,1292x[1][0] * a,1293x[1][1] * a,1294x[1][2] * a,1295x[2][0] * a,1296x[2][1] * a,1297x[2][2] * a);1298}12991300template <class T>1301inline Matrix33<T>1302operator * (T a, const Matrix33<T> &v)1303{1304return v * a;1305}13061307template <class T>1308const Matrix33<T> &1309Matrix33<T>::operator *= (const Matrix33<T> &v)1310{1311Matrix33 tmp (T (0));13121313for (int i = 0; i < 3; i++)1314for (int j = 0; j < 3; j++)1315for (int k = 0; k < 3; k++)1316tmp.x[i][j] += x[i][k] * v.x[k][j];13171318*this = tmp;1319return *this;1320}13211322template <class T>1323Matrix33<T>1324Matrix33<T>::operator * (const Matrix33<T> &v) const1325{1326Matrix33 tmp (T (0));13271328for (int i = 0; i < 3; i++)1329for (int j = 0; j < 3; j++)1330for (int k = 0; k < 3; k++)1331tmp.x[i][j] += x[i][k] * v.x[k][j];13321333return tmp;1334}13351336template <class T>1337template <class S>1338void1339Matrix33<T>::multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const1340{1341S a, b, w;13421343a = src[0] * x[0][0] + src[1] * x[1][0] + x[2][0];1344b = src[0] * x[0][1] + src[1] * x[1][1] + x[2][1];1345w = src[0] * x[0][2] + src[1] * x[1][2] + x[2][2];13461347dst.x = a / w;1348dst.y = b / w;1349}13501351template <class T>1352template <class S>1353void1354Matrix33<T>::multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const1355{1356S a, b;13571358a = src[0] * x[0][0] + src[1] * x[1][0];1359b = src[0] * x[0][1] + src[1] * x[1][1];13601361dst.x = a;1362dst.y = b;1363}13641365template <class T>1366const Matrix33<T> &1367Matrix33<T>::operator /= (T a)1368{1369x[0][0] /= a;1370x[0][1] /= a;1371x[0][2] /= a;1372x[1][0] /= a;1373x[1][1] /= a;1374x[1][2] /= a;1375x[2][0] /= a;1376x[2][1] /= a;1377x[2][2] /= a;13781379return *this;1380}13811382template <class T>1383Matrix33<T>1384Matrix33<T>::operator / (T a) const1385{1386return Matrix33 (x[0][0] / a,1387x[0][1] / a,1388x[0][2] / a,1389x[1][0] / a,1390x[1][1] / a,1391x[1][2] / a,1392x[2][0] / a,1393x[2][1] / a,1394x[2][2] / a);1395}13961397template <class T>1398const Matrix33<T> &1399Matrix33<T>::transpose ()1400{1401Matrix33 tmp (x[0][0],1402x[1][0],1403x[2][0],1404x[0][1],1405x[1][1],1406x[2][1],1407x[0][2],1408x[1][2],1409x[2][2]);1410*this = tmp;1411return *this;1412}14131414template <class T>1415Matrix33<T>1416Matrix33<T>::transposed () const1417{1418return Matrix33 (x[0][0],1419x[1][0],1420x[2][0],1421x[0][1],1422x[1][1],1423x[2][1],1424x[0][2],1425x[1][2],1426x[2][2]);1427}14281429template <class T>1430const Matrix33<T> &1431Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)1432{1433*this = gjInverse (singExc);1434return *this;1435}14361437template <class T>1438Matrix33<T>1439Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)1440{1441int i, j, k;1442Matrix33 s;1443Matrix33 t (*this);14441445// Forward elimination14461447for (i = 0; i < 2 ; i++)1448{1449int pivot = i;14501451T pivotsize = t[i][i];14521453if (pivotsize < 0)1454pivotsize = -pivotsize;14551456for (j = i + 1; j < 3; j++)1457{1458T tmp = t[j][i];14591460if (tmp < 0)1461tmp = -tmp;14621463if (tmp > pivotsize)1464{1465pivot = j;1466pivotsize = tmp;1467}1468}14691470if (pivotsize == 0)1471{1472if (singExc)1473throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");14741475return Matrix33();1476}14771478if (pivot != i)1479{1480for (j = 0; j < 3; j++)1481{1482T tmp;14831484tmp = t[i][j];1485t[i][j] = t[pivot][j];1486t[pivot][j] = tmp;14871488tmp = s[i][j];1489s[i][j] = s[pivot][j];1490s[pivot][j] = tmp;1491}1492}14931494for (j = i + 1; j < 3; j++)1495{1496T f = t[j][i] / t[i][i];14971498for (k = 0; k < 3; k++)1499{1500t[j][k] -= f * t[i][k];1501s[j][k] -= f * s[i][k];1502}1503}1504}15051506// Backward substitution15071508for (i = 2; i >= 0; --i)1509{1510T f;15111512if ((f = t[i][i]) == 0)1513{1514if (singExc)1515throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");15161517return Matrix33();1518}15191520for (j = 0; j < 3; j++)1521{1522t[i][j] /= f;1523s[i][j] /= f;1524}15251526for (j = 0; j < i; j++)1527{1528f = t[j][i];15291530for (k = 0; k < 3; k++)1531{1532t[j][k] -= f * t[i][k];1533s[j][k] -= f * s[i][k];1534}1535}1536}15371538return s;1539}15401541template <class T>1542const Matrix33<T> &1543Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)1544{1545*this = inverse (singExc);1546return *this;1547}15481549template <class T>1550Matrix33<T>1551Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)1552{1553if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)1554{1555Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],1556x[2][1] * x[0][2] - x[0][1] * x[2][2],1557x[0][1] * x[1][2] - x[1][1] * x[0][2],15581559x[2][0] * x[1][2] - x[1][0] * x[2][2],1560x[0][0] * x[2][2] - x[2][0] * x[0][2],1561x[1][0] * x[0][2] - x[0][0] * x[1][2],15621563x[1][0] * x[2][1] - x[2][0] * x[1][1],1564x[2][0] * x[0][1] - x[0][0] * x[2][1],1565x[0][0] * x[1][1] - x[1][0] * x[0][1]);15661567T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];15681569if (Imath::abs (r) >= 1)1570{1571for (int i = 0; i < 3; ++i)1572{1573for (int j = 0; j < 3; ++j)1574{1575s[i][j] /= r;1576}1577}1578}1579else1580{1581T mr = Imath::abs (r) / limits<T>::smallest();15821583for (int i = 0; i < 3; ++i)1584{1585for (int j = 0; j < 3; ++j)1586{1587if (mr > Imath::abs (s[i][j]))1588{1589s[i][j] /= r;1590}1591else1592{1593if (singExc)1594throw SingMatrixExc ("Cannot invert "1595"singular matrix.");1596return Matrix33();1597}1598}1599}1600}16011602return s;1603}1604else1605{1606Matrix33 s ( x[1][1],1607-x[0][1],16080,16091610-x[1][0],1611x[0][0],16120,161316140,16150,16161);16171618T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];16191620if (Imath::abs (r) >= 1)1621{1622for (int i = 0; i < 2; ++i)1623{1624for (int j = 0; j < 2; ++j)1625{1626s[i][j] /= r;1627}1628}1629}1630else1631{1632T mr = Imath::abs (r) / limits<T>::smallest();16331634for (int i = 0; i < 2; ++i)1635{1636for (int j = 0; j < 2; ++j)1637{1638if (mr > Imath::abs (s[i][j]))1639{1640s[i][j] /= r;1641}1642else1643{1644if (singExc)1645throw SingMatrixExc ("Cannot invert "1646"singular matrix.");1647return Matrix33();1648}1649}1650}1651}16521653s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0];1654s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1];16551656return s;1657}1658}16591660template <class T>1661inline T1662Matrix33<T>::minorOf (const int r, const int c) const1663{1664int r0 = 0 + (r < 1 ? 1 : 0);1665int r1 = 1 + (r < 2 ? 1 : 0);1666int c0 = 0 + (c < 1 ? 1 : 0);1667int c1 = 1 + (c < 2 ? 1 : 0);16681669return x[r0][c0]*x[r1][c1] - x[r1][c0]*x[r0][c1];1670}16711672template <class T>1673inline T1674Matrix33<T>::fastMinor( const int r0, const int r1,1675const int c0, const int c1) const1676{1677return x[r0][c0]*x[r1][c1] - x[r0][c1]*x[r1][c0];1678}16791680template <class T>1681inline T1682Matrix33<T>::determinant () const1683{1684return x[0][0]*(x[1][1]*x[2][2] - x[1][2]*x[2][1]) +1685x[0][1]*(x[1][2]*x[2][0] - x[1][0]*x[2][2]) +1686x[0][2]*(x[1][0]*x[2][1] - x[1][1]*x[2][0]);1687}16881689template <class T>1690template <class S>1691const Matrix33<T> &1692Matrix33<T>::setRotation (S r)1693{1694S cos_r, sin_r;16951696cos_r = Math<T>::cos (r);1697sin_r = Math<T>::sin (r);16981699x[0][0] = cos_r;1700x[0][1] = sin_r;1701x[0][2] = 0;17021703x[1][0] = -sin_r;1704x[1][1] = cos_r;1705x[1][2] = 0;17061707x[2][0] = 0;1708x[2][1] = 0;1709x[2][2] = 1;17101711return *this;1712}17131714template <class T>1715template <class S>1716const Matrix33<T> &1717Matrix33<T>::rotate (S r)1718{1719*this *= Matrix33<T>().setRotation (r);1720return *this;1721}17221723template <class T>1724const Matrix33<T> &1725Matrix33<T>::setScale (T s)1726{1727memset (x, 0, sizeof (x));1728x[0][0] = s;1729x[1][1] = s;1730x[2][2] = 1;17311732return *this;1733}17341735template <class T>1736template <class S>1737const Matrix33<T> &1738Matrix33<T>::setScale (const Vec2<S> &s)1739{1740memset (x, 0, sizeof (x));1741x[0][0] = s[0];1742x[1][1] = s[1];1743x[2][2] = 1;17441745return *this;1746}17471748template <class T>1749template <class S>1750const Matrix33<T> &1751Matrix33<T>::scale (const Vec2<S> &s)1752{1753x[0][0] *= s[0];1754x[0][1] *= s[0];1755x[0][2] *= s[0];17561757x[1][0] *= s[1];1758x[1][1] *= s[1];1759x[1][2] *= s[1];17601761return *this;1762}17631764template <class T>1765template <class S>1766const Matrix33<T> &1767Matrix33<T>::setTranslation (const Vec2<S> &t)1768{1769x[0][0] = 1;1770x[0][1] = 0;1771x[0][2] = 0;17721773x[1][0] = 0;1774x[1][1] = 1;1775x[1][2] = 0;17761777x[2][0] = t[0];1778x[2][1] = t[1];1779x[2][2] = 1;17801781return *this;1782}17831784template <class T>1785inline Vec2<T>1786Matrix33<T>::translation () const1787{1788return Vec2<T> (x[2][0], x[2][1]);1789}17901791template <class T>1792template <class S>1793const Matrix33<T> &1794Matrix33<T>::translate (const Vec2<S> &t)1795{1796x[2][0] += t[0] * x[0][0] + t[1] * x[1][0];1797x[2][1] += t[0] * x[0][1] + t[1] * x[1][1];1798x[2][2] += t[0] * x[0][2] + t[1] * x[1][2];17991800return *this;1801}18021803template <class T>1804template <class S>1805const Matrix33<T> &1806Matrix33<T>::setShear (const S &xy)1807{1808x[0][0] = 1;1809x[0][1] = 0;1810x[0][2] = 0;18111812x[1][0] = xy;1813x[1][1] = 1;1814x[1][2] = 0;18151816x[2][0] = 0;1817x[2][1] = 0;1818x[2][2] = 1;18191820return *this;1821}18221823template <class T>1824template <class S>1825const Matrix33<T> &1826Matrix33<T>::setShear (const Vec2<S> &h)1827{1828x[0][0] = 1;1829x[0][1] = h[1];1830x[0][2] = 0;18311832x[1][0] = h[0];1833x[1][1] = 1;1834x[1][2] = 0;18351836x[2][0] = 0;1837x[2][1] = 0;1838x[2][2] = 1;18391840return *this;1841}18421843template <class T>1844template <class S>1845const Matrix33<T> &1846Matrix33<T>::shear (const S &xy)1847{1848//1849// In this case, we don't need a temp. copy of the matrix1850// because we never use a value on the RHS after we've1851// changed it on the LHS.1852//18531854x[1][0] += xy * x[0][0];1855x[1][1] += xy * x[0][1];1856x[1][2] += xy * x[0][2];18571858return *this;1859}18601861template <class T>1862template <class S>1863const Matrix33<T> &1864Matrix33<T>::shear (const Vec2<S> &h)1865{1866Matrix33<T> P (*this);18671868x[0][0] = P[0][0] + h[1] * P[1][0];1869x[0][1] = P[0][1] + h[1] * P[1][1];1870x[0][2] = P[0][2] + h[1] * P[1][2];18711872x[1][0] = P[1][0] + h[0] * P[0][0];1873x[1][1] = P[1][1] + h[0] * P[0][1];1874x[1][2] = P[1][2] + h[0] * P[0][2];18751876return *this;1877}187818791880//---------------------------1881// Implementation of Matrix441882//---------------------------18831884template <class T>1885inline T *1886Matrix44<T>::operator [] (int i)1887{1888return x[i];1889}18901891template <class T>1892inline const T *1893Matrix44<T>::operator [] (int i) const1894{1895return x[i];1896}18971898template <class T>1899inline1900Matrix44<T>::Matrix44 ()1901{1902memset (x, 0, sizeof (x));1903x[0][0] = 1;1904x[1][1] = 1;1905x[2][2] = 1;1906x[3][3] = 1;1907}19081909template <class T>1910inline1911Matrix44<T>::Matrix44 (T a)1912{1913x[0][0] = a;1914x[0][1] = a;1915x[0][2] = a;1916x[0][3] = a;1917x[1][0] = a;1918x[1][1] = a;1919x[1][2] = a;1920x[1][3] = a;1921x[2][0] = a;1922x[2][1] = a;1923x[2][2] = a;1924x[2][3] = a;1925x[3][0] = a;1926x[3][1] = a;1927x[3][2] = a;1928x[3][3] = a;1929}19301931template <class T>1932inline1933Matrix44<T>::Matrix44 (const T a[4][4])1934{1935memcpy (x, a, sizeof (x));1936}19371938template <class T>1939inline1940Matrix44<T>::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h,1941T i, T j, T k, T l, T m, T n, T o, T p)1942{1943x[0][0] = a;1944x[0][1] = b;1945x[0][2] = c;1946x[0][3] = d;1947x[1][0] = e;1948x[1][1] = f;1949x[1][2] = g;1950x[1][3] = h;1951x[2][0] = i;1952x[2][1] = j;1953x[2][2] = k;1954x[2][3] = l;1955x[3][0] = m;1956x[3][1] = n;1957x[3][2] = o;1958x[3][3] = p;1959}196019611962template <class T>1963inline1964Matrix44<T>::Matrix44 (Matrix33<T> r, Vec3<T> t)1965{1966x[0][0] = r[0][0];1967x[0][1] = r[0][1];1968x[0][2] = r[0][2];1969x[0][3] = 0;1970x[1][0] = r[1][0];1971x[1][1] = r[1][1];1972x[1][2] = r[1][2];1973x[1][3] = 0;1974x[2][0] = r[2][0];1975x[2][1] = r[2][1];1976x[2][2] = r[2][2];1977x[2][3] = 0;1978x[3][0] = t[0];1979x[3][1] = t[1];1980x[3][2] = t[2];1981x[3][3] = 1;1982}19831984template <class T>1985inline1986Matrix44<T>::Matrix44 (const Matrix44 &v)1987{1988x[0][0] = v.x[0][0];1989x[0][1] = v.x[0][1];1990x[0][2] = v.x[0][2];1991x[0][3] = v.x[0][3];1992x[1][0] = v.x[1][0];1993x[1][1] = v.x[1][1];1994x[1][2] = v.x[1][2];1995x[1][3] = v.x[1][3];1996x[2][0] = v.x[2][0];1997x[2][1] = v.x[2][1];1998x[2][2] = v.x[2][2];1999x[2][3] = v.x[2][3];2000x[3][0] = v.x[3][0];2001x[3][1] = v.x[3][1];2002x[3][2] = v.x[3][2];2003x[3][3] = v.x[3][3];2004}20052006template <class T>2007template <class S>2008inline2009Matrix44<T>::Matrix44 (const Matrix44<S> &v)2010{2011x[0][0] = T (v.x[0][0]);2012x[0][1] = T (v.x[0][1]);2013x[0][2] = T (v.x[0][2]);2014x[0][3] = T (v.x[0][3]);2015x[1][0] = T (v.x[1][0]);2016x[1][1] = T (v.x[1][1]);2017x[1][2] = T (v.x[1][2]);2018x[1][3] = T (v.x[1][3]);2019x[2][0] = T (v.x[2][0]);2020x[2][1] = T (v.x[2][1]);2021x[2][2] = T (v.x[2][2]);2022x[2][3] = T (v.x[2][3]);2023x[3][0] = T (v.x[3][0]);2024x[3][1] = T (v.x[3][1]);2025x[3][2] = T (v.x[3][2]);2026x[3][3] = T (v.x[3][3]);2027}20282029template <class T>2030inline const Matrix44<T> &2031Matrix44<T>::operator = (const Matrix44 &v)2032{2033x[0][0] = v.x[0][0];2034x[0][1] = v.x[0][1];2035x[0][2] = v.x[0][2];2036x[0][3] = v.x[0][3];2037x[1][0] = v.x[1][0];2038x[1][1] = v.x[1][1];2039x[1][2] = v.x[1][2];2040x[1][3] = v.x[1][3];2041x[2][0] = v.x[2][0];2042x[2][1] = v.x[2][1];2043x[2][2] = v.x[2][2];2044x[2][3] = v.x[2][3];2045x[3][0] = v.x[3][0];2046x[3][1] = v.x[3][1];2047x[3][2] = v.x[3][2];2048x[3][3] = v.x[3][3];2049return *this;2050}20512052template <class T>2053inline const Matrix44<T> &2054Matrix44<T>::operator = (T a)2055{2056x[0][0] = a;2057x[0][1] = a;2058x[0][2] = a;2059x[0][3] = a;2060x[1][0] = a;2061x[1][1] = a;2062x[1][2] = a;2063x[1][3] = a;2064x[2][0] = a;2065x[2][1] = a;2066x[2][2] = a;2067x[2][3] = a;2068x[3][0] = a;2069x[3][1] = a;2070x[3][2] = a;2071x[3][3] = a;2072return *this;2073}20742075template <class T>2076inline T *2077Matrix44<T>::getValue ()2078{2079return (T *) &x[0][0];2080}20812082template <class T>2083inline const T *2084Matrix44<T>::getValue () const2085{2086return (const T *) &x[0][0];2087}20882089template <class T>2090template <class S>2091inline void2092Matrix44<T>::getValue (Matrix44<S> &v) const2093{2094if (isSameType<S,T>::value)2095{2096memcpy (v.x, x, sizeof (x));2097}2098else2099{2100v.x[0][0] = x[0][0];2101v.x[0][1] = x[0][1];2102v.x[0][2] = x[0][2];2103v.x[0][3] = x[0][3];2104v.x[1][0] = x[1][0];2105v.x[1][1] = x[1][1];2106v.x[1][2] = x[1][2];2107v.x[1][3] = x[1][3];2108v.x[2][0] = x[2][0];2109v.x[2][1] = x[2][1];2110v.x[2][2] = x[2][2];2111v.x[2][3] = x[2][3];2112v.x[3][0] = x[3][0];2113v.x[3][1] = x[3][1];2114v.x[3][2] = x[3][2];2115v.x[3][3] = x[3][3];2116}2117}21182119template <class T>2120template <class S>2121inline Matrix44<T> &2122Matrix44<T>::setValue (const Matrix44<S> &v)2123{2124if (isSameType<S,T>::value)2125{2126memcpy (x, v.x, sizeof (x));2127}2128else2129{2130x[0][0] = v.x[0][0];2131x[0][1] = v.x[0][1];2132x[0][2] = v.x[0][2];2133x[0][3] = v.x[0][3];2134x[1][0] = v.x[1][0];2135x[1][1] = v.x[1][1];2136x[1][2] = v.x[1][2];2137x[1][3] = v.x[1][3];2138x[2][0] = v.x[2][0];2139x[2][1] = v.x[2][1];2140x[2][2] = v.x[2][2];2141x[2][3] = v.x[2][3];2142x[3][0] = v.x[3][0];2143x[3][1] = v.x[3][1];2144x[3][2] = v.x[3][2];2145x[3][3] = v.x[3][3];2146}21472148return *this;2149}21502151template <class T>2152template <class S>2153inline Matrix44<T> &2154Matrix44<T>::setTheMatrix (const Matrix44<S> &v)2155{2156if (isSameType<S,T>::value)2157{2158memcpy (x, v.x, sizeof (x));2159}2160else2161{2162x[0][0] = v.x[0][0];2163x[0][1] = v.x[0][1];2164x[0][2] = v.x[0][2];2165x[0][3] = v.x[0][3];2166x[1][0] = v.x[1][0];2167x[1][1] = v.x[1][1];2168x[1][2] = v.x[1][2];2169x[1][3] = v.x[1][3];2170x[2][0] = v.x[2][0];2171x[2][1] = v.x[2][1];2172x[2][2] = v.x[2][2];2173x[2][3] = v.x[2][3];2174x[3][0] = v.x[3][0];2175x[3][1] = v.x[3][1];2176x[3][2] = v.x[3][2];2177x[3][3] = v.x[3][3];2178}21792180return *this;2181}21822183template <class T>2184inline void2185Matrix44<T>::makeIdentity()2186{2187memset (x, 0, sizeof (x));2188x[0][0] = 1;2189x[1][1] = 1;2190x[2][2] = 1;2191x[3][3] = 1;2192}21932194template <class T>2195bool2196Matrix44<T>::operator == (const Matrix44 &v) const2197{2198return x[0][0] == v.x[0][0] &&2199x[0][1] == v.x[0][1] &&2200x[0][2] == v.x[0][2] &&2201x[0][3] == v.x[0][3] &&2202x[1][0] == v.x[1][0] &&2203x[1][1] == v.x[1][1] &&2204x[1][2] == v.x[1][2] &&2205x[1][3] == v.x[1][3] &&2206x[2][0] == v.x[2][0] &&2207x[2][1] == v.x[2][1] &&2208x[2][2] == v.x[2][2] &&2209x[2][3] == v.x[2][3] &&2210x[3][0] == v.x[3][0] &&2211x[3][1] == v.x[3][1] &&2212x[3][2] == v.x[3][2] &&2213x[3][3] == v.x[3][3];2214}22152216template <class T>2217bool2218Matrix44<T>::operator != (const Matrix44 &v) const2219{2220return x[0][0] != v.x[0][0] ||2221x[0][1] != v.x[0][1] ||2222x[0][2] != v.x[0][2] ||2223x[0][3] != v.x[0][3] ||2224x[1][0] != v.x[1][0] ||2225x[1][1] != v.x[1][1] ||2226x[1][2] != v.x[1][2] ||2227x[1][3] != v.x[1][3] ||2228x[2][0] != v.x[2][0] ||2229x[2][1] != v.x[2][1] ||2230x[2][2] != v.x[2][2] ||2231x[2][3] != v.x[2][3] ||2232x[3][0] != v.x[3][0] ||2233x[3][1] != v.x[3][1] ||2234x[3][2] != v.x[3][2] ||2235x[3][3] != v.x[3][3];2236}22372238template <class T>2239bool2240Matrix44<T>::equalWithAbsError (const Matrix44<T> &m, T e) const2241{2242for (int i = 0; i < 4; i++)2243for (int j = 0; j < 4; j++)2244if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))2245return false;22462247return true;2248}22492250template <class T>2251bool2252Matrix44<T>::equalWithRelError (const Matrix44<T> &m, T e) const2253{2254for (int i = 0; i < 4; i++)2255for (int j = 0; j < 4; j++)2256if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))2257return false;22582259return true;2260}22612262template <class T>2263const Matrix44<T> &2264Matrix44<T>::operator += (const Matrix44<T> &v)2265{2266x[0][0] += v.x[0][0];2267x[0][1] += v.x[0][1];2268x[0][2] += v.x[0][2];2269x[0][3] += v.x[0][3];2270x[1][0] += v.x[1][0];2271x[1][1] += v.x[1][1];2272x[1][2] += v.x[1][2];2273x[1][3] += v.x[1][3];2274x[2][0] += v.x[2][0];2275x[2][1] += v.x[2][1];2276x[2][2] += v.x[2][2];2277x[2][3] += v.x[2][3];2278x[3][0] += v.x[3][0];2279x[3][1] += v.x[3][1];2280x[3][2] += v.x[3][2];2281x[3][3] += v.x[3][3];22822283return *this;2284}22852286template <class T>2287const Matrix44<T> &2288Matrix44<T>::operator += (T a)2289{2290x[0][0] += a;2291x[0][1] += a;2292x[0][2] += a;2293x[0][3] += a;2294x[1][0] += a;2295x[1][1] += a;2296x[1][2] += a;2297x[1][3] += a;2298x[2][0] += a;2299x[2][1] += a;2300x[2][2] += a;2301x[2][3] += a;2302x[3][0] += a;2303x[3][1] += a;2304x[3][2] += a;2305x[3][3] += a;23062307return *this;2308}23092310template <class T>2311Matrix44<T>2312Matrix44<T>::operator + (const Matrix44<T> &v) const2313{2314return Matrix44 (x[0][0] + v.x[0][0],2315x[0][1] + v.x[0][1],2316x[0][2] + v.x[0][2],2317x[0][3] + v.x[0][3],2318x[1][0] + v.x[1][0],2319x[1][1] + v.x[1][1],2320x[1][2] + v.x[1][2],2321x[1][3] + v.x[1][3],2322x[2][0] + v.x[2][0],2323x[2][1] + v.x[2][1],2324x[2][2] + v.x[2][2],2325x[2][3] + v.x[2][3],2326x[3][0] + v.x[3][0],2327x[3][1] + v.x[3][1],2328x[3][2] + v.x[3][2],2329x[3][3] + v.x[3][3]);2330}23312332template <class T>2333const Matrix44<T> &2334Matrix44<T>::operator -= (const Matrix44<T> &v)2335{2336x[0][0] -= v.x[0][0];2337x[0][1] -= v.x[0][1];2338x[0][2] -= v.x[0][2];2339x[0][3] -= v.x[0][3];2340x[1][0] -= v.x[1][0];2341x[1][1] -= v.x[1][1];2342x[1][2] -= v.x[1][2];2343x[1][3] -= v.x[1][3];2344x[2][0] -= v.x[2][0];2345x[2][1] -= v.x[2][1];2346x[2][2] -= v.x[2][2];2347x[2][3] -= v.x[2][3];2348x[3][0] -= v.x[3][0];2349x[3][1] -= v.x[3][1];2350x[3][2] -= v.x[3][2];2351x[3][3] -= v.x[3][3];23522353return *this;2354}23552356template <class T>2357const Matrix44<T> &2358Matrix44<T>::operator -= (T a)2359{2360x[0][0] -= a;2361x[0][1] -= a;2362x[0][2] -= a;2363x[0][3] -= a;2364x[1][0] -= a;2365x[1][1] -= a;2366x[1][2] -= a;2367x[1][3] -= a;2368x[2][0] -= a;2369x[2][1] -= a;2370x[2][2] -= a;2371x[2][3] -= a;2372x[3][0] -= a;2373x[3][1] -= a;2374x[3][2] -= a;2375x[3][3] -= a;23762377return *this;2378}23792380template <class T>2381Matrix44<T>2382Matrix44<T>::operator - (const Matrix44<T> &v) const2383{2384return Matrix44 (x[0][0] - v.x[0][0],2385x[0][1] - v.x[0][1],2386x[0][2] - v.x[0][2],2387x[0][3] - v.x[0][3],2388x[1][0] - v.x[1][0],2389x[1][1] - v.x[1][1],2390x[1][2] - v.x[1][2],2391x[1][3] - v.x[1][3],2392x[2][0] - v.x[2][0],2393x[2][1] - v.x[2][1],2394x[2][2] - v.x[2][2],2395x[2][3] - v.x[2][3],2396x[3][0] - v.x[3][0],2397x[3][1] - v.x[3][1],2398x[3][2] - v.x[3][2],2399x[3][3] - v.x[3][3]);2400}24012402template <class T>2403Matrix44<T>2404Matrix44<T>::operator - () const2405{2406return Matrix44 (-x[0][0],2407-x[0][1],2408-x[0][2],2409-x[0][3],2410-x[1][0],2411-x[1][1],2412-x[1][2],2413-x[1][3],2414-x[2][0],2415-x[2][1],2416-x[2][2],2417-x[2][3],2418-x[3][0],2419-x[3][1],2420-x[3][2],2421-x[3][3]);2422}24232424template <class T>2425const Matrix44<T> &2426Matrix44<T>::negate ()2427{2428x[0][0] = -x[0][0];2429x[0][1] = -x[0][1];2430x[0][2] = -x[0][2];2431x[0][3] = -x[0][3];2432x[1][0] = -x[1][0];2433x[1][1] = -x[1][1];2434x[1][2] = -x[1][2];2435x[1][3] = -x[1][3];2436x[2][0] = -x[2][0];2437x[2][1] = -x[2][1];2438x[2][2] = -x[2][2];2439x[2][3] = -x[2][3];2440x[3][0] = -x[3][0];2441x[3][1] = -x[3][1];2442x[3][2] = -x[3][2];2443x[3][3] = -x[3][3];24442445return *this;2446}24472448template <class T>2449const Matrix44<T> &2450Matrix44<T>::operator *= (T a)2451{2452x[0][0] *= a;2453x[0][1] *= a;2454x[0][2] *= a;2455x[0][3] *= a;2456x[1][0] *= a;2457x[1][1] *= a;2458x[1][2] *= a;2459x[1][3] *= a;2460x[2][0] *= a;2461x[2][1] *= a;2462x[2][2] *= a;2463x[2][3] *= a;2464x[3][0] *= a;2465x[3][1] *= a;2466x[3][2] *= a;2467x[3][3] *= a;24682469return *this;2470}24712472template <class T>2473Matrix44<T>2474Matrix44<T>::operator * (T a) const2475{2476return Matrix44 (x[0][0] * a,2477x[0][1] * a,2478x[0][2] * a,2479x[0][3] * a,2480x[1][0] * a,2481x[1][1] * a,2482x[1][2] * a,2483x[1][3] * a,2484x[2][0] * a,2485x[2][1] * a,2486x[2][2] * a,2487x[2][3] * a,2488x[3][0] * a,2489x[3][1] * a,2490x[3][2] * a,2491x[3][3] * a);2492}24932494template <class T>2495inline Matrix44<T>2496operator * (T a, const Matrix44<T> &v)2497{2498return v * a;2499}25002501template <class T>2502inline const Matrix44<T> &2503Matrix44<T>::operator *= (const Matrix44<T> &v)2504{2505Matrix44 tmp (T (0));25062507multiply (*this, v, tmp);2508*this = tmp;2509return *this;2510}25112512template <class T>2513inline Matrix44<T>2514Matrix44<T>::operator * (const Matrix44<T> &v) const2515{2516Matrix44 tmp (T (0));25172518multiply (*this, v, tmp);2519return tmp;2520}25212522template <class T>2523void2524Matrix44<T>::multiply (const Matrix44<T> &a,2525const Matrix44<T> &b,2526Matrix44<T> &c)2527{2528register const T * IMATH_RESTRICT ap = &a.x[0][0];2529register const T * IMATH_RESTRICT bp = &b.x[0][0];2530register T * IMATH_RESTRICT cp = &c.x[0][0];25312532register T a0, a1, a2, a3;25332534a0 = ap[0];2535a1 = ap[1];2536a2 = ap[2];2537a3 = ap[3];25382539cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];2540cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];2541cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];2542cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];25432544a0 = ap[4];2545a1 = ap[5];2546a2 = ap[6];2547a3 = ap[7];25482549cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];2550cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];2551cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];2552cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];25532554a0 = ap[8];2555a1 = ap[9];2556a2 = ap[10];2557a3 = ap[11];25582559cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];2560cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];2561cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];2562cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];25632564a0 = ap[12];2565a1 = ap[13];2566a2 = ap[14];2567a3 = ap[15];25682569cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];2570cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];2571cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];2572cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];2573}25742575template <class T> template <class S>2576void2577Matrix44<T>::multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const2578{2579S a, b, c, w;25802581a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0] + x[3][0];2582b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1] + x[3][1];2583c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2] + x[3][2];2584w = src[0] * x[0][3] + src[1] * x[1][3] + src[2] * x[2][3] + x[3][3];25852586dst.x = a / w;2587dst.y = b / w;2588dst.z = c / w;2589}25902591template <class T> template <class S>2592void2593Matrix44<T>::multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const2594{2595S a, b, c;25962597a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0];2598b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1];2599c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2];26002601dst.x = a;2602dst.y = b;2603dst.z = c;2604}26052606template <class T>2607const Matrix44<T> &2608Matrix44<T>::operator /= (T a)2609{2610x[0][0] /= a;2611x[0][1] /= a;2612x[0][2] /= a;2613x[0][3] /= a;2614x[1][0] /= a;2615x[1][1] /= a;2616x[1][2] /= a;2617x[1][3] /= a;2618x[2][0] /= a;2619x[2][1] /= a;2620x[2][2] /= a;2621x[2][3] /= a;2622x[3][0] /= a;2623x[3][1] /= a;2624x[3][2] /= a;2625x[3][3] /= a;26262627return *this;2628}26292630template <class T>2631Matrix44<T>2632Matrix44<T>::operator / (T a) const2633{2634return Matrix44 (x[0][0] / a,2635x[0][1] / a,2636x[0][2] / a,2637x[0][3] / a,2638x[1][0] / a,2639x[1][1] / a,2640x[1][2] / a,2641x[1][3] / a,2642x[2][0] / a,2643x[2][1] / a,2644x[2][2] / a,2645x[2][3] / a,2646x[3][0] / a,2647x[3][1] / a,2648x[3][2] / a,2649x[3][3] / a);2650}26512652template <class T>2653const Matrix44<T> &2654Matrix44<T>::transpose ()2655{2656Matrix44 tmp (x[0][0],2657x[1][0],2658x[2][0],2659x[3][0],2660x[0][1],2661x[1][1],2662x[2][1],2663x[3][1],2664x[0][2],2665x[1][2],2666x[2][2],2667x[3][2],2668x[0][3],2669x[1][3],2670x[2][3],2671x[3][3]);2672*this = tmp;2673return *this;2674}26752676template <class T>2677Matrix44<T>2678Matrix44<T>::transposed () const2679{2680return Matrix44 (x[0][0],2681x[1][0],2682x[2][0],2683x[3][0],2684x[0][1],2685x[1][1],2686x[2][1],2687x[3][1],2688x[0][2],2689x[1][2],2690x[2][2],2691x[3][2],2692x[0][3],2693x[1][3],2694x[2][3],2695x[3][3]);2696}26972698template <class T>2699const Matrix44<T> &2700Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)2701{2702*this = gjInverse (singExc);2703return *this;2704}27052706template <class T>2707Matrix44<T>2708Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)2709{2710int i, j, k;2711Matrix44 s;2712Matrix44 t (*this);27132714// Forward elimination27152716for (i = 0; i < 3 ; i++)2717{2718int pivot = i;27192720T pivotsize = t[i][i];27212722if (pivotsize < 0)2723pivotsize = -pivotsize;27242725for (j = i + 1; j < 4; j++)2726{2727T tmp = t[j][i];27282729if (tmp < 0)2730tmp = -tmp;27312732if (tmp > pivotsize)2733{2734pivot = j;2735pivotsize = tmp;2736}2737}27382739if (pivotsize == 0)2740{2741if (singExc)2742throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");27432744return Matrix44();2745}27462747if (pivot != i)2748{2749for (j = 0; j < 4; j++)2750{2751T tmp;27522753tmp = t[i][j];2754t[i][j] = t[pivot][j];2755t[pivot][j] = tmp;27562757tmp = s[i][j];2758s[i][j] = s[pivot][j];2759s[pivot][j] = tmp;2760}2761}27622763for (j = i + 1; j < 4; j++)2764{2765T f = t[j][i] / t[i][i];27662767for (k = 0; k < 4; k++)2768{2769t[j][k] -= f * t[i][k];2770s[j][k] -= f * s[i][k];2771}2772}2773}27742775// Backward substitution27762777for (i = 3; i >= 0; --i)2778{2779T f;27802781if ((f = t[i][i]) == 0)2782{2783if (singExc)2784throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");27852786return Matrix44();2787}27882789for (j = 0; j < 4; j++)2790{2791t[i][j] /= f;2792s[i][j] /= f;2793}27942795for (j = 0; j < i; j++)2796{2797f = t[j][i];27982799for (k = 0; k < 4; k++)2800{2801t[j][k] -= f * t[i][k];2802s[j][k] -= f * s[i][k];2803}2804}2805}28062807return s;2808}28092810template <class T>2811const Matrix44<T> &2812Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)2813{2814*this = inverse (singExc);2815return *this;2816}28172818template <class T>2819Matrix44<T>2820Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)2821{2822if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)2823return gjInverse(singExc);28242825Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],2826x[2][1] * x[0][2] - x[0][1] * x[2][2],2827x[0][1] * x[1][2] - x[1][1] * x[0][2],28280,28292830x[2][0] * x[1][2] - x[1][0] * x[2][2],2831x[0][0] * x[2][2] - x[2][0] * x[0][2],2832x[1][0] * x[0][2] - x[0][0] * x[1][2],28330,28342835x[1][0] * x[2][1] - x[2][0] * x[1][1],2836x[2][0] * x[0][1] - x[0][0] * x[2][1],2837x[0][0] * x[1][1] - x[1][0] * x[0][1],28380,283928400,28410,28420,28431);28442845T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];28462847if (Imath::abs (r) >= 1)2848{2849for (int i = 0; i < 3; ++i)2850{2851for (int j = 0; j < 3; ++j)2852{2853s[i][j] /= r;2854}2855}2856}2857else2858{2859T mr = Imath::abs (r) / limits<T>::smallest();28602861for (int i = 0; i < 3; ++i)2862{2863for (int j = 0; j < 3; ++j)2864{2865if (mr > Imath::abs (s[i][j]))2866{2867s[i][j] /= r;2868}2869else2870{2871if (singExc)2872throw SingMatrixExc ("Cannot invert singular matrix.");28732874return Matrix44();2875}2876}2877}2878}28792880s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0];2881s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1];2882s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2];28832884return s;2885}28862887template <class T>2888inline T2889Matrix44<T>::fastMinor( const int r0, const int r1, const int r2,2890const int c0, const int c1, const int c2) const2891{2892return x[r0][c0] * (x[r1][c1]*x[r2][c2] - x[r1][c2]*x[r2][c1])2893+ x[r0][c1] * (x[r1][c2]*x[r2][c0] - x[r1][c0]*x[r2][c2])2894+ x[r0][c2] * (x[r1][c0]*x[r2][c1] - x[r1][c1]*x[r2][c0]);2895}28962897template <class T>2898inline T2899Matrix44<T>::minorOf (const int r, const int c) const2900{2901int r0 = 0 + (r < 1 ? 1 : 0);2902int r1 = 1 + (r < 2 ? 1 : 0);2903int r2 = 2 + (r < 3 ? 1 : 0);2904int c0 = 0 + (c < 1 ? 1 : 0);2905int c1 = 1 + (c < 2 ? 1 : 0);2906int c2 = 2 + (c < 3 ? 1 : 0);29072908Matrix33<T> working (x[r0][c0],x[r1][c0],x[r2][c0],2909x[r0][c1],x[r1][c1],x[r2][c1],2910x[r0][c2],x[r1][c2],x[r2][c2]);29112912return working.determinant();2913}29142915template <class T>2916inline T2917Matrix44<T>::determinant () const2918{2919T sum = (T)0;29202921if (x[0][3] != 0.) sum -= x[0][3] * fastMinor(1,2,3,0,1,2);2922if (x[1][3] != 0.) sum += x[1][3] * fastMinor(0,2,3,0,1,2);2923if (x[2][3] != 0.) sum -= x[2][3] * fastMinor(0,1,3,0,1,2);2924if (x[3][3] != 0.) sum += x[3][3] * fastMinor(0,1,2,0,1,2);29252926return sum;2927}29282929template <class T>2930template <class S>2931const Matrix44<T> &2932Matrix44<T>::setEulerAngles (const Vec3<S>& r)2933{2934S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;29352936cos_rz = Math<T>::cos (r[2]);2937cos_ry = Math<T>::cos (r[1]);2938cos_rx = Math<T>::cos (r[0]);29392940sin_rz = Math<T>::sin (r[2]);2941sin_ry = Math<T>::sin (r[1]);2942sin_rx = Math<T>::sin (r[0]);29432944x[0][0] = cos_rz * cos_ry;2945x[0][1] = sin_rz * cos_ry;2946x[0][2] = -sin_ry;2947x[0][3] = 0;29482949x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;2950x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;2951x[1][2] = cos_ry * sin_rx;2952x[1][3] = 0;29532954x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;2955x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;2956x[2][2] = cos_ry * cos_rx;2957x[2][3] = 0;29582959x[3][0] = 0;2960x[3][1] = 0;2961x[3][2] = 0;2962x[3][3] = 1;29632964return *this;2965}29662967template <class T>2968template <class S>2969const Matrix44<T> &2970Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle)2971{2972Vec3<S> unit (axis.normalized());2973S sine = Math<T>::sin (angle);2974S cosine = Math<T>::cos (angle);29752976x[0][0] = unit[0] * unit[0] * (1 - cosine) + cosine;2977x[0][1] = unit[0] * unit[1] * (1 - cosine) + unit[2] * sine;2978x[0][2] = unit[0] * unit[2] * (1 - cosine) - unit[1] * sine;2979x[0][3] = 0;29802981x[1][0] = unit[0] * unit[1] * (1 - cosine) - unit[2] * sine;2982x[1][1] = unit[1] * unit[1] * (1 - cosine) + cosine;2983x[1][2] = unit[1] * unit[2] * (1 - cosine) + unit[0] * sine;2984x[1][3] = 0;29852986x[2][0] = unit[0] * unit[2] * (1 - cosine) + unit[1] * sine;2987x[2][1] = unit[1] * unit[2] * (1 - cosine) - unit[0] * sine;2988x[2][2] = unit[2] * unit[2] * (1 - cosine) + cosine;2989x[2][3] = 0;29902991x[3][0] = 0;2992x[3][1] = 0;2993x[3][2] = 0;2994x[3][3] = 1;29952996return *this;2997}29982999template <class T>3000template <class S>3001const Matrix44<T> &3002Matrix44<T>::rotate (const Vec3<S> &r)3003{3004S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;3005S m00, m01, m02;3006S m10, m11, m12;3007S m20, m21, m22;30083009cos_rz = Math<S>::cos (r[2]);3010cos_ry = Math<S>::cos (r[1]);3011cos_rx = Math<S>::cos (r[0]);30123013sin_rz = Math<S>::sin (r[2]);3014sin_ry = Math<S>::sin (r[1]);3015sin_rx = Math<S>::sin (r[0]);30163017m00 = cos_rz * cos_ry;3018m01 = sin_rz * cos_ry;3019m02 = -sin_ry;3020m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;3021m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;3022m12 = cos_ry * sin_rx;3023m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx;3024m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx;3025m22 = cos_ry * cos_rx;30263027Matrix44<T> P (*this);30283029x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02;3030x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02;3031x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02;3032x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02;30333034x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12;3035x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12;3036x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12;3037x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12;30383039x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22;3040x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22;3041x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22;3042x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22;30433044return *this;3045}30463047template <class T>3048const Matrix44<T> &3049Matrix44<T>::setScale (T s)3050{3051memset (x, 0, sizeof (x));3052x[0][0] = s;3053x[1][1] = s;3054x[2][2] = s;3055x[3][3] = 1;30563057return *this;3058}30593060template <class T>3061template <class S>3062const Matrix44<T> &3063Matrix44<T>::setScale (const Vec3<S> &s)3064{3065memset (x, 0, sizeof (x));3066x[0][0] = s[0];3067x[1][1] = s[1];3068x[2][2] = s[2];3069x[3][3] = 1;30703071return *this;3072}30733074template <class T>3075template <class S>3076const Matrix44<T> &3077Matrix44<T>::scale (const Vec3<S> &s)3078{3079x[0][0] *= s[0];3080x[0][1] *= s[0];3081x[0][2] *= s[0];3082x[0][3] *= s[0];30833084x[1][0] *= s[1];3085x[1][1] *= s[1];3086x[1][2] *= s[1];3087x[1][3] *= s[1];30883089x[2][0] *= s[2];3090x[2][1] *= s[2];3091x[2][2] *= s[2];3092x[2][3] *= s[2];30933094return *this;3095}30963097template <class T>3098template <class S>3099const Matrix44<T> &3100Matrix44<T>::setTranslation (const Vec3<S> &t)3101{3102x[0][0] = 1;3103x[0][1] = 0;3104x[0][2] = 0;3105x[0][3] = 0;31063107x[1][0] = 0;3108x[1][1] = 1;3109x[1][2] = 0;3110x[1][3] = 0;31113112x[2][0] = 0;3113x[2][1] = 0;3114x[2][2] = 1;3115x[2][3] = 0;31163117x[3][0] = t[0];3118x[3][1] = t[1];3119x[3][2] = t[2];3120x[3][3] = 1;31213122return *this;3123}31243125template <class T>3126inline const Vec3<T>3127Matrix44<T>::translation () const3128{3129return Vec3<T> (x[3][0], x[3][1], x[3][2]);3130}31313132template <class T>3133template <class S>3134const Matrix44<T> &3135Matrix44<T>::translate (const Vec3<S> &t)3136{3137x[3][0] += t[0] * x[0][0] + t[1] * x[1][0] + t[2] * x[2][0];3138x[3][1] += t[0] * x[0][1] + t[1] * x[1][1] + t[2] * x[2][1];3139x[3][2] += t[0] * x[0][2] + t[1] * x[1][2] + t[2] * x[2][2];3140x[3][3] += t[0] * x[0][3] + t[1] * x[1][3] + t[2] * x[2][3];31413142return *this;3143}31443145template <class T>3146template <class S>3147const Matrix44<T> &3148Matrix44<T>::setShear (const Vec3<S> &h)3149{3150x[0][0] = 1;3151x[0][1] = 0;3152x[0][2] = 0;3153x[0][3] = 0;31543155x[1][0] = h[0];3156x[1][1] = 1;3157x[1][2] = 0;3158x[1][3] = 0;31593160x[2][0] = h[1];3161x[2][1] = h[2];3162x[2][2] = 1;3163x[2][3] = 0;31643165x[3][0] = 0;3166x[3][1] = 0;3167x[3][2] = 0;3168x[3][3] = 1;31693170return *this;3171}31723173template <class T>3174template <class S>3175const Matrix44<T> &3176Matrix44<T>::setShear (const Shear6<S> &h)3177{3178x[0][0] = 1;3179x[0][1] = h.yx;3180x[0][2] = h.zx;3181x[0][3] = 0;31823183x[1][0] = h.xy;3184x[1][1] = 1;3185x[1][2] = h.zy;3186x[1][3] = 0;31873188x[2][0] = h.xz;3189x[2][1] = h.yz;3190x[2][2] = 1;3191x[2][3] = 0;31923193x[3][0] = 0;3194x[3][1] = 0;3195x[3][2] = 0;3196x[3][3] = 1;31973198return *this;3199}32003201template <class T>3202template <class S>3203const Matrix44<T> &3204Matrix44<T>::shear (const Vec3<S> &h)3205{3206//3207// In this case, we don't need a temp. copy of the matrix3208// because we never use a value on the RHS after we've3209// changed it on the LHS.3210//32113212for (int i=0; i < 4; i++)3213{3214x[2][i] += h[1] * x[0][i] + h[2] * x[1][i];3215x[1][i] += h[0] * x[0][i];3216}32173218return *this;3219}32203221template <class T>3222template <class S>3223const Matrix44<T> &3224Matrix44<T>::shear (const Shear6<S> &h)3225{3226Matrix44<T> P (*this);32273228for (int i=0; i < 4; i++)3229{3230x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i];3231x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i];3232x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i];3233}32343235return *this;3236}323732383239//--------------------------------3240// Implementation of stream output3241//--------------------------------32423243template <class T>3244std::ostream &3245operator << (std::ostream &s, const Matrix33<T> &m)3246{3247std::ios_base::fmtflags oldFlags = s.flags();3248int width;32493250if (s.flags() & std::ios_base::fixed)3251{3252s.setf (std::ios_base::showpoint);3253width = s.precision() + 5;3254}3255else3256{3257s.setf (std::ios_base::scientific);3258s.setf (std::ios_base::showpoint);3259width = s.precision() + 8;3260}32613262s << "(" << std::setw (width) << m[0][0] <<3263" " << std::setw (width) << m[0][1] <<3264" " << std::setw (width) << m[0][2] << "\n" <<32653266" " << std::setw (width) << m[1][0] <<3267" " << std::setw (width) << m[1][1] <<3268" " << std::setw (width) << m[1][2] << "\n" <<32693270" " << std::setw (width) << m[2][0] <<3271" " << std::setw (width) << m[2][1] <<3272" " << std::setw (width) << m[2][2] << ")\n";32733274s.flags (oldFlags);3275return s;3276}32773278template <class T>3279std::ostream &3280operator << (std::ostream &s, const Matrix44<T> &m)3281{3282std::ios_base::fmtflags oldFlags = s.flags();3283int width;32843285if (s.flags() & std::ios_base::fixed)3286{3287s.setf (std::ios_base::showpoint);3288width = s.precision() + 5;3289}3290else3291{3292s.setf (std::ios_base::scientific);3293s.setf (std::ios_base::showpoint);3294width = s.precision() + 8;3295}32963297s << "(" << std::setw (width) << m[0][0] <<3298" " << std::setw (width) << m[0][1] <<3299" " << std::setw (width) << m[0][2] <<3300" " << std::setw (width) << m[0][3] << "\n" <<33013302" " << std::setw (width) << m[1][0] <<3303" " << std::setw (width) << m[1][1] <<3304" " << std::setw (width) << m[1][2] <<3305" " << std::setw (width) << m[1][3] << "\n" <<33063307" " << std::setw (width) << m[2][0] <<3308" " << std::setw (width) << m[2][1] <<3309" " << std::setw (width) << m[2][2] <<3310" " << std::setw (width) << m[2][3] << "\n" <<33113312" " << std::setw (width) << m[3][0] <<3313" " << std::setw (width) << m[3][1] <<3314" " << std::setw (width) << m[3][2] <<3315" " << std::setw (width) << m[3][3] << ")\n";33163317s.flags (oldFlags);3318return s;3319}332033213322//---------------------------------------------------------------3323// Implementation of vector-times-matrix multiplication operators3324//---------------------------------------------------------------33253326template <class S, class T>3327inline const Vec2<S> &3328operator *= (Vec2<S> &v, const Matrix33<T> &m)3329{3330S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);3331S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);3332S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);33333334v.x = x / w;3335v.y = y / w;33363337return v;3338}33393340template <class S, class T>3341inline Vec2<S>3342operator * (const Vec2<S> &v, const Matrix33<T> &m)3343{3344S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]);3345S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]);3346S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]);33473348return Vec2<S> (x / w, y / w);3349}335033513352template <class S, class T>3353inline const Vec3<S> &3354operator *= (Vec3<S> &v, const Matrix33<T> &m)3355{3356S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);3357S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);3358S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);33593360v.x = x;3361v.y = y;3362v.z = z;33633364return v;3365}33663367template <class S, class T>3368inline Vec3<S>3369operator * (const Vec3<S> &v, const Matrix33<T> &m)3370{3371S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);3372S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);3373S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);33743375return Vec3<S> (x, y, z);3376}337733783379template <class S, class T>3380inline const Vec3<S> &3381operator *= (Vec3<S> &v, const Matrix44<T> &m)3382{3383S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);3384S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);3385S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);3386S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);33873388v.x = x / w;3389v.y = y / w;3390v.z = z / w;33913392return v;3393}33943395template <class S, class T>3396inline Vec3<S>3397operator * (const Vec3<S> &v, const Matrix44<T> &m)3398{3399S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);3400S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);3401S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);3402S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);34033404return Vec3<S> (x / w, y / w, z / w);3405}340634073408template <class S, class T>3409inline const Vec4<S> &3410operator *= (Vec4<S> &v, const Matrix44<T> &m)3411{3412S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);3413S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);3414S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);3415S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);34163417v.x = x;3418v.y = y;3419v.z = z;3420v.w = w;34213422return v;3423}34243425template <class S, class T>3426inline Vec4<S>3427operator * (const Vec4<S> &v, const Matrix44<T> &m)3428{3429S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);3430S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);3431S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);3432S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);34333434return Vec4<S> (x, y, z, w);3435}34363437} // namespace Imath3438343934403441#endif344234433444