• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 
36 #ifndef INCLUDED_IMATHBOX_H
37 #define INCLUDED_IMATHBOX_H
38 
39 //-------------------------------------------------------------------
40 //
41 //	class Imath::Box<class T>
42 //	--------------------------------
43 //
44 //	This class imposes the following requirements on its
45 //	parameter class:
46 //
47 //	1) The class T must implement these operators:
48 //			+ - < > <= >= =
49 //	   with the signature (T,T) and the expected
50 //	   return values for a numeric type.
51 //
52 //	2) The class T must implement operator=
53 //	   with the signature (T,float and/or double)
54 //
55 //	3) The class T must have a constructor which takes
56 //	   a float (and/or double) for use in initializing the box.
57 //
58 //	4) The class T must have a function T::dimensions()
59 //	   which returns the number of dimensions in the class
60 //	   (since its assumed its a vector) -- preferably, this
61 //	   returns a constant expression.
62 //
63 //-------------------------------------------------------------------
64 
65 #include "ImathVec.h"
66 
67 namespace Imath {
68 
69 
70 template <class T>
71 class Box
72 {
73   public:
74 
75     //-------------------------
76     //  Data Members are public
77     //-------------------------
78 
79     T				min;
80     T				max;
81 
82     //-----------------------------------------------------
83     //	Constructors - an "empty" box is created by default
84     //-----------------------------------------------------
85 
86     Box ();
87     Box (const T &point);
88     Box (const T &minT, const T &maxT);
89 
90     //--------------------
91     //  Operators:  ==, !=
92     //--------------------
93 
94     bool		operator == (const Box<T> &src) const;
95     bool		operator != (const Box<T> &src) const;
96 
97     //------------------
98     //	Box manipulation
99     //------------------
100 
101     void		makeEmpty ();
102     void		extendBy (const T &point);
103     void		extendBy (const Box<T> &box);
104     void		makeInfinite ();
105 
106     //---------------------------------------------------
107     //	Query functions - these compute results each time
108     //---------------------------------------------------
109 
110     T			size () const;
111     T			center () const;
112     bool		intersects (const T &point) const;
113     bool		intersects (const Box<T> &box) const;
114 
115     unsigned int	majorAxis () const;
116 
117     //----------------
118     //	Classification
119     //----------------
120 
121     bool		isEmpty () const;
122     bool		hasVolume () const;
123     bool		isInfinite () const;
124 };
125 
126 
127 //--------------------
128 // Convenient typedefs
129 //--------------------
130 
131 typedef Box <V2s> Box2s;
132 typedef Box <V2i> Box2i;
133 typedef Box <V2f> Box2f;
134 typedef Box <V2d> Box2d;
135 typedef Box <V3s> Box3s;
136 typedef Box <V3i> Box3i;
137 typedef Box <V3f> Box3f;
138 typedef Box <V3d> Box3d;
139 
140 
141 //----------------
142 //  Implementation
143 
144 
145 template <class T>
Box()146 inline Box<T>::Box()
147 {
148     makeEmpty();
149 }
150 
151 
152 template <class T>
Box(const T & point)153 inline Box<T>::Box (const T &point)
154 {
155     min = point;
156     max = point;
157 }
158 
159 
160 template <class T>
Box(const T & minT,const T & maxT)161 inline Box<T>::Box (const T &minT, const T &maxT)
162 {
163     min = minT;
164     max = maxT;
165 }
166 
167 
168 template <class T>
169 inline bool
170 Box<T>::operator == (const Box<T> &src) const
171 {
172     return (min == src.min && max == src.max);
173 }
174 
175 
176 template <class T>
177 inline bool
178 Box<T>::operator != (const Box<T> &src) const
179 {
180     return (min != src.min || max != src.max);
181 }
182 
183 
184 template <class T>
makeEmpty()185 inline void Box<T>::makeEmpty()
186 {
187     min = T(T::baseTypeMax());
188     max = T(T::baseTypeMin());
189 }
190 
191 template <class T>
makeInfinite()192 inline void Box<T>::makeInfinite()
193 {
194     min = T(T::baseTypeMin());
195     max = T(T::baseTypeMax());
196 }
197 
198 
199 template <class T>
200 inline void
extendBy(const T & point)201 Box<T>::extendBy(const T &point)
202 {
203     for (unsigned int i = 0; i < min.dimensions(); i++)
204     {
205     if (point[i] < min[i])
206         min[i] = point[i];
207 
208     if (point[i] > max[i])
209         max[i] = point[i];
210     }
211 }
212 
213 
214 template <class T>
215 inline void
extendBy(const Box<T> & box)216 Box<T>::extendBy(const Box<T> &box)
217 {
218     for (unsigned int i = 0; i < min.dimensions(); i++)
219     {
220     if (box.min[i] < min[i])
221         min[i] = box.min[i];
222 
223     if (box.max[i] > max[i])
224         max[i] = box.max[i];
225     }
226 }
227 
228 
229 template <class T>
230 inline bool
intersects(const T & point)231 Box<T>::intersects(const T &point) const
232 {
233     for (unsigned int i = 0; i < min.dimensions(); i++)
234     {
235         if (point[i] < min[i] || point[i] > max[i])
236         return false;
237     }
238 
239     return true;
240 }
241 
242 
243 template <class T>
244 inline bool
intersects(const Box<T> & box)245 Box<T>::intersects(const Box<T> &box) const
246 {
247     for (unsigned int i = 0; i < min.dimensions(); i++)
248     {
249         if (box.max[i] < min[i] || box.min[i] > max[i])
250         return false;
251     }
252 
253     return true;
254 }
255 
256 
257 template <class T>
258 inline T
size()259 Box<T>::size() const
260 {
261     if (isEmpty())
262     return T (0);
263 
264     return max - min;
265 }
266 
267 
268 template <class T>
269 inline T
center()270 Box<T>::center() const
271 {
272     return (max + min) / 2;
273 }
274 
275 
276 template <class T>
277 inline bool
isEmpty()278 Box<T>::isEmpty() const
279 {
280     for (unsigned int i = 0; i < min.dimensions(); i++)
281     {
282         if (max[i] < min[i])
283         return true;
284     }
285 
286     return false;
287 }
288 
289 template <class T>
290 inline bool
isInfinite()291 Box<T>::isInfinite() const
292 {
293     for (unsigned int i = 0; i < min.dimensions(); i++)
294     {
295         if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
296         return false;
297     }
298 
299     return true;
300 }
301 
302 
303 template <class T>
304 inline bool
hasVolume()305 Box<T>::hasVolume() const
306 {
307     for (unsigned int i = 0; i < min.dimensions(); i++)
308     {
309         if (max[i] <= min[i])
310         return false;
311     }
312 
313     return true;
314 }
315 
316 
317 template<class T>
318 inline unsigned int
majorAxis()319 Box<T>::majorAxis() const
320 {
321     unsigned int major = 0;
322     T s = size();
323 
324     for (unsigned int i = 1; i < min.dimensions(); i++)
325     {
326     if (s[i] > s[major])
327         major = i;
328     }
329 
330     return major;
331 }
332 
333 //-------------------------------------------------------------------
334 //
335 //  Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
336 //
337 //-------------------------------------------------------------------
338 
339 template <typename T> class Box;
340 
341 template <class T>
342 class Box<Vec2<T> >
343 {
344   public:
345 
346     //-------------------------
347     //  Data Members are public
348     //-------------------------
349 
350     Vec2<T>		min;
351     Vec2<T>		max;
352 
353     //-----------------------------------------------------
354     //  Constructors - an "empty" box is created by default
355     //-----------------------------------------------------
356 
357     Box();
358     Box (const Vec2<T> &point);
359     Box (const Vec2<T> &minT, const Vec2<T> &maxT);
360 
361     //--------------------
362     //  Operators:  ==, !=
363     //--------------------
364 
365     bool		operator == (const Box<Vec2<T> > &src) const;
366     bool		operator != (const Box<Vec2<T> > &src) const;
367 
368     //------------------
369     //  Box manipulation
370     //------------------
371 
372     void		makeEmpty();
373     void		extendBy (const Vec2<T> &point);
374     void		extendBy (const Box<Vec2<T> > &box);
375     void		makeInfinite();
376 
377     //---------------------------------------------------
378     //  Query functions - these compute results each time
379     //---------------------------------------------------
380 
381     Vec2<T>		size() const;
382     Vec2<T>		center() const;
383     bool		intersects (const Vec2<T> &point) const;
384     bool		intersects (const Box<Vec2<T> > &box) const;
385 
386     unsigned int	majorAxis() const;
387 
388     //----------------
389     //  Classification
390     //----------------
391 
392     bool		isEmpty() const;
393     bool		hasVolume() const;
394     bool		isInfinite() const;
395 };
396 
397 
398 //----------------
399 //  Implementation
400 
401 template <class T>
Box()402 inline Box<Vec2<T> >::Box()
403 {
404     makeEmpty();
405 }
406 
407 
408 template <class T>
Box(const Vec2<T> & point)409 inline Box<Vec2<T> >::Box (const Vec2<T> &point)
410 {
411     min = point;
412     max = point;
413 }
414 
415 
416 template <class T>
Box(const Vec2<T> & minT,const Vec2<T> & maxT)417 inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
418 {
419     min = minT;
420     max = maxT;
421 }
422 
423 
424 template <class T>
425 inline bool
426 Box<Vec2<T> >::operator ==  (const Box<Vec2<T> > &src) const
427 {
428     return (min == src.min && max == src.max);
429 }
430 
431 
432 template <class T>
433 inline bool
434 Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
435 {
436     return (min != src.min || max != src.max);
437 }
438 
439 
440 template <class T>
makeEmpty()441 inline void Box<Vec2<T> >::makeEmpty()
442 {
443     min = Vec2<T>(Vec2<T>::baseTypeMax());
444     max = Vec2<T>(Vec2<T>::baseTypeMin());
445 }
446 
447 template <class T>
makeInfinite()448 inline void Box<Vec2<T> >::makeInfinite()
449 {
450     min = Vec2<T>(Vec2<T>::baseTypeMin());
451     max = Vec2<T>(Vec2<T>::baseTypeMax());
452 }
453 
454 
455 template <class T>
456 inline void
extendBy(const Vec2<T> & point)457 Box<Vec2<T> >::extendBy (const Vec2<T> &point)
458 {
459     if (point[0] < min[0])
460         min[0] = point[0];
461 
462     if (point[0] > max[0])
463         max[0] = point[0];
464 
465     if (point[1] < min[1])
466         min[1] = point[1];
467 
468     if (point[1] > max[1])
469         max[1] = point[1];
470 }
471 
472 
473 template <class T>
474 inline void
extendBy(const Box<Vec2<T>> & box)475 Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
476 {
477     if (box.min[0] < min[0])
478         min[0] = box.min[0];
479 
480     if (box.max[0] > max[0])
481         max[0] = box.max[0];
482 
483     if (box.min[1] < min[1])
484         min[1] = box.min[1];
485 
486     if (box.max[1] > max[1])
487         max[1] = box.max[1];
488 }
489 
490 
491 template <class T>
492 inline bool
intersects(const Vec2<T> & point)493 Box<Vec2<T> >::intersects (const Vec2<T> &point) const
494 {
495     if (point[0] < min[0] || point[0] > max[0] ||
496         point[1] < min[1] || point[1] > max[1])
497         return false;
498 
499     return true;
500 }
501 
502 
503 template <class T>
504 inline bool
intersects(const Box<Vec2<T>> & box)505 Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
506 {
507     if (box.max[0] < min[0] || box.min[0] > max[0] ||
508         box.max[1] < min[1] || box.min[1] > max[1])
509         return false;
510 
511     return true;
512 }
513 
514 
515 template <class T>
516 inline Vec2<T>
size()517 Box<Vec2<T> >::size() const
518 {
519     if (isEmpty())
520         return Vec2<T> (0);
521 
522     return max - min;
523 }
524 
525 
526 template <class T>
527 inline Vec2<T>
center()528 Box<Vec2<T> >::center() const
529 {
530     return (max + min) / 2;
531 }
532 
533 
534 template <class T>
535 inline bool
isEmpty()536 Box<Vec2<T> >::isEmpty() const
537 {
538     if (max[0] < min[0] ||
539         max[1] < min[1])
540         return true;
541 
542     return false;
543 }
544 
545 template <class T>
546 inline bool
isInfinite()547 Box<Vec2<T> > ::isInfinite() const
548 {
549     if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
550         min[1] != limits<T>::min() || max[1] != limits<T>::max())
551         return false;
552 
553     return true;
554 }
555 
556 
557 template <class T>
558 inline bool
hasVolume()559 Box<Vec2<T> >::hasVolume() const
560 {
561     if (max[0] <= min[0] ||
562         max[1] <= min[1])
563         return false;
564 
565     return true;
566 }
567 
568 
569 template <class T>
570 inline unsigned int
majorAxis()571 Box<Vec2<T> >::majorAxis() const
572 {
573     unsigned int major = 0;
574     Vec2<T>	 s     = size();
575 
576     if (s[1] > s[major])
577         major = 1;
578 
579     return major;
580 }
581 
582 
583 template <class T>
584 class Box<Vec3<T> >
585 {
586   public:
587 
588     //-------------------------
589     //  Data Members are public
590     //-------------------------
591 
592     Vec3<T>			min;
593     Vec3<T>			max;
594 
595     //-----------------------------------------------------
596     //  Constructors - an "empty" box is created by default
597     //-----------------------------------------------------
598 
599     Box();
600     Box (const Vec3<T> &point);
601     Box (const Vec3<T> &minT, const Vec3<T> &maxT);
602 
603     //--------------------
604     //  Operators:  ==, !=
605     //--------------------
606 
607     bool		operator == (const Box<Vec3<T> > &src) const;
608     bool		operator != (const Box<Vec3<T> > &src) const;
609 
610     //------------------
611     //  Box manipulation
612     //------------------
613 
614     void		makeEmpty();
615     void		extendBy (const Vec3<T> &point);
616     void		extendBy (const Box<Vec3<T> > &box);
617     void		makeInfinite ();
618 
619     //---------------------------------------------------
620     //  Query functions - these compute results each time
621     //---------------------------------------------------
622 
623     Vec3<T>		size() const;
624     Vec3<T>		center() const;
625     bool		intersects (const Vec3<T> &point) const;
626     bool		intersects (const Box<Vec3<T> > &box) const;
627 
628     unsigned int	majorAxis() const;
629 
630     //----------------
631     //  Classification
632     //----------------
633 
634     bool		isEmpty() const;
635     bool		hasVolume() const;
636     bool		isInfinite() const;
637 };
638 
639 
640 //----------------
641 //  Implementation
642 
643 
644 template <class T>
Box()645 inline Box<Vec3<T> >::Box()
646 {
647     makeEmpty();
648 }
649 
650 
651 template <class T>
Box(const Vec3<T> & point)652 inline Box<Vec3<T> >::Box (const Vec3<T> &point)
653 {
654     min = point;
655     max = point;
656 }
657 
658 
659 template <class T>
Box(const Vec3<T> & minT,const Vec3<T> & maxT)660 inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
661 {
662     min = minT;
663     max = maxT;
664 }
665 
666 
667 template <class T>
668 inline bool
669 Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
670 {
671     return (min == src.min && max == src.max);
672 }
673 
674 
675 template <class T>
676 inline bool
677 Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
678 {
679     return (min != src.min || max != src.max);
680 }
681 
682 
683 template <class T>
makeEmpty()684 inline void Box<Vec3<T> >::makeEmpty()
685 {
686     min = Vec3<T>(Vec3<T>::baseTypeMax());
687     max = Vec3<T>(Vec3<T>::baseTypeMin());
688 }
689 
690 template <class T>
makeInfinite()691 inline void Box<Vec3<T> >::makeInfinite()
692 {
693     min = Vec3<T>(Vec3<T>::baseTypeMin());
694     max = Vec3<T>(Vec3<T>::baseTypeMax());
695 }
696 
697 
698 template <class T>
699 inline void
extendBy(const Vec3<T> & point)700 Box<Vec3<T> >::extendBy (const Vec3<T> &point)
701 {
702     if (point[0] < min[0])
703         min[0] = point[0];
704 
705     if (point[0] > max[0])
706         max[0] = point[0];
707 
708     if (point[1] < min[1])
709         min[1] = point[1];
710 
711     if (point[1] > max[1])
712         max[1] = point[1];
713 
714     if (point[2] < min[2])
715         min[2] = point[2];
716 
717     if (point[2] > max[2])
718         max[2] = point[2];
719 }
720 
721 
722 template <class T>
723 inline void
extendBy(const Box<Vec3<T>> & box)724 Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box)
725 {
726     if (box.min[0] < min[0])
727         min[0] = box.min[0];
728 
729     if (box.max[0] > max[0])
730         max[0] = box.max[0];
731 
732     if (box.min[1] < min[1])
733         min[1] = box.min[1];
734 
735     if (box.max[1] > max[1])
736         max[1] = box.max[1];
737 
738     if (box.min[2] < min[2])
739         min[2] = box.min[2];
740 
741     if (box.max[2] > max[2])
742         max[2] = box.max[2];
743 }
744 
745 
746 template <class T>
747 inline bool
intersects(const Vec3<T> & point)748 Box<Vec3<T> >::intersects (const Vec3<T> &point) const
749 {
750     if (point[0] < min[0] || point[0] > max[0] ||
751         point[1] < min[1] || point[1] > max[1] ||
752         point[2] < min[2] || point[2] > max[2])
753         return false;
754 
755     return true;
756 }
757 
758 
759 template <class T>
760 inline bool
intersects(const Box<Vec3<T>> & box)761 Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
762 {
763     if (box.max[0] < min[0] || box.min[0] > max[0] ||
764         box.max[1] < min[1] || box.min[1] > max[1] ||
765         box.max[2] < min[2] || box.min[2] > max[2])
766         return false;
767 
768     return true;
769 }
770 
771 
772 template <class T>
773 inline Vec3<T>
size()774 Box<Vec3<T> >::size() const
775 {
776     if (isEmpty())
777         return Vec3<T> (0);
778 
779     return max - min;
780 }
781 
782 
783 template <class T>
784 inline Vec3<T>
center()785 Box<Vec3<T> >::center() const
786 {
787     return (max + min) / 2;
788 }
789 
790 
791 template <class T>
792 inline bool
isEmpty()793 Box<Vec3<T> >::isEmpty() const
794 {
795     if (max[0] < min[0] ||
796         max[1] < min[1] ||
797         max[2] < min[2])
798         return true;
799 
800     return false;
801 }
802 
803 template <class T>
804 inline bool
isInfinite()805 Box<Vec3<T> >::isInfinite() const
806 {
807     if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
808         min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
809         min[2] != limits<T>::min() || max[2] != limits<T>::max())
810         return false;
811 
812     return true;
813 }
814 
815 
816 template <class T>
817 inline bool
hasVolume()818 Box<Vec3<T> >::hasVolume() const
819 {
820     if (max[0] <= min[0] ||
821         max[1] <= min[1] ||
822         max[2] <= min[2])
823         return false;
824 
825     return true;
826 }
827 
828 
829 template <class T>
830 inline unsigned int
majorAxis()831 Box<Vec3<T> >::majorAxis() const
832 {
833     unsigned int major = 0;
834     Vec3<T>	 s     = size();
835 
836     if (s[1] > s[major])
837         major = 1;
838 
839     if (s[2] > s[major])
840         major = 2;
841 
842     return major;
843 }
844 
845 
846 
847 
848 } // namespace Imath
849 
850 #endif
851