PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 00037 #ifndef INCLUDED_IMATHSHEAR_H 00038 #define INCLUDED_IMATHSHEAR_H 00039 00040 //---------------------------------------------------- 00041 // 00042 // Shear6 class template. 00043 // 00044 //---------------------------------------------------- 00045 00046 #include "ImathExc.h" 00047 #include "ImathLimits.h" 00048 #include "ImathMath.h" 00049 #include "ImathVec.h" 00050 00051 #include <iostream> 00052 00053 00054 namespace Imath { 00055 00056 00057 00058 00059 template <class T> class Shear6 00060 { 00061 public: 00062 00063 //------------------- 00064 // Access to elements 00065 //------------------- 00066 00067 T xy, xz, yz, yx, zx, zy; 00068 00069 T & operator [] (int i); 00070 const T & operator [] (int i) const; 00071 00072 00073 //------------- 00074 // Constructors 00075 //------------- 00076 00077 Shear6 (); // (0 0 0 0 0 0) 00078 Shear6 (T XY, T XZ, T YZ); // (XY XZ YZ 0 0 0) 00079 Shear6 (const Vec3<T> &v); // (v.x v.y v.z 0 0 0) 00080 template <class S> // (v.x v.y v.z 0 0 0) 00081 Shear6 (const Vec3<S> &v); 00082 Shear6 (T XY, T XZ, T YZ, // (XY XZ YZ YX ZX ZY) 00083 T YX, T ZX, T ZY); 00084 00085 00086 //--------------------------------- 00087 // Copy constructors and assignment 00088 //--------------------------------- 00089 00090 Shear6 (const Shear6 &h); 00091 template <class S> Shear6 (const Shear6<S> &h); 00092 00093 const Shear6 & operator = (const Shear6 &h); 00094 template <class S> 00095 const Shear6 & operator = (const Vec3<S> &v); 00096 00097 00098 //---------------------- 00099 // Compatibility with Sb 00100 //---------------------- 00101 00102 template <class S> 00103 void setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY); 00104 00105 template <class S> 00106 void setValue (const Shear6<S> &h); 00107 00108 template <class S> 00109 void getValue (S &XY, S &XZ, S &YZ, 00110 S &YX, S &ZX, S &ZY) const; 00111 00112 template <class S> 00113 void getValue (Shear6<S> &h) const; 00114 00115 T * getValue(); 00116 const T * getValue() const; 00117 00118 00119 //--------- 00120 // Equality 00121 //--------- 00122 00123 template <class S> 00124 bool operator == (const Shear6<S> &h) const; 00125 00126 template <class S> 00127 bool operator != (const Shear6<S> &h) const; 00128 00129 //----------------------------------------------------------------------- 00130 // Compare two shears and test if they are "approximately equal": 00131 // 00132 // equalWithAbsError (h, e) 00133 // 00134 // Returns true if the coefficients of this and h are the same with 00135 // an absolute error of no more than e, i.e., for all i 00136 // 00137 // abs (this[i] - h[i]) <= e 00138 // 00139 // equalWithRelError (h, e) 00140 // 00141 // Returns true if the coefficients of this and h are the same with 00142 // a relative error of no more than e, i.e., for all i 00143 // 00144 // abs (this[i] - h[i]) <= e * abs (this[i]) 00145 //----------------------------------------------------------------------- 00146 00147 bool equalWithAbsError (const Shear6<T> &h, T e) const; 00148 bool equalWithRelError (const Shear6<T> &h, T e) const; 00149 00150 00151 //------------------------ 00152 // Component-wise addition 00153 //------------------------ 00154 00155 const Shear6 & operator += (const Shear6 &h); 00156 Shear6 operator + (const Shear6 &h) const; 00157 00158 00159 //--------------------------- 00160 // Component-wise subtraction 00161 //--------------------------- 00162 00163 const Shear6 & operator -= (const Shear6 &h); 00164 Shear6 operator - (const Shear6 &h) const; 00165 00166 00167 //------------------------------------ 00168 // Component-wise multiplication by -1 00169 //------------------------------------ 00170 00171 Shear6 operator - () const; 00172 const Shear6 & negate (); 00173 00174 00175 //------------------------------ 00176 // Component-wise multiplication 00177 //------------------------------ 00178 00179 const Shear6 & operator *= (const Shear6 &h); 00180 const Shear6 & operator *= (T a); 00181 Shear6 operator * (const Shear6 &h) const; 00182 Shear6 operator * (T a) const; 00183 00184 00185 //------------------------ 00186 // Component-wise division 00187 //------------------------ 00188 00189 const Shear6 & operator /= (const Shear6 &h); 00190 const Shear6 & operator /= (T a); 00191 Shear6 operator / (const Shear6 &h) const; 00192 Shear6 operator / (T a) const; 00193 00194 00195 //---------------------------------------------------------- 00196 // Number of dimensions, i.e. number of elements in a Shear6 00197 //---------------------------------------------------------- 00198 00199 static unsigned int dimensions() {return 6;} 00200 00201 00202 //------------------------------------------------- 00203 // Limitations of type T (see also class limits<T>) 00204 //------------------------------------------------- 00205 00206 static T baseTypeMin() {return limits<T>::min();} 00207 static T baseTypeMax() {return limits<T>::max();} 00208 static T baseTypeSmallest() {return limits<T>::smallest();} 00209 static T baseTypeEpsilon() {return limits<T>::epsilon();} 00210 00211 00212 //-------------------------------------------------------------- 00213 // Base type -- in templates, which accept a parameter, V, which 00214 // could be either a Vec2<T> or a Shear6<T>, you can refer to T as 00215 // V::BaseType 00216 //-------------------------------------------------------------- 00217 00218 typedef T BaseType; 00219 }; 00220 00221 00222 //-------------- 00223 // Stream output 00224 //-------------- 00225 00226 template <class T> 00227 std::ostream & operator << (std::ostream &s, const Shear6<T> &h); 00228 00229 00230 //---------------------------------------------------- 00231 // Reverse multiplication: scalar * Shear6<T> 00232 //---------------------------------------------------- 00233 00234 template <class S, class T> Shear6<T> operator * (S a, const Shear6<T> &h); 00235 00236 00237 //------------------------- 00238 // Typedefs for convenience 00239 //------------------------- 00240 00241 typedef Vec3 <float> Shear3f; 00242 typedef Vec3 <double> Shear3d; 00243 typedef Shear6 <float> Shear6f; 00244 typedef Shear6 <double> Shear6d; 00245 00246 00247 00248 00249 //----------------------- 00250 // Implementation of Shear6 00251 //----------------------- 00252 00253 template <class T> 00254 inline T & 00255 Shear6<T>::operator [] (int i) 00256 { 00257 return (&xy)[i]; 00258 } 00259 00260 template <class T> 00261 inline const T & 00262 Shear6<T>::operator [] (int i) const 00263 { 00264 return (&xy)[i]; 00265 } 00266 00267 template <class T> 00268 inline 00269 Shear6<T>::Shear6 () 00270 { 00271 xy = xz = yz = yx = zx = zy = 0; 00272 } 00273 00274 template <class T> 00275 inline 00276 Shear6<T>::Shear6 (T XY, T XZ, T YZ) 00277 { 00278 xy = XY; 00279 xz = XZ; 00280 yz = YZ; 00281 yx = 0; 00282 zx = 0; 00283 zy = 0; 00284 } 00285 00286 template <class T> 00287 inline 00288 Shear6<T>::Shear6 (const Vec3<T> &v) 00289 { 00290 xy = v.x; 00291 xz = v.y; 00292 yz = v.z; 00293 yx = 0; 00294 zx = 0; 00295 zy = 0; 00296 } 00297 00298 template <class T> 00299 template <class S> 00300 inline 00301 Shear6<T>::Shear6 (const Vec3<S> &v) 00302 { 00303 xy = T (v.x); 00304 xz = T (v.y); 00305 yz = T (v.z); 00306 yx = 0; 00307 zx = 0; 00308 zy = 0; 00309 } 00310 00311 template <class T> 00312 inline 00313 Shear6<T>::Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY) 00314 { 00315 xy = XY; 00316 xz = XZ; 00317 yz = YZ; 00318 yx = YX; 00319 zx = ZX; 00320 zy = ZY; 00321 } 00322 00323 template <class T> 00324 inline 00325 Shear6<T>::Shear6 (const Shear6 &h) 00326 { 00327 xy = h.xy; 00328 xz = h.xz; 00329 yz = h.yz; 00330 yx = h.yx; 00331 zx = h.zx; 00332 zy = h.zy; 00333 } 00334 00335 template <class T> 00336 template <class S> 00337 inline 00338 Shear6<T>::Shear6 (const Shear6<S> &h) 00339 { 00340 xy = T (h.xy); 00341 xz = T (h.xz); 00342 yz = T (h.yz); 00343 yx = T (h.yx); 00344 zx = T (h.zx); 00345 zy = T (h.zy); 00346 } 00347 00348 template <class T> 00349 inline const Shear6<T> & 00350 Shear6<T>::operator = (const Shear6 &h) 00351 { 00352 xy = h.xy; 00353 xz = h.xz; 00354 yz = h.yz; 00355 yx = h.yx; 00356 zx = h.zx; 00357 zy = h.zy; 00358 return *this; 00359 } 00360 00361 template <class T> 00362 template <class S> 00363 inline const Shear6<T> & 00364 Shear6<T>::operator = (const Vec3<S> &v) 00365 { 00366 xy = T (v.x); 00367 xz = T (v.y); 00368 yz = T (v.z); 00369 yx = 0; 00370 zx = 0; 00371 zy = 0; 00372 return *this; 00373 } 00374 00375 template <class T> 00376 template <class S> 00377 inline void 00378 Shear6<T>::setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY) 00379 { 00380 xy = T (XY); 00381 xz = T (XZ); 00382 yz = T (YZ); 00383 yx = T (YX); 00384 zx = T (ZX); 00385 zy = T (ZY); 00386 } 00387 00388 template <class T> 00389 template <class S> 00390 inline void 00391 Shear6<T>::setValue (const Shear6<S> &h) 00392 { 00393 xy = T (h.xy); 00394 xz = T (h.xz); 00395 yz = T (h.yz); 00396 yx = T (h.yx); 00397 zx = T (h.zx); 00398 zy = T (h.zy); 00399 } 00400 00401 template <class T> 00402 template <class S> 00403 inline void 00404 Shear6<T>::getValue (S &XY, S &XZ, S &YZ, S &YX, S &ZX, S &ZY) const 00405 { 00406 XY = S (xy); 00407 XZ = S (xz); 00408 YZ = S (yz); 00409 YX = S (yx); 00410 ZX = S (zx); 00411 ZY = S (zy); 00412 } 00413 00414 template <class T> 00415 template <class S> 00416 inline void 00417 Shear6<T>::getValue (Shear6<S> &h) const 00418 { 00419 h.xy = S (xy); 00420 h.xz = S (xz); 00421 h.yz = S (yz); 00422 h.yx = S (yx); 00423 h.zx = S (zx); 00424 h.zy = S (zy); 00425 } 00426 00427 template <class T> 00428 inline T * 00429 Shear6<T>::getValue() 00430 { 00431 return (T *) &xy; 00432 } 00433 00434 template <class T> 00435 inline const T * 00436 Shear6<T>::getValue() const 00437 { 00438 return (const T *) &xy; 00439 } 00440 00441 template <class T> 00442 template <class S> 00443 inline bool 00444 Shear6<T>::operator == (const Shear6<S> &h) const 00445 { 00446 return xy == h.xy && xz == h.xz && yz == h.yz && 00447 yx == h.yx && zx == h.zx && zy == h.zy; 00448 } 00449 00450 template <class T> 00451 template <class S> 00452 inline bool 00453 Shear6<T>::operator != (const Shear6<S> &h) const 00454 { 00455 return xy != h.xy || xz != h.xz || yz != h.yz || 00456 yx != h.yx || zx != h.zx || zy != h.zy; 00457 } 00458 00459 template <class T> 00460 bool 00461 Shear6<T>::equalWithAbsError (const Shear6<T> &h, T e) const 00462 { 00463 for (int i = 0; i < 6; i++) 00464 if (!Imath::equalWithAbsError ((*this)[i], h[i], e)) 00465 return false; 00466 00467 return true; 00468 } 00469 00470 template <class T> 00471 bool 00472 Shear6<T>::equalWithRelError (const Shear6<T> &h, T e) const 00473 { 00474 for (int i = 0; i < 6; i++) 00475 if (!Imath::equalWithRelError ((*this)[i], h[i], e)) 00476 return false; 00477 00478 return true; 00479 } 00480 00481 00482 template <class T> 00483 inline const Shear6<T> & 00484 Shear6<T>::operator += (const Shear6 &h) 00485 { 00486 xy += h.xy; 00487 xz += h.xz; 00488 yz += h.yz; 00489 yx += h.yx; 00490 zx += h.zx; 00491 zy += h.zy; 00492 return *this; 00493 } 00494 00495 template <class T> 00496 inline Shear6<T> 00497 Shear6<T>::operator + (const Shear6 &h) const 00498 { 00499 return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz, 00500 yx + h.yx, zx + h.zx, zy + h.zy); 00501 } 00502 00503 template <class T> 00504 inline const Shear6<T> & 00505 Shear6<T>::operator -= (const Shear6 &h) 00506 { 00507 xy -= h.xy; 00508 xz -= h.xz; 00509 yz -= h.yz; 00510 yx -= h.yx; 00511 zx -= h.zx; 00512 zy -= h.zy; 00513 return *this; 00514 } 00515 00516 template <class T> 00517 inline Shear6<T> 00518 Shear6<T>::operator - (const Shear6 &h) const 00519 { 00520 return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz, 00521 yx - h.yx, zx - h.zx, zy - h.zy); 00522 } 00523 00524 template <class T> 00525 inline Shear6<T> 00526 Shear6<T>::operator - () const 00527 { 00528 return Shear6 (-xy, -xz, -yz, -yx, -zx, -zy); 00529 } 00530 00531 template <class T> 00532 inline const Shear6<T> & 00533 Shear6<T>::negate () 00534 { 00535 xy = -xy; 00536 xz = -xz; 00537 yz = -yz; 00538 yx = -yx; 00539 zx = -zx; 00540 zy = -zy; 00541 return *this; 00542 } 00543 00544 template <class T> 00545 inline const Shear6<T> & 00546 Shear6<T>::operator *= (const Shear6 &h) 00547 { 00548 xy *= h.xy; 00549 xz *= h.xz; 00550 yz *= h.yz; 00551 yx *= h.yx; 00552 zx *= h.zx; 00553 zy *= h.zy; 00554 return *this; 00555 } 00556 00557 template <class T> 00558 inline const Shear6<T> & 00559 Shear6<T>::operator *= (T a) 00560 { 00561 xy *= a; 00562 xz *= a; 00563 yz *= a; 00564 yx *= a; 00565 zx *= a; 00566 zy *= a; 00567 return *this; 00568 } 00569 00570 template <class T> 00571 inline Shear6<T> 00572 Shear6<T>::operator * (const Shear6 &h) const 00573 { 00574 return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz, 00575 yx * h.yx, zx * h.zx, zy * h.zy); 00576 } 00577 00578 template <class T> 00579 inline Shear6<T> 00580 Shear6<T>::operator * (T a) const 00581 { 00582 return Shear6 (xy * a, xz * a, yz * a, 00583 yx * a, zx * a, zy * a); 00584 } 00585 00586 template <class T> 00587 inline const Shear6<T> & 00588 Shear6<T>::operator /= (const Shear6 &h) 00589 { 00590 xy /= h.xy; 00591 xz /= h.xz; 00592 yz /= h.yz; 00593 yx /= h.yx; 00594 zx /= h.zx; 00595 zy /= h.zy; 00596 return *this; 00597 } 00598 00599 template <class T> 00600 inline const Shear6<T> & 00601 Shear6<T>::operator /= (T a) 00602 { 00603 xy /= a; 00604 xz /= a; 00605 yz /= a; 00606 yx /= a; 00607 zx /= a; 00608 zy /= a; 00609 return *this; 00610 } 00611 00612 template <class T> 00613 inline Shear6<T> 00614 Shear6<T>::operator / (const Shear6 &h) const 00615 { 00616 return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz, 00617 yx / h.yx, zx / h.zx, zy / h.zy); 00618 } 00619 00620 template <class T> 00621 inline Shear6<T> 00622 Shear6<T>::operator / (T a) const 00623 { 00624 return Shear6 (xy / a, xz / a, yz / a, 00625 yx / a, zx / a, zy / a); 00626 } 00627 00628 00629 //----------------------------- 00630 // Stream output implementation 00631 //----------------------------- 00632 00633 template <class T> 00634 std::ostream & 00635 operator << (std::ostream &s, const Shear6<T> &h) 00636 { 00637 return s << '(' 00638 << h.xy << ' ' << h.xz << ' ' << h.yz 00639 << h.yx << ' ' << h.zx << ' ' << h.zy 00640 << ')'; 00641 } 00642 00643 00644 //----------------------------------------- 00645 // Implementation of reverse multiplication 00646 //----------------------------------------- 00647 00648 template <class S, class T> 00649 inline Shear6<T> 00650 operator * (S a, const Shear6<T> &h) 00651 { 00652 return Shear6<T> (a * h.xy, a * h.xz, a * h.yz, 00653 a * h.yx, a * h.zx, a * h.zy); 00654 } 00655 00656 00657 } // namespace Imath 00658 00659 #endif