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 Matrix4x4 rotationMatrix( ) const
00328 {
00329 return mInv.Transpose();
00330 }
00331
00332
00333 Transform getInverse() const
00334 {
00335 return Transform( mInv, m );
00336 }
00337
00338
00339
00340 inline Point operator()( const Point &p ) const;
00341 inline void operator()( const Point &p, Point &pt ) const;
00342
00343
00344 inline void operator()( const Point &p, HPoint &pt ) const;
00345 inline HPoint operator()( const HPoint &p ) const;
00346 inline void operator()( const HPoint &p, HPoint &pt ) const;
00347
00348 inline Vector operator()( const Vector &v ) const;
00349 inline void operator()( const Vector &v, Vector &vt ) const;
00350 inline Normal operator()( const Normal & ) const;
00351 inline void operator()( const Normal &, Normal &nt ) const;
00352 inline Ray operator()( const Ray &r ) const;
00353 inline void operator()( const Ray &r, Ray &rt ) const;
00354 BBox operator()( const BBox &b ) const;
00355
00356
00357
00358
00359 inline Point inverse( const Point &p ) const;
00360 inline void inverse( const Point &p, Point &pt ) const;
00361
00362
00363 inline void inverse( const Point &p, HPoint &pt ) const;
00364
00365 inline Vector inverse( const Vector &v ) const;
00366 inline void inverse( const Vector &v, Vector &vt ) const;
00367 inline Normal inverse( const Normal & ) const;
00368 inline void inverse( const Normal &, Normal &nt ) const;
00369 inline Ray inverse( const Ray &r ) const;
00370 inline void inverse( const Ray &r, Ray &rt ) const;
00371 BBox inverse( const BBox &b ) const;
00372
00373
00374
00375 Transform operator*( const Transform &t2 ) const;
00376
00377 bool SwapsHandedness() const;
00378
00379 protected:
00380
00381
00382 Matrix4x4 m, mInv;
00383 };
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 Transform Viewport( float width, float height );
00394 Transform Perspective( float fov, float aspect, float znear, float zfar );
00395 Transform Orthographic( float znear, float zfar );
00396 Transform Orthographic( const float left, const float right, const float bottom, const float top, const float znear, const float zfar );
00397 Transform LookAt( const Point &pos, const Point &look, const Vector &up );
00398 Transform Rotate( float angle, const Vector &axis );
00399 Transform RotateX( float angle );
00400 Transform RotateY( float angle );
00401 Transform RotateZ( float angle );
00402 Transform Scale( float x, float y, float z );
00403 Transform Scale( float value );
00404 Transform Translate( const Vector &delta );
00405
00406
00407
00408 inline
00409 Point Transform::operator()( const Point &p ) const
00410 {
00411 const float x = p.x;
00412 const float y = p.y;
00413 const float z = p.z;
00414
00415 const float xt = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00416 const float yt = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00417 const float zt = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00418 const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00419
00420 assert( wt != 0 );
00421 if( wt == 1.f )
00422 return Point( xt, yt, zt );
00423 else
00424 return Point( xt, yt, zt ) / wt;
00425 }
00426
00427
00428 inline
00429 void Transform::operator()( const Point &p, Point &pt ) const
00430 {
00431 const float x = p.x;
00432 const float y = p.y;
00433 const float z = p.z;
00434
00435 pt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00436 pt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00437 pt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00438
00439 const float wt = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00440 assert( wt != 0 );
00441 if( wt != 1.f )
00442 pt /= wt;
00443 }
00444
00445 inline
00446 void Transform::operator()( const Point &p, HPoint &pt ) const
00447 {
00448 const float x = p.x;
00449 const float y = p.y;
00450 const float z = p.z;
00451
00452 pt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3];
00453 pt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3];
00454 pt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3];
00455 pt.w = m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3];
00456 }
00457
00458 inline
00459 void Transform::operator()( const HPoint &p, HPoint &pt ) const
00460 {
00461 const float x = p.x;
00462 const float y = p.y;
00463 const float z = p.z;
00464 const float w = p.w;
00465
00466 pt.x= m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3] * w;
00467 pt.y= m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3] * w;
00468 pt.z= m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3] * w;
00469 pt.w= m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3] * w;
00470 }
00471
00472 inline
00473 HPoint Transform::operator()( const HPoint &p ) const
00474 {
00475 const float x = p.x;
00476 const float y = p.y;
00477 const float z = p.z;
00478 const float w = p.w;
00479
00480 HPoint pt;
00481 pt.x= m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z + m.m[0][3] * w;
00482 pt.y= m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z + m.m[1][3] * w;
00483 pt.z= m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z + m.m[2][3] * w;
00484 pt.w= m.m[3][0] * x + m.m[3][1] * y + m.m[3][2] * z + m.m[3][3] * w;
00485
00486 return pt;
00487 }
00488
00489 inline
00490 Vector Transform::operator()( const Vector &v ) const
00491 {
00492 const float x = v.x;
00493 const float y = v.y;
00494 const float z = v.z;
00495
00496 return Vector(
00497 m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z,
00498 m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z,
00499 m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z);
00500 }
00501
00502 inline
00503 void Transform::operator()( const Vector &v, Vector &vt ) const
00504 {
00505 const float x = v.x;
00506 const float y = v.y;
00507 const float z = v.z;
00508
00509 vt.x = m.m[0][0] * x + m.m[0][1] * y + m.m[0][2] * z;
00510 vt.y = m.m[1][0] * x + m.m[1][1] * y + m.m[1][2] * z;
00511 vt.z = m.m[2][0] * x + m.m[2][1] * y + m.m[2][2] * z;
00512 }
00513
00514 inline
00515 Normal Transform::operator()( const Normal &n ) const
00516 {
00517 const float x = n.x;
00518 const float y = n.y;
00519 const float z = n.z;
00520
00521 return Normal(
00522 mInv.m[0][0] * x + mInv.m[1][0] * y + mInv.m[2][0] * z,
00523 mInv.m[0][1] * x + mInv.m[1][1] * y + mInv.m[2][1] * z,
00524 mInv.m[0][2] * x + mInv.m[1][2] * y + mInv.m[2][2] * z);
00525 }
00526
00527 inline
00528 void Transform::operator()( const Normal &n, Normal& nt ) const
00529 {
00530 const float x = n.x;
00531 const float y = n.y;
00532 const float z = n.z;
00533
00534 nt.x = mInv.m[0][0] * x + mInv.m[1][0] * y + mInv.m[2][0] * z;
00535 nt.y = mInv.m[0][1] * x + mInv.m[1][1] * y + mInv.m[2][1] * z;
00536 nt.z = mInv.m[0][2] * x + mInv.m[1][2] * y + mInv.m[2][2] * z;
00537 }
00538
00539 #if 1
00540 inline
00541 BBox Transform::operator()( const BBox &b ) const
00542 {
00543
00544 const Transform &M = *this;
00545
00546 BBox ret( M( Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00547 ret = Union( ret, M( Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00548 ret = Union( ret, M( Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00549 ret = Union( ret, M( Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00550 ret = Union( ret, M( Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00551 ret = Union( ret, M( Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00552 ret = Union( ret, M( Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00553 ret = Union( ret, M( Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );
00554
00555 return ret;
00556 }
00557 #endif
00558
00559 inline
00560 Ray Transform::operator()( const Ray &ray ) const
00561 {
00562 return Ray( (*this)(ray.o), (*this)(ray.d), ray.tmin, 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 }
00570
00571
00572
00573 inline
00574 Point Transform::inverse( const Point &p ) const
00575 {
00576 const float x = p.x;
00577 const float y = p.y;
00578 const float z = p.z;
00579
00580 const float xt = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00581 const float yt = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00582 const float zt = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00583 const float wt = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00584
00585 assert( wt != 0 );
00586 if( wt == 1.f )
00587 return Point( xt, yt, zt );
00588 else
00589 return Point( xt, yt, zt ) / wt;
00590 }
00591
00592
00593 inline
00594 void Transform::inverse( const Point &p, Point &pt ) const
00595 {
00596 const float x = p.x;
00597 const float y = p.y;
00598 const float z = p.z;
00599
00600 pt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00601 pt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00602 pt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00603
00604 const float wt = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00605 assert( wt != 0 );
00606 if( wt != 1.f )
00607 pt /= wt;
00608 }
00609
00610 inline
00611 void Transform::inverse( const Point &p, HPoint &pt ) const
00612 {
00613 const float x = p.x;
00614 const float y = p.y;
00615 const float z = p.z;
00616
00617 pt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z + mInv.m[0][3];
00618 pt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z + mInv.m[1][3];
00619 pt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z + mInv.m[2][3];
00620 pt.w = mInv.m[3][0] * x + mInv.m[3][1] * y + mInv.m[3][2] * z + mInv.m[3][3];
00621 }
00622
00623 inline
00624 Vector Transform::inverse( const Vector &v ) const
00625 {
00626 const float x = v.x;
00627 const float y = v.y;
00628 const float z = v.z;
00629
00630 return Vector(
00631 mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z,
00632 mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z,
00633 mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z);
00634 }
00635
00636 inline
00637 void Transform::inverse( const Vector &v, Vector &vt ) const
00638 {
00639 const float x = v.x;
00640 const float y = v.y;
00641 const float z = v.z;
00642
00643 vt.x = mInv.m[0][0] * x + mInv.m[0][1] * y + mInv.m[0][2] * z;
00644 vt.y = mInv.m[1][0] * x + mInv.m[1][1] * y + mInv.m[1][2] * z;
00645 vt.z = mInv.m[2][0] * x + mInv.m[2][1] * y + mInv.m[2][2] * z;
00646 }
00647
00648 inline
00649 Normal Transform::inverse( const Normal &n ) const
00650 {
00651 const float x = n.x;
00652 const float y = n.y;
00653 const float z = n.z;
00654
00655 return Normal(
00656 m.m[0][0] * x + m.m[1][0] * y + m.m[2][0] * z,
00657 m.m[0][1] * x + m.m[1][1] * y + m.m[2][1] * z,
00658 m.m[0][2] * x + m.m[1][2] * y + m.m[2][2] * z);
00659 }
00660
00661 inline
00662 void Transform::inverse( const Normal &n, Normal& nt ) const
00663 {
00664 const float x = n.x;
00665 const float y = n.y;
00666 const float z = n.z;
00667
00668 nt.x = m.m[0][0] * x + m.m[1][0] * y + m.m[2][0] * z;
00669 nt.y = m.m[0][1] * x + m.m[1][1] * y + m.m[2][1] * z;
00670 nt.z = m.m[0][2] * x + m.m[1][2] * y + m.m[2][2] * z;
00671 }
00672
00673 #if 1
00674 inline
00675 BBox Transform::inverse( const BBox &b ) const
00676 {
00677
00678 const Transform &M = *this;
00679
00680 BBox ret( M.inverse( Point( b.pMin.x, b.pMin.y, b.pMin.z ) ) );
00681 ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMin.y, b.pMin.z ) ) );
00682 ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMax.y, b.pMin.z ) ) );
00683 ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMin.y, b.pMax.z ) ) );
00684 ret = Union( ret, M.inverse( Point( b.pMin.x, b.pMax.y, b.pMax.z ) ) );
00685 ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMax.y, b.pMin.z ) ) );
00686 ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMin.y, b.pMax.z ) ) );
00687 ret = Union( ret, M.inverse( Point( b.pMax.x, b.pMax.y, b.pMax.z ) ) );
00688
00689 return ret;
00690 }
00691 #endif
00692
00693 inline
00694 Ray Transform::inverse( const Ray &ray ) const
00695 {
00696 return Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), ray.tmin, ray.tmax );
00697 }
00698
00699 inline
00700 void Transform::inverse( const Ray &ray, Ray &rt ) const
00701 {
00702 rt= Ray( (*this).inverse(ray.o), (*this).inverse(ray.d), ray.tmin, ray.tmax );
00703 }
00704
00705 }
00706
00707 #endif // PBRT_TRANSFORM_H