gKitGL
|
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