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 #ifndef INCLUDED_IMATHBOX_H 00037 #define INCLUDED_IMATHBOX_H 00038 00039 //------------------------------------------------------------------- 00040 // 00041 // class Imath::Box<class T> 00042 // -------------------------------- 00043 // 00044 // This class imposes the following requirements on its 00045 // parameter class: 00046 // 00047 // 1) The class T must implement these operators: 00048 // + - < > <= >= = 00049 // with the signature (T,T) and the expected 00050 // return values for a numeric type. 00051 // 00052 // 2) The class T must implement operator= 00053 // with the signature (T,float and/or double) 00054 // 00055 // 3) The class T must have a constructor which takes 00056 // a float (and/or double) for use in initializing the box. 00057 // 00058 // 4) The class T must have a function T::dimensions() 00059 // which returns the number of dimensions in the class 00060 // (since its assumed its a vector) -- preferably, this 00061 // returns a constant expression. 00062 // 00063 //------------------------------------------------------------------- 00064 00065 #include "ImathVec.h" 00066 00067 namespace Imath { 00068 00069 00070 template <class T> 00071 class Box 00072 { 00073 public: 00074 00075 //------------------------- 00076 // Data Members are public 00077 //------------------------- 00078 00079 T min; 00080 T max; 00081 00082 //----------------------------------------------------- 00083 // Constructors - an "empty" box is created by default 00084 //----------------------------------------------------- 00085 00086 Box (); 00087 Box (const T &point); 00088 Box (const T &minT, const T &maxT); 00089 00090 //-------------------- 00091 // Operators: ==, != 00092 //-------------------- 00093 00094 bool operator == (const Box<T> &src) const; 00095 bool operator != (const Box<T> &src) const; 00096 00097 //------------------ 00098 // Box manipulation 00099 //------------------ 00100 00101 void makeEmpty (); 00102 void extendBy (const T &point); 00103 void extendBy (const Box<T> &box); 00104 00105 //--------------------------------------------------- 00106 // Query functions - these compute results each time 00107 //--------------------------------------------------- 00108 00109 T size () const; 00110 T center () const; 00111 bool intersects (const T &point) const; 00112 bool intersects (const Box<T> &box) const; 00113 00114 unsigned int majorAxis () const; 00115 00116 //---------------- 00117 // Classification 00118 //---------------- 00119 00120 bool isEmpty () const; 00121 bool hasVolume () const; 00122 }; 00123 00124 00125 //-------------------- 00126 // Convenient typedefs 00127 //-------------------- 00128 00129 typedef Box <V2s> Box2s; 00130 typedef Box <V2i> Box2i; 00131 typedef Box <V2f> Box2f; 00132 typedef Box <V2d> Box2d; 00133 typedef Box <V3s> Box3s; 00134 typedef Box <V3i> Box3i; 00135 typedef Box <V3f> Box3f; 00136 typedef Box <V3d> Box3d; 00137 00138 00139 //---------------- 00140 // Implementation 00141 00142 00143 template <class T> 00144 inline Box<T>::Box() 00145 { 00146 makeEmpty(); 00147 } 00148 00149 00150 template <class T> 00151 inline Box<T>::Box (const T &point) 00152 { 00153 min = point; 00154 max = point; 00155 } 00156 00157 00158 template <class T> 00159 inline Box<T>::Box (const T &minT, const T &maxT) 00160 { 00161 min = minT; 00162 max = maxT; 00163 } 00164 00165 00166 template <class T> 00167 inline bool 00168 Box<T>::operator == (const Box<T> &src) const 00169 { 00170 return (min == src.min && max == src.max); 00171 } 00172 00173 00174 template <class T> 00175 inline bool 00176 Box<T>::operator != (const Box<T> &src) const 00177 { 00178 return (min != src.min || max != src.max); 00179 } 00180 00181 00182 template <class T> 00183 inline void Box<T>::makeEmpty() 00184 { 00185 min = T(T::baseTypeMax()); 00186 max = T(T::baseTypeMin()); 00187 } 00188 00189 00190 template <class T> 00191 inline void 00192 Box<T>::extendBy(const T &point) 00193 { 00194 for (unsigned int i = 0; i < min.dimensions(); i++) 00195 { 00196 if (point[i] < min[i]) 00197 min[i] = point[i]; 00198 00199 if (point[i] > max[i]) 00200 max[i] = point[i]; 00201 } 00202 } 00203 00204 00205 template <class T> 00206 inline void 00207 Box<T>::extendBy(const Box<T> &box) 00208 { 00209 for (unsigned int i = 0; i < min.dimensions(); i++) 00210 { 00211 if (box.min[i] < min[i]) 00212 min[i] = box.min[i]; 00213 00214 if (box.max[i] > max[i]) 00215 max[i] = box.max[i]; 00216 } 00217 } 00218 00219 00220 template <class T> 00221 inline bool 00222 Box<T>::intersects(const T &point) const 00223 { 00224 for (unsigned int i = 0; i < min.dimensions(); i++) 00225 { 00226 if (point[i] < min[i] || point[i] > max[i]) 00227 return false; 00228 } 00229 00230 return true; 00231 } 00232 00233 00234 template <class T> 00235 inline bool 00236 Box<T>::intersects(const Box<T> &box) const 00237 { 00238 for (unsigned int i = 0; i < min.dimensions(); i++) 00239 { 00240 if (box.max[i] < min[i] || box.min[i] > max[i]) 00241 return false; 00242 } 00243 00244 return true; 00245 } 00246 00247 00248 template <class T> 00249 inline T 00250 Box<T>::size() const 00251 { 00252 if (isEmpty()) 00253 return T (0); 00254 00255 return max - min; 00256 } 00257 00258 00259 template <class T> 00260 inline T 00261 Box<T>::center() const 00262 { 00263 return (max + min) / 2; 00264 } 00265 00266 00267 template <class T> 00268 inline bool 00269 Box<T>::isEmpty() const 00270 { 00271 for (unsigned int i = 0; i < min.dimensions(); i++) 00272 { 00273 if (max[i] < min[i]) 00274 return true; 00275 } 00276 00277 return false; 00278 } 00279 00280 00281 template <class T> 00282 inline bool 00283 Box<T>::hasVolume() const 00284 { 00285 for (unsigned int i = 0; i < min.dimensions(); i++) 00286 { 00287 if (max[i] <= min[i]) 00288 return false; 00289 } 00290 00291 return true; 00292 } 00293 00294 00295 template<class T> 00296 inline unsigned int 00297 Box<T>::majorAxis() const 00298 { 00299 unsigned int major = 0; 00300 T s = size(); 00301 00302 for (unsigned int i = 1; i < min.dimensions(); i++) 00303 { 00304 if (s[i] > s[major]) 00305 major = i; 00306 } 00307 00308 return major; 00309 } 00310 00311 //------------------------------------------------------------------- 00312 // 00313 // Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T> 00314 // 00315 //------------------------------------------------------------------- 00316 00317 template <typename T> class Box; 00318 00319 template <class T> 00320 class Box<Vec2<T> > 00321 { 00322 public: 00323 00324 //------------------------- 00325 // Data Members are public 00326 //------------------------- 00327 00328 Vec2<T> min; 00329 Vec2<T> max; 00330 00331 //----------------------------------------------------- 00332 // Constructors - an "empty" box is created by default 00333 //----------------------------------------------------- 00334 00335 Box(); 00336 Box (const Vec2<T> &point); 00337 Box (const Vec2<T> &minT, const Vec2<T> &maxT); 00338 00339 //-------------------- 00340 // Operators: ==, != 00341 //-------------------- 00342 00343 bool operator == (const Box<Vec2<T> > &src) const; 00344 bool operator != (const Box<Vec2<T> > &src) const; 00345 00346 //------------------ 00347 // Box manipulation 00348 //------------------ 00349 00350 void makeEmpty(); 00351 void extendBy (const Vec2<T> &point); 00352 void extendBy (const Box<Vec2<T> > &box); 00353 00354 //--------------------------------------------------- 00355 // Query functions - these compute results each time 00356 //--------------------------------------------------- 00357 00358 Vec2<T> size() const; 00359 Vec2<T> center() const; 00360 bool intersects (const Vec2<T> &point) const; 00361 bool intersects (const Box<Vec2<T> > &box) const; 00362 00363 unsigned int majorAxis() const; 00364 00365 //---------------- 00366 // Classification 00367 //---------------- 00368 00369 bool isEmpty() const; 00370 bool hasVolume() const; 00371 }; 00372 00373 00374 //---------------- 00375 // Implementation 00376 00377 template <class T> 00378 inline Box<Vec2<T> >::Box() 00379 { 00380 makeEmpty(); 00381 } 00382 00383 00384 template <class T> 00385 inline Box<Vec2<T> >::Box (const Vec2<T> &point) 00386 { 00387 min = point; 00388 max = point; 00389 } 00390 00391 00392 template <class T> 00393 inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT) 00394 { 00395 min = minT; 00396 max = maxT; 00397 } 00398 00399 00400 template <class T> 00401 inline bool 00402 Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const 00403 { 00404 return (min == src.min && max == src.max); 00405 } 00406 00407 00408 template <class T> 00409 inline bool 00410 Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const 00411 { 00412 return (min != src.min || max != src.max); 00413 } 00414 00415 00416 template <class T> 00417 inline void Box<Vec2<T> >::makeEmpty() 00418 { 00419 min = Vec2<T>(Vec2<T>::baseTypeMax()); 00420 max = Vec2<T>(Vec2<T>::baseTypeMin()); 00421 } 00422 00423 00424 template <class T> 00425 inline void 00426 Box<Vec2<T> >::extendBy (const Vec2<T> &point) 00427 { 00428 if (point[0] < min[0]) 00429 min[0] = point[0]; 00430 00431 if (point[0] > max[0]) 00432 max[0] = point[0]; 00433 00434 if (point[1] < min[1]) 00435 min[1] = point[1]; 00436 00437 if (point[1] > max[1]) 00438 max[1] = point[1]; 00439 } 00440 00441 00442 template <class T> 00443 inline void 00444 Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box) 00445 { 00446 if (box.min[0] < min[0]) 00447 min[0] = box.min[0]; 00448 00449 if (box.max[0] > max[0]) 00450 max[0] = box.max[0]; 00451 00452 if (box.min[1] < min[1]) 00453 min[1] = box.min[1]; 00454 00455 if (box.max[1] > max[1]) 00456 max[1] = box.max[1]; 00457 } 00458 00459 00460 template <class T> 00461 inline bool 00462 Box<Vec2<T> >::intersects (const Vec2<T> &point) const 00463 { 00464 if (point[0] < min[0] || point[0] > max[0] || 00465 point[1] < min[1] || point[1] > max[1]) 00466 return false; 00467 00468 return true; 00469 } 00470 00471 00472 template <class T> 00473 inline bool 00474 Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const 00475 { 00476 if (box.max[0] < min[0] || box.min[0] > max[0] || 00477 box.max[1] < min[1] || box.min[1] > max[1]) 00478 return false; 00479 00480 return true; 00481 } 00482 00483 00484 template <class T> 00485 inline Vec2<T> 00486 Box<Vec2<T> >::size() const 00487 { 00488 if (isEmpty()) 00489 return Vec2<T> (0); 00490 00491 return max - min; 00492 } 00493 00494 00495 template <class T> 00496 inline Vec2<T> 00497 Box<Vec2<T> >::center() const 00498 { 00499 return (max + min) / 2; 00500 } 00501 00502 00503 template <class T> 00504 inline bool 00505 Box<Vec2<T> >::isEmpty() const 00506 { 00507 if (max[0] < min[0] || 00508 max[1] < min[1]) 00509 return true; 00510 00511 return false; 00512 } 00513 00514 00515 template <class T> 00516 inline bool 00517 Box<Vec2<T> >::hasVolume() const 00518 { 00519 if (max[0] <= min[0] || 00520 max[1] <= min[1]) 00521 return false; 00522 00523 return true; 00524 } 00525 00526 00527 template <class T> 00528 inline unsigned int 00529 Box<Vec2<T> >::majorAxis() const 00530 { 00531 unsigned int major = 0; 00532 Vec2<T> s = size(); 00533 00534 if (s[1] > s[major]) 00535 major = 1; 00536 00537 return major; 00538 } 00539 00540 00541 template <class T> 00542 class Box<Vec3<T> > 00543 { 00544 public: 00545 00546 //------------------------- 00547 // Data Members are public 00548 //------------------------- 00549 00550 Vec3<T> min; 00551 Vec3<T> max; 00552 00553 //----------------------------------------------------- 00554 // Constructors - an "empty" box is created by default 00555 //----------------------------------------------------- 00556 00557 Box(); 00558 Box (const Vec3<T> &point); 00559 Box (const Vec3<T> &minT, const Vec3<T> &maxT); 00560 00561 //-------------------- 00562 // Operators: ==, != 00563 //-------------------- 00564 00565 bool operator == (const Box<Vec3<T> > &src) const; 00566 bool operator != (const Box<Vec3<T> > &src) const; 00567 00568 //------------------ 00569 // Box manipulation 00570 //------------------ 00571 00572 void makeEmpty(); 00573 void extendBy (const Vec3<T> &point); 00574 void extendBy (const Box<Vec3<T> > &box); 00575 00576 //--------------------------------------------------- 00577 // Query functions - these compute results each time 00578 //--------------------------------------------------- 00579 00580 Vec3<T> size() const; 00581 Vec3<T> center() const; 00582 bool intersects (const Vec3<T> &point) const; 00583 bool intersects (const Box<Vec3<T> > &box) const; 00584 00585 unsigned int majorAxis() const; 00586 00587 //---------------- 00588 // Classification 00589 //---------------- 00590 00591 bool isEmpty() const; 00592 bool hasVolume() const; 00593 }; 00594 00595 00596 //---------------- 00597 // Implementation 00598 00599 00600 template <class T> 00601 inline Box<Vec3<T> >::Box() 00602 { 00603 makeEmpty(); 00604 } 00605 00606 00607 template <class T> 00608 inline Box<Vec3<T> >::Box (const Vec3<T> &point) 00609 { 00610 min = point; 00611 max = point; 00612 } 00613 00614 00615 template <class T> 00616 inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT) 00617 { 00618 min = minT; 00619 max = maxT; 00620 } 00621 00622 00623 template <class T> 00624 inline bool 00625 Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const 00626 { 00627 return (min == src.min && max == src.max); 00628 } 00629 00630 00631 template <class T> 00632 inline bool 00633 Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const 00634 { 00635 return (min != src.min || max != src.max); 00636 } 00637 00638 00639 template <class T> 00640 inline void Box<Vec3<T> >::makeEmpty() 00641 { 00642 min = Vec3<T>(Vec3<T>::baseTypeMax()); 00643 max = Vec3<T>(Vec3<T>::baseTypeMin()); 00644 } 00645 00646 00647 template <class T> 00648 inline void 00649 Box<Vec3<T> >::extendBy (const Vec3<T> &point) 00650 { 00651 if (point[0] < min[0]) 00652 min[0] = point[0]; 00653 00654 if (point[0] > max[0]) 00655 max[0] = point[0]; 00656 00657 if (point[1] < min[1]) 00658 min[1] = point[1]; 00659 00660 if (point[1] > max[1]) 00661 max[1] = point[1]; 00662 00663 if (point[2] < min[2]) 00664 min[2] = point[2]; 00665 00666 if (point[2] > max[2]) 00667 max[2] = point[2]; 00668 } 00669 00670 00671 template <class T> 00672 inline void 00673 Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box) 00674 { 00675 if (box.min[0] < min[0]) 00676 min[0] = box.min[0]; 00677 00678 if (box.max[0] > max[0]) 00679 max[0] = box.max[0]; 00680 00681 if (box.min[1] < min[1]) 00682 min[1] = box.min[1]; 00683 00684 if (box.max[1] > max[1]) 00685 max[1] = box.max[1]; 00686 00687 if (box.min[2] < min[2]) 00688 min[2] = box.min[2]; 00689 00690 if (box.max[2] > max[2]) 00691 max[2] = box.max[2]; 00692 } 00693 00694 00695 template <class T> 00696 inline bool 00697 Box<Vec3<T> >::intersects (const Vec3<T> &point) const 00698 { 00699 if (point[0] < min[0] || point[0] > max[0] || 00700 point[1] < min[1] || point[1] > max[1] || 00701 point[2] < min[2] || point[2] > max[2]) 00702 return false; 00703 00704 return true; 00705 } 00706 00707 00708 template <class T> 00709 inline bool 00710 Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const 00711 { 00712 if (box.max[0] < min[0] || box.min[0] > max[0] || 00713 box.max[1] < min[1] || box.min[1] > max[1] || 00714 box.max[2] < min[2] || box.min[2] > max[2]) 00715 return false; 00716 00717 return true; 00718 } 00719 00720 00721 template <class T> 00722 inline Vec3<T> 00723 Box<Vec3<T> >::size() const 00724 { 00725 if (isEmpty()) 00726 return Vec3<T> (0); 00727 00728 return max - min; 00729 } 00730 00731 00732 template <class T> 00733 inline Vec3<T> 00734 Box<Vec3<T> >::center() const 00735 { 00736 return (max + min) / 2; 00737 } 00738 00739 00740 template <class T> 00741 inline bool 00742 Box<Vec3<T> >::isEmpty() const 00743 { 00744 if (max[0] < min[0] || 00745 max[1] < min[1] || 00746 max[2] < min[2]) 00747 return true; 00748 00749 return false; 00750 } 00751 00752 00753 template <class T> 00754 inline bool 00755 Box<Vec3<T> >::hasVolume() const 00756 { 00757 if (max[0] <= min[0] || 00758 max[1] <= min[1] || 00759 max[2] <= min[2]) 00760 return false; 00761 00762 return true; 00763 } 00764 00765 00766 template <class T> 00767 inline unsigned int 00768 Box<Vec3<T> >::majorAxis() const 00769 { 00770 unsigned int major = 0; 00771 Vec3<T> s = size(); 00772 00773 if (s[1] > s[major]) 00774 major = 1; 00775 00776 if (s[2] > s[major]) 00777 major = 2; 00778 00779 return major; 00780 } 00781 00782 00783 00784 00785 } // namespace Imath 00786 00787 #endif