gKitGL
Transform.h
00001 /* version restructuree mailto:jean-claude.iehl@liris.cnrs.fr */
00002 
00003 /*
00004  * pbrt source code Copyright(c) 1998-2005 Matt Pharr and Greg Humphreys
00005  *
00006  * All Rights Reserved.
00007  * For educational use only; commercial use expressly forbidden.
00008  * NO WARRANTY, express or implied, for this software.
00009  * (See file License.txt for complete license)
00010  */
00011 
00012 #ifndef PBRT_TRANSFORM_H
00013 #define PBRT_TRANSFORM_H
00014 
00015 #include <iostream>
00016 #include <cstdio>
00017 #include <cassert>
00018 
00019 #include "Geometry.h"
00020 
00021 namespace gk {
00022 
00023 //! \defgroup Transform representation matrices homogenes, transformations, compositions de transformations, etc.
00024 //@{
00025     
00026 // Matrix4x4 Declarations
00027 //! representation d'une matrice homogene 4x4.
00028 struct Matrix4x4
00029 {
00030     // Matrix4x4 Public Methods
00031     //! construit une matrice identite, par defaut.
00032     Matrix4x4( )
00033     {
00034         for(int i = 0; i < 4; ++i)
00035             for(int j = 0; j < 4; ++j)
00036                 m[i][j] = 0.f;
00037         
00038         for(int k= 0; k < 4; k++)
00039             m[k][k]= 1.f;
00040     }
00041     
00042     //! construit une matrice a partir d'un tableau 2d de reels [ligne][colonne].
00043     Matrix4x4( const float mat[4][4] );
00044     
00045     //! construit une matrice a partir des 16 elements.
00046     Matrix4x4( 
00047        float t00, float t01, float t02, float t03,
00048        float t10, float t11, float t12, float t13,
00049        float t20, float t21, float t22, float t23,
00050        float t30, float t31, float t32, float t33 );
00051     
00052     //! renvoie la matrice transposee.
00053     Matrix4x4 Transpose( ) const;
00054     
00055     //! affiche la matrice.
00056     void Print( std::ostream &os ) const 
00057     {
00058         os << "[ ";
00059         for (int i = 0; i < 4; ++i) {
00060             os << "[ ";
00061             for (int j = 0; j < 4; ++j)  {
00062                 os << m[i][j];
00063                 if (j != 3) os << ", ";
00064             }
00065             os << " ] ";
00066         }
00067         os << " ] ";
00068     }
00069     
00070     //! affiche la matrice.
00071     void print( ) const
00072     {
00073         #define M44(m, r, c) m[r][c]
00074         
00075         printf("% -.8f  % -.8f  % -.8f  % -.8f\n", 
00076             M44(m, 0, 0), M44(m, 0, 1), M44(m, 0, 2), M44(m, 0, 3));
00077         printf("% -.8f  % -.8f  % -.8f  % -.8f\n", 
00078             M44(m, 1, 0), M44(m, 1, 1), M44(m, 1, 2), M44(m, 1, 3));
00079         printf("% -.8f  % -.8f  % -.8f  % -.8f\n", 
00080             M44(m, 2, 0), M44(m, 2, 1), M44(m, 2, 2), M44(m, 2, 3));
00081         printf("% -.8f  % -.8f  % -.8f  % -.8f\n", 
00082             M44(m, 3, 0), M44(m, 3, 1), M44(m, 3, 2), M44(m, 3, 3));
00083         printf("\n");
00084         
00085         #undef M44
00086     }
00087     
00088     //! \name renvoie un vecteur de la matrice 
00089     // @{
00090     void getColumn( const int c, float v[4] ) const
00091     {
00092         assert(c >= 0 && c < 4);
00093         v[0]= m[0][c];
00094         v[1]= m[1][c];
00095         v[2]= m[2][c];
00096         v[3]= m[3][c];
00097     }
00098     
00099     void getRow( const int r, float v[4] ) const
00100     {
00101         assert(r >= 0 && r < 4);
00102         v[0]= m[r][0];
00103         v[1]= m[r][1];
00104         v[2]= m[r][2];
00105         v[3]= m[r][3];
00106     }
00107     
00108     Vector getRotationVector( const int c ) const
00109     {
00110         assert(c >= 0 && c < 3);
00111         return Vector(m[c][0], m[c][1], m[c][2]);
00112     }
00113     
00114     void getRotationVector( const int c, Vector& v ) const
00115     {
00116         assert(c >= 0 && c < 3);
00117         v.x= m[c][0];
00118         v.y= m[c][1];
00119         v.z= m[c][2];
00120     }
00121     
00122     Vector getTranslationVector( ) const
00123     {
00124         return Vector(m[0][3], m[1][3], m[2][3]);
00125     }
00126     
00127     void getTranslationVector( Vector& v ) const
00128     {
00129         v.x= m[0][3];
00130         v.y= m[1][3];
00131         v.z= m[2][3];
00132     }
00133     // @}
00134     
00135     //! produit de 2 matrices : renvoie m1 * m2.
00136     static 
00137     Matrix4x4 Mul( const Matrix4x4 &m1, const Matrix4x4 &m2 )
00138     {
00139         float r[4][4];
00140         
00141         for (int i = 0; i < 4; ++i)
00142             for (int j = 0; j < 4; ++j)
00143                 r[i][j] = 
00144                     m1.m[i][0] * m2.m[0][j] +
00145                     m1.m[i][1] * m2.m[1][j] +
00146                     m1.m[i][2] * m2.m[2][j] +
00147                     m1.m[i][3] * m2.m[3][j];
00148         
00149         return Matrix4x4(r);
00150     }
00151     
00152     //! \name transformation de points, vecteurs, etc. par la matrice.
00153     
00154     // @{
00155     static
00156     Vector Transform( const Matrix4x4& m, const Vector& v )
00157     {
00158         const float x = v.x;
00159         const float y = v.y;
00160         const float z = v.z;
00161         
00162         return Vector( 
00163             m.m[0][0]*x + m.m[0][1]*y + m.m[0][2]*z,
00164             m.m[1][0]*x + m.m[1][1]*y + m.m[1][2]*z,
00165             m.m[2][0]*x + m.m[2][1]*y + m.m[2][2]*z );        
00166     }
00167     
00168     static
00169     Point Transform( const Matrix4x4& m, const Point& p )
00170     {
00171         const float x = p.x;
00172         const float y = p.y;
00173         const float z = p.z;
00174         
00175         const float xt = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00176         const float yt = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00177         const float zt = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00178         const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00179         
00180         assert( wt != 0 );
00181         if( wt == 1.f ) 
00182             return Point( xt, yt, zt );
00183         else
00184             return Point( xt, yt, zt ) / wt;        
00185     }
00186 
00187     static
00188     HPoint Transform( const Matrix4x4& m, const HPoint& p)
00189     {
00190         const float x = p.x;
00191         const float y = p.y;
00192         const float z = p.z;
00193         assert(p.w == 1.f);
00194         
00195         const float xt = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00196         const float yt = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00197         const float zt = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00198         const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00199         //~ assert( wt != 0 );
00200         
00201         return HPoint(xt, yt, zt, wt);
00202     }
00203     
00204     static
00205     Normal Transform( const Matrix4x4& m, const Normal& n )
00206     {
00207         const float x = n.x;
00208         const float y = n.y;
00209         const float z = n.z;
00210         
00211         // utilise la transformation inverse ... pas une transformation directe.
00212         const float tx = m.m[0][0] * x + m.m[1][0] * y + m.m[2][0] * z;
00213         const float ty = m.m[0][1] * x + m.m[1][1] * y + m.m[2][1] * z;
00214         const float tz = m.m[0][2] * x + m.m[1][2] * y + m.m[2][2] * z;
00215         
00216         return Normal(tx, ty, tz);
00217     }
00218     
00219     static
00220     BBox Transform( const Matrix4x4& m, const BBox& b )
00221     {
00222     #if 0
00223         BBox ret( Matrix4x4::Transform( m, Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00224         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00225         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00226         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00227         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00228         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00229         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00230         ret= Union(ret, Matrix4x4::Transform( m, Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );
00231         
00232     #else
00233         BBox ret;
00234         ret.Union( Matrix4x4::Transform( m, Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00235         ret.Union( Matrix4x4::Transform( m, Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00236         ret.Union( Matrix4x4::Transform( m, Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00237         ret.Union( Matrix4x4::Transform( m, Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00238         ret.Union( Matrix4x4::Transform( m, Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00239         ret.Union( Matrix4x4::Transform( m, Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00240         ret.Union( Matrix4x4::Transform( m, Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00241         ret.Union( Matrix4x4::Transform( m, Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );        
00242     #endif
00243         return ret;
00244     }
00245     // @}
00246     
00247     //! renvoie l'inverse de la matrice.
00248     Matrix4x4 getInverse( ) const;
00249     
00250     //! conversion en float (*)[4]
00251     operator float *( )
00252     {
00253         return (float *) m;
00254     }
00255     
00256     //! conversion en const float (*)[4]
00257     operator const float *( ) const
00258     {
00259         return (const float *) m;
00260     }
00261     
00262     //! elements de la matrice.
00263     float m[4][4];
00264 };
00265 
00266 
00267 // Transform Declarations
00268 //! representation d'une transformation == un changement de repere, du repere '1' vers le repere '2'. 
00269 class Transform
00270 {
00271 public:
00272     // Transform Public Methods
00273     //! constructeur par defaut, transformation identite.
00274     Transform( ) {}
00275     
00276     //! construction a partir d'une matrice representee par un tableau 2d de reels.
00277     Transform( float mat[4][4] )
00278     {
00279         m= Matrix4x4(mat);
00280         mInv = m.getInverse();
00281     }
00282     
00283     //! construction a partir d'une matrice.
00284     Transform( const Matrix4x4& mat )
00285     {
00286         m = mat;
00287         mInv = m.getInverse();
00288     }
00289     
00290     //! construction a partir d'une matrice et de son inverse.
00291     Transform( const Matrix4x4& mat, const Matrix4x4& minv )
00292     {
00293         m = mat;
00294         mInv = minv;
00295     }
00296     
00297     friend std::ostream &operator<<( std::ostream &, const Transform & );
00298     
00299     //! affiche la matrice representant la transformation.
00300     void print() const
00301     {
00302         m.print();
00303     }
00304     
00305     //! reinitialise la transformation
00306     void identity( )
00307     {
00308         *this= Transform();
00309     }
00310     
00311     //! renvoie la transformation sous forme de matrice openGL, utilisable directement avec glLoadTransposeMatrixf();
00312     const Matrix4x4& getGLTransposeMatrix( ) const
00313     {
00314         return m;
00315     }
00316     
00317     //! renvoie la transformation sous forme de matrice.
00318     const Matrix4x4& matrix( ) const
00319     {
00320         return m;
00321     }
00322     
00323     Matrix4x4 transposeMatrix( ) const
00324     {
00325         return m.Transpose();
00326     }
00327     //! renvoie la transformation inverse sous forme de matrice.
00328     const Matrix4x4& inverseMatrix( ) const
00329     {
00330         return mInv;
00331     }
00332     
00333     //! renvoie la matrice de transformation des normales associee a la transformation directe = inverse transpose.
00334     Matrix4x4 normalMatrix( ) const
00335     {
00336         return mInv.Transpose();
00337     }
00338     
00339     //! renvoie la transformation inverse.
00340     Transform getInverse() const
00341     {
00342         return Transform( mInv, m );
00343     }
00344     
00345     //! \name transformations de points, vecteurs, normales, rayons, aabox. passage du repere '1' au repere '2'.
00346     // @{
00347     inline Point operator()( const Point &p ) const;
00348     inline void operator()( const Point &p, Point &pt ) const;
00349 
00350     //! renvoie le point homogene transforme.
00351     inline void operator()( const Point &p, HPoint &pt ) const;
00352     inline HPoint operator()( const HPoint &p ) const;
00353     inline void operator()( const HPoint &p, HPoint &pt ) const;
00354     
00355     inline Vector operator()( const Vector &v ) const;
00356     inline void operator()( const Vector &v, Vector &vt ) const;
00357     inline Normal operator()( const Normal & ) const;
00358     inline void operator()( const Normal &, Normal &nt ) const;
00359     inline Ray operator()( const Ray &r ) const;
00360     inline void operator()( const Ray &r, Ray &rt ) const;
00361     BBox operator()( const BBox &b ) const;
00362     // @}
00363 
00364     //! \name transformations inverses de points, vecteurs, normales, rayons, aabox. passage du repere '2' vers le repere '1'.
00365     // @{
00366     inline Point inverse( const Point &p ) const;
00367     inline void inverse( const Point &p, Point &pt ) const;
00368 
00369     //! renvoie le point homogene transforme.
00370     inline void inverse( const Point &p, HPoint &pt ) const;
00371     
00372     inline Vector inverse( const Vector &v ) const;
00373     inline void inverse( const Vector &v, Vector &vt ) const;
00374     inline Normal inverse( const Normal & ) const;
00375     inline void inverse( const Normal &, Normal &nt ) const;
00376     inline Ray inverse( const Ray &r ) const;
00377     inline void inverse( const Ray &r, Ray &rt ) const;
00378     BBox inverse( const BBox &b ) const;
00379     // @}
00380     
00381     //! composition de 2 transformations.
00382     Transform operator*( const Transform &t2 ) const;
00383     
00384     bool SwapsHandedness() const;
00385 
00386 protected:
00387     // Transform Private Data
00388     //! les matrices directe et inverse de changement de repere.
00389     Matrix4x4 m, mInv;
00390 };
00391 
00392 Transform Viewport( float width, float height );
00393 Transform Perspective( float fov, float aspect, float znear, float zfar );
00394 Transform Orthographic( float znear, float zfar );
00395 Transform Orthographic( const float left, const float right, const float bottom, const float top, const float znear, const float zfar );
00396 Transform LookAt( const Point &pos, const Point &look, const Vector &up );
00397 Transform Rotate( float angle, const Vector &axis );
00398 Transform RotateX( float angle );
00399 Transform RotateY( float angle );
00400 Transform RotateZ( float angle );
00401 Transform Scale( float x, float y, float z );
00402 Transform Scale( float value );
00403 Transform Translate( const Vector &delta );
00404 
00405 
00406 // Transform Inline Functions
00407 inline 
00408 Point Transform::operator()( const Point &p ) const
00409 {
00410     const float x = p.x;
00411     const float y = p.y;
00412     const float z = p.z;
00413     
00414     const float xt = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00415     const float yt = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00416     const float zt = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00417     const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00418     
00419     assert( wt != 0 );
00420     if( wt == 1.f ) 
00421         return Point( xt, yt, zt );
00422     else
00423         return Point( xt, yt, zt ) / wt;
00424 }
00425 
00426 
00427 inline 
00428 void Transform::operator()( const Point &p, Point &pt ) const
00429 {
00430     const float x = p.x;
00431     const float y = p.y;
00432     const float z = p.z;
00433     
00434     pt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00435     pt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00436     pt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00437     
00438     const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00439     assert( wt != 0 );
00440     if( wt != 1.f ) 
00441         pt /= wt;
00442 }
00443 
00444 inline 
00445 void Transform::operator()( const Point &p, HPoint &pt ) const
00446 {
00447     const float x = p.x;
00448     const float y = p.y;
00449     const float z = p.z;
00450     
00451     pt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00452     pt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00453     pt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00454     pt.w = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00455 }
00456 
00457 inline 
00458 void Transform::operator()( const HPoint &p, HPoint &pt ) const
00459 {
00460     const float x = p.x;
00461     const float y = p.y;
00462     const float z = p.z;
00463     const float w = p.w;
00464 
00465     pt.x= m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3] * w;
00466     pt.y= m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3] * w;
00467     pt.z= m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3] * w; 
00468     pt.w= m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3] * w;
00469 }
00470 
00471 inline 
00472 HPoint Transform::operator()( const HPoint &p ) const
00473 {
00474     const float x = p.x;
00475     const float y = p.y;
00476     const float z = p.z;
00477     const float w = p.w;
00478 
00479     HPoint pt;
00480     pt.x= m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3] * w;
00481     pt.y= m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3] * w;
00482     pt.z= m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3] * w; 
00483     pt.w= m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3] * w;
00484     
00485     return pt;
00486 }
00487 
00488 inline 
00489 Vector Transform::operator()( const Vector &v ) const
00490 {
00491     const float x = v.x;
00492     const float y = v.y;
00493     const float z = v.z;
00494     
00495     return Vector( 
00496         m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z,
00497         m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z,
00498         m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z);
00499 }
00500 
00501 inline 
00502 void Transform::operator()( const Vector &v, Vector &vt ) const
00503 {
00504     const float x = v.x;
00505     const float y = v.y;
00506     const float z = v.z;
00507     
00508     vt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z;
00509     vt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z;
00510     vt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z;
00511 }
00512 
00513 inline 
00514 Normal Transform::operator()( const Normal &n ) const
00515 {
00516     const float x = n.x;
00517     const float y = n.y;
00518     const float z = n.z;
00519     
00520     return Normal( 
00521         mInv.m[0][0] * x + mInv.m[1][0] * y + mInv.m[2][0] * z,
00522         mInv.m[0][1] * x + mInv.m[1][1] * y + mInv.m[2][1] * z,
00523         mInv.m[0][2] * x + mInv.m[1][2] * y + mInv.m[2][2] * z);
00524 }
00525 
00526 inline 
00527 void Transform::operator()( const Normal &n, Normal& nt ) const
00528 {
00529     const float x = n.x;
00530     const float y = n.y;
00531     const float z = n.z;
00532     
00533     nt.x = mInv.m[0][0] * x + mInv.m[1][0] * y + mInv.m[2][0] * z;
00534     nt.y = mInv.m[0][1] * x + mInv.m[1][1] * y + mInv.m[2][1] * z;
00535     nt.z = mInv.m[0][2] * x + mInv.m[1][2] * y + mInv.m[2][2] * z;
00536 }
00537 
00538 #if 1
00539 inline
00540 BBox Transform::operator()( const BBox &b ) const
00541 {
00542     // transformation rigide ...
00543     const Transform &M = *this;
00544     
00545     BBox ret( M( Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00546     ret = Union( ret, M( Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00547     ret = Union( ret, M( Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00548     ret = Union( ret, M( Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00549     ret = Union( ret, M( Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00550     ret = Union( ret, M( Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00551     ret = Union( ret, M( Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00552     ret = Union( ret, M( Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );
00553     
00554     return ret;
00555 }
00556 #endif
00557 
00558 inline 
00559 Ray Transform::operator()( const Ray &ray ) const
00560 {
00561     //~ return Ray( (*this)(ray.o), (*this)(ray.d), ray.tmin, ray.tmax );
00562     return Ray( (*this)(ray.o), (*this)(ray.d), RAY_EPSILON, ray.tmax );
00563 }
00564 
00565 inline 
00566 void Transform::operator()( const Ray &ray, Ray &rt ) const
00567 {
00568     //~ rt= Ray( (*this)(ray.o), (*this)(ray.d), ray.tmin, ray.tmax );
00569     rt= Ray( (*this)(ray.o), (*this)(ray.d), RAY_EPSILON, ray.tmax );
00570 }
00571 
00572 
00573 // inverse Transform Inline Functions
00574 inline 
00575 Point Transform::inverse( const Point &p ) const
00576 {
00577     const float x = p.x;
00578     const float y = p.y;
00579     const float z = p.z;
00580     
00581     const float xt = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00582     const float yt = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00583     const float zt = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00584     const float wt = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00585     
00586     assert( wt != 0 );
00587     if( wt == 1.f ) 
00588         return Point( xt, yt, zt );
00589     else
00590         return Point( xt, yt, zt ) / wt;
00591 }
00592 
00593 
00594 inline 
00595 void Transform::inverse( const Point &p, Point &pt ) const
00596 {
00597     const float x = p.x;
00598     const float y = p.y;
00599     const float z = p.z;
00600     
00601     pt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00602     pt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00603     pt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00604     
00605     const float wt = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00606     assert( wt != 0 );
00607     if( wt != 1.f ) 
00608         pt /= wt;
00609 }
00610 
00611 inline 
00612 void Transform::inverse( const Point &p, HPoint &pt ) const
00613 {
00614     const float x = p.x;
00615     const float y = p.y;
00616     const float z = p.z;
00617     
00618     pt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00619     pt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00620     pt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00621     pt.w = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00622 }
00623 
00624 inline 
00625 Vector Transform::inverse( const Vector &v ) const
00626 {
00627     const float x = v.x;
00628     const float y = v.y;
00629     const float z = v.z;
00630     
00631     return Vector( 
00632         mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z,
00633         mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z,
00634         mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z);
00635 }
00636 
00637 inline 
00638 void Transform::inverse( const Vector &v, Vector &vt ) const
00639 {
00640     const float x = v.x;
00641     const float y = v.y;
00642     const float z = v.z;
00643     
00644     vt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z;
00645     vt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z;
00646     vt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z;
00647 }
00648 
00649 inline 
00650 Normal Transform::inverse( const Normal &n ) const
00651 {
00652     const float x = n.x;
00653     const float y = n.y;
00654     const float z = n.z;
00655     
00656     return Normal( 
00657         m.m[0][0] * x + m.m[1][0] * y + m.m[2][0] * z,
00658         m.m[0][1] * x + m.m[1][1] * y + m.m[2][1] * z,
00659         m.m[0][2] * x + m.m[1][2] * y + m.m[2][2] * z);
00660 }
00661 
00662 inline 
00663 void Transform::inverse( const Normal &n, Normal& nt ) const
00664 {
00665     const float x = n.x;
00666     const float y = n.y;
00667     const float z = n.z;
00668     
00669     nt.x = m.m[0][0] * x + m.m[1][0] * y + m.m[2][0] * z;
00670     nt.y = m.m[0][1] * x + m.m[1][1] * y + m.m[2][1] * z;
00671     nt.z = m.m[0][2] * x + m.m[1][2] * y + m.m[2][2] * z;
00672 }
00673 
00674 #if 1
00675 inline
00676 BBox Transform::inverse( const BBox &b ) const
00677 {
00678     // transformation rigide ...
00679     const Transform &M = *this;
00680     
00681     BBox ret( M.inverse( Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00682     ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00683     ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00684     ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00685     ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00686     ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00687     ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00688     ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );
00689     
00690     return ret;
00691 }
00692 #endif
00693 
00694 inline 
00695 Ray Transform::inverse( const Ray &ray ) const
00696 {
00697     //~ return Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), ray.tmin, ray.tmax );
00698     return Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), RAY_EPSILON, ray.tmax );
00699 }
00700 
00701 inline 
00702 void Transform::inverse( const Ray &ray, Ray &rt ) const
00703 {
00704     //~ rt= Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), ray.tmin, ray.tmax );
00705     rt= Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), RAY_EPSILON, ray.tmax );
00706 }
00707 // @}
00708 
00709 } // namespace
00710 
00711 #endif // PBRT_TRANSFORM_H
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends