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