// // RiAffineTMatrix3.h -- RiAffineTMatrix3 class definition // // Author: Peter Shirley, April 24, 1997 #ifndef RIAFFINETMATRIX3_H #define RIAFFINETMATRIX3_H #ifndef RIVECTOR3_H #include #endif class RiTMatrix3Factory; /*************************************************************** CLASS RiAffineTMatrix3 An abstract class that represents a homegeneous transform matrix and its inverse. DESCRIPTION This class is the base class for all transforms. It uses column vectors and right-multiplication, so vnew = M*vold. Individual entries are gotten via the getData() member, which takes two indices and has the following pattern for rows and colums- getData(row,col): | 00 01 02 03 | | 10 11 12 13 | | 20 21 22 23 | | 30 31 32 33 | For affine transforms, row 3 is implictly 0 0 0 1. There are three types of transforms for three types of data: locations, directions, and normals. These get more efficient for more and more specific vector types. WARNING RiAffineTMatrix3 currently stores 24 floats, so something such as a compact translate matrix cannot be derived effectively. ****************************************************************/ class RiAffineTMatrix3 { public: friend RiTMatrix3Factory; RiAffineTMatrix3(); //// changes a location (point) RiVector3 ApplyLocation( const RiVector3& v ) const; //// changes a direction (offset) RiVector3 ApplyDirection( const RiVector3& v ) const; //// changes a perpendicular (offset) RiVector3 ApplyNormal( const RiVector3& v ) const; //// changes a location (point) RiVector3 ApplyInverseLocation( const RiVector3& v ) const; //// changes a direction (offset) RiVector3 ApplyInverseDirection( const RiVector3& v ) const; //// changes a perpendicular (offset) RiVector3 ApplyInverseNormal( const RiVector3& v ) const; //// RiAffineTMatrix3 operator*( const RiAffineTMatrix3& ) const; //// RiReal GetData( int row, int col ) const; //// RiReal GetDeterminant() const; protected: RiReal data[3][4]; RiReal idata[3][4]; }; ostream &operator<<(ostream &os, const RiAffineTMatrix3 &m); inline RiAffineTMatrix3::RiAffineTMatrix3() { #ifndef NDEBUG data[0][0] = data[0][1] = data[0][2] = data[0][3] = RI_NAN; data[1][0] = data[1][1] = data[1][2] = data[1][3] = RI_NAN; data[2][0] = data[2][1] = data[2][2] = data[2][3] = RI_NAN; #endif } // we must assume that the homogeneous coordinate gets changed. // the homogeneous coordinate of v is assumed to be one. inline RiVector3 RiAffineTMatrix3::ApplyLocation( const RiVector3& v ) const { return RiVector3( data[0][0]*v[0] + data[0][1]*v[1] + data[0][2]*v[2] + data[0][3], data[1][0]*v[0] + data[1][1]*v[1] + data[1][2]*v[2] + data[1][3], data[2][0]*v[0] + data[2][1]*v[1] + data[2][2]*v[2] + data[2][3] ); } // we must assume that the homogeneous coordinate gets changed. // the homogeneous coordinate of v is assumed to be zero. inline RiVector3 RiAffineTMatrix3::ApplyDirection( const RiVector3& v ) const { return RiVector3( data[0][0]*v[0] + data[0][1]*v[1] + data[0][2]*v[2] , data[1][0]*v[0] + data[1][1]*v[1] + data[1][2]*v[2] , data[2][0]*v[0] + data[2][1]*v[1] + data[2][2]*v[2] ); } // normal vectors transform differently. While tangent and // other vectors transform as v' = Mv, normal vectors transform // as v' = M'v where M' is the transpose of the inverse of M. // See the OpenGL Programming Guide p 477 for a proof. inline RiVector3 RiAffineTMatrix3::ApplyNormal( const RiVector3& v ) const { return RiVector3( idata[0][0]*v[0] + idata[1][0]*v[1] + idata[2][0]*v[2], idata[0][1]*v[0] + idata[1][1]*v[1] + idata[2][1]*v[2], idata[0][2]*v[0] + idata[1][2]*v[1] + idata[2][2]*v[2] ); } inline RiVector3 RiAffineTMatrix3::ApplyInverseLocation( const RiVector3& v ) const { return RiVector3( idata[0][0]*v[0] + idata[0][1]*v[1] + idata[0][2]*v[2] + idata[0][3], idata[1][0]*v[0] + idata[1][1]*v[1] + idata[1][2]*v[2] + idata[1][3], idata[2][0]*v[0] + idata[2][1]*v[1] + idata[2][2]*v[2] + idata[2][3] ); } inline RiVector3 RiAffineTMatrix3::ApplyInverseDirection( const RiVector3& v ) const { return RiVector3( idata[0][0]*v[0] + idata[0][1]*v[1] + idata[0][2]*v[2] , idata[1][0]*v[0] + idata[1][1]*v[1] + idata[1][2]*v[2] , idata[2][0]*v[0] + idata[2][1]*v[1] + idata[2][2]*v[2] ); } inline RiVector3 RiAffineTMatrix3::ApplyInverseNormal( const RiVector3& v ) const { return RiVector3( data[0][0]*v[0] + data[1][0]*v[1] + data[2][0]*v[2], data[0][1]*v[0] + data[1][1]*v[1] + data[2][1]*v[2], data[0][2]*v[0] + data[1][2]*v[1] + data[2][2]*v[2] ); } #endif // RIAFFINETMATRIX3_H