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