PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathBox.h
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