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 67namespace Imath { 68 69 70template <class T> 71class 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 105 //--------------------------------------------------- 106 // Query functions - these compute results each time 107 //--------------------------------------------------- 108 109 T size() const; 110 T center() const; 111 bool intersects(const T &point) const; 112 bool intersects(const Box<T> &box) const; 113 114 unsigned int majorAxis() const; 115 116 //---------------- 117 // Classification 118 //---------------- 119 120 bool isEmpty() const; 121 bool hasVolume() const; 122}; 123 124 125//-------------------- 126// Convenient typedefs 127//-------------------- 128 129 130typedef Box <V2s> Box2s; 131typedef Box <V2i> Box2i; 132typedef Box <V2f> Box2f; 133typedef Box <V2d> Box2d; 134typedef Box <V3s> Box3s; 135typedef Box <V3i> Box3i; 136typedef Box <V3f> Box3f; 137typedef Box <V3d> Box3d; 138 139 140//---------------- 141// Implementation 142//---------------- 143 144 145template <class T> 146inline Box<T>::Box() 147{ 148 makeEmpty(); 149} 150 151template <class T> 152inline Box<T>::Box(const T& point) 153{ 154 min = point; 155 max = point; 156} 157 158template <class T> 159inline Box<T>::Box(const T& minV, const T& maxV) 160{ 161 min = minV; 162 max = maxV; 163} 164 165template <class T> 166inline bool 167Box<T>::operator == (const Box<T> &src) const 168{ 169 return (min == src.min && max == src.max); 170} 171 172template <class T> 173inline bool 174Box<T>::operator != (const Box<T> &src) const 175{ 176 return (min != src.min || max != src.max); 177} 178 179template <class T> 180inline void Box<T>::makeEmpty() 181{ 182 min = T(T::baseTypeMax()); 183 max = T(T::baseTypeMin()); 184} 185 186template <class T> 187inline void Box<T>::extendBy(const T& point) 188{ 189 for (unsigned int i=0; i<min.dimensions(); i++) 190 { 191 if ( point[i] < min[i] ) min[i] = point[i]; 192 if ( point[i] > max[i] ) max[i] = point[i]; 193 } 194} 195 196template <class T> 197inline void Box<T>::extendBy(const Box<T>& box) 198{ 199 for (unsigned int i=0; i<min.dimensions(); i++) 200 { 201 if ( box.min[i] < min[i] ) min[i] = box.min[i]; 202 if ( box.max[i] > max[i] ) max[i] = box.max[i]; 203 } 204} 205 206template <class T> 207inline bool Box<T>::intersects(const T& point) const 208{ 209 for (unsigned int i=0; i<min.dimensions(); i++) 210 { 211 if (point[i] < min[i] || point[i] > max[i]) return false; 212 } 213 return true; 214} 215 216template <class T> 217inline bool Box<T>::intersects(const Box<T>& box) const 218{ 219 for (unsigned int i=0; i<min.dimensions(); i++) 220 { 221 if (box.max[i] < min[i] || box.min[i] > max[i]) return false; 222 } 223 return true; 224} 225 226template <class T> 227inline T Box<T>::size() const 228{ 229 if (isEmpty()) 230 return T (0); 231 232 return max-min; 233} 234 235template <class T> 236inline T Box<T>::center() const 237{ 238 return (max+min)/2; 239} 240 241template <class T> 242inline bool Box<T>::isEmpty() const 243{ 244 for (unsigned int i=0; i<min.dimensions(); i++) 245 { 246 if (max[i] < min[i]) return true; 247 } 248 return false; 249} 250 251template <class T> 252inline bool Box<T>::hasVolume() const 253{ 254 for (unsigned int i=0; i<min.dimensions(); i++) 255 { 256 if (max[i] <= min[i]) return false; 257 } 258 return true; 259} 260 261template<class T> 262inline unsigned int Box<T>::majorAxis() const 263{ 264 unsigned int major = 0; 265 T s = size(); 266 267 for (unsigned int i=1; i<min.dimensions(); i++) 268 { 269 if ( s[i] > s[major] ) major = i; 270 } 271 272 return major; 273} 274 275} // namespace Imath 276 277#endif 278