vmmlib  1.9.0
Templatized C++ vector and matrix math library
aabb.hpp
1 /*
2  * Copyright (c) 2006-2014, Visualization and Multimedia Lab,
3  * University of Zurich <http://vmml.ifi.uzh.ch>,
4  * Eyescale Software GmbH,
5  * Blue Brain Project, EPFL
6  *
7  * This file is part of VMMLib <https://github.com/VMML/vmmlib/>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * Redistributions of source code must retain the above copyright notice, this
13  * list of conditions and the following disclaimer. Redistributions in binary
14  * form must reproduce the above copyright notice, this list of conditions and
15  * the following disclaimer in the documentation and/or other materials provided
16  * with the distribution. Neither the name of the Visualization and Multimedia
17  * Lab, University of Zurich nor the names of its contributors may be used to
18  * endorse or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #ifndef __VMML__AXIS_ALIGNED_BOUNDING_BOX__HPP__
33 #define __VMML__AXIS_ALIGNED_BOUNDING_BOX__HPP__
34 
35 #include <vmmlib/vector.hpp>
36 #include <limits>
37 
38 namespace vmml
39 {
48 template< typename T > class AABB
49 {
50 public:
52  AABB();
53  AABB( const vector< 3, T >& pMin,
54  const vector< 3, T >& pMax );
55  AABB( const vector< 4, T >& sphere );
56  AABB( T cx, T cy, T cz, T size );
57 
58  bool isIn( const vector< 3, T >& pos );
59  bool isIn2d( const vector< 3, T >& pos ); // only x and y components are checked
60  bool isIn( const vector< 4, T >& sphere );
61 
62  void set( const vector< 3, T >& pMin, const vector< 3, T >& pMax );
63  void set( T cx, T cy, T cz, T size );
64  void setMin( const vector< 3, T >& pMin );
65  void setMax( const vector< 3, T >& pMax );
66 
67  const vector< 3, T >& getMin() const;
68  const vector< 3, T >& getMax() const;
69  vector< 3, T >& getMin();
70  vector< 3, T >& getMax();
71 
72  void merge( const AABB< T >& aabb );
73  void merge( const vector< 3, T >& point );
74 
75  void setEmpty();
76  bool isEmpty() const;
77 
78  AABB operator*( const T value ) const;
79  AABB operator/( const T value ) const;
80  AABB operator+( const T value ) const;
81  AABB operator-( const T value ) const;
82 
83  void operator*=( const T value );
84  void operator/=( const T value );
85  void operator+=( const T value );
86  void operator-=( const T value );
87 
88  template< class U >
89  bool operator==( const AABB< U >& other ) const;
90  template< class U >
91  bool operator!=( const AABB< U >& other ) const;
92 
93  vector< 3, T > getCenter() const;
94  vector< 3, T > getDimension() const;
95 
96  static AABB< T > makeUnitBox();
97 
98 protected:
99  vector< 3, T > _min;
100  vector< 3, T > _max;
101 };
102 
103 #ifndef VMMLIB_NO_TYPEDEFS
104 typedef AABB< float > AABBf;
105 typedef AABB< double > AABBd;
106 #endif
107 
108 template< typename T >
109 inline std::ostream& operator << ( std::ostream& os,
110  const AABB< T >& aabb )
111 {
112  return os << aabb.getMin() << " - " << aabb.getMax();
113 }
114 
115 template< typename T > AABB< T >::AABB()
116  : _min( std::numeric_limits< T >::max( ))
117  , _max( std::numeric_limits< T >::min( ))
118 {}
119 
120 template<> inline AABB< float >::AABB()
121  : _min( std::numeric_limits< float >::max( ))
122  , _max( -std::numeric_limits< float >::max( ))
123 {}
124 
125 template<> inline AABB< double >::AABB()
126  : _min( std::numeric_limits< double >::max( ))
127  , _max( -std::numeric_limits< double >::max( ))
128 {}
129 
130 template< typename T >
131 AABB< T >::AABB( const vector< 3, T >& pMin,
132  const vector< 3, T >& pMax)
133  : _min( pMin )
134  , _max( pMax )
135 {}
136 
137 template< typename T >
138 AABB< T >::AABB( const vector< 4, T >& sphere )
139 {
140  _max = _min = sphere.getCenter();
141  _max += sphere.getRadius();
142  _min -= sphere.getRadius();
143 }
144 
145 template< typename T >
146 AABB< T >::AABB( T cx, T cy, T cz, T size )
147 {
148  _max = _min = vector< 3, T >( cx, cy, cz );
149  _max += size;
150  _min -= size;
151 }
152 
153 template< typename T >
154 inline bool AABB< T >::isIn( const vector< 4, T >& sphere )
155 {
156  vector< 3, T > sv ( sphere.getCenter() );
157  sv += sphere.getRadius();
158  if ( sv.x() > _max.x() || sv.y() > _max.y() || sv.z() > _max.z() )
159  return false;
160  sv -= sphere.getRadius() * 2.0f;
161  if ( sv.x() < _min.x() || sv.y() < _min.y() || sv.z() < _min.z() )
162  return false;
163  return true;
164 }
165 
166 template< typename T >
167 inline bool AABB< T >::isIn( const vector< 3, T >& pos )
168 {
169  if ( pos.x() > _max.x() || pos.y() > _max.y() || pos.z() > _max.z() ||
170  pos.x() < _min.x() || pos.y() < _min.y() || pos.z() < _min.z( ))
171  {
172  return false;
173  }
174  return true;
175 }
176 
177 template< typename T >
178 inline bool AABB< T >::isIn2d( const vector< 3, T >& pos )
179 {
180  if ( pos.x() > _max.x() || pos.y() > _max.y() || pos.x() < _min.x() ||
181  pos.y() < _min.y( ))
182  {
183  return false;
184  }
185  return true;
186 }
187 
188 template< typename T >
189 inline void AABB< T >::set( const vector< 3, T >& pMin,
190  const vector< 3, T >& pMax )
191 {
192  _min = pMin;
193  _max = pMax;
194 }
195 
196 template< typename T >
197 inline void AABB< T >::set( T cx, T cy, T cz, T size )
198 {
199  vector< 3, T > center( cx, cy, cz );
200  _min = center - size;
201  _max = center + size;
202 }
203 
204 template< typename T >
205 inline void AABB< T >::setMin( const vector< 3, T >& pMin )
206 {
207  _min = pMin;
208 }
209 
210 template< typename T >
211 inline void AABB< T >::setMax( const vector< 3, T >& pMax )
212 {
213  _max = pMax;
214 }
215 
216 template< typename T >
217 inline const vector< 3, T >& AABB< T >::getMin() const
218 {
219  return _min;
220 }
221 
222 template< typename T >
223 inline const vector< 3, T >& AABB< T >::getMax() const
224 {
225  return _max;
226 }
227 
228 template< typename T > inline vector< 3, T >& AABB< T >::getMin()
229 {
230  return _min;
231 }
232 
233 template< typename T > inline vector< 3, T >& AABB< T >::getMax()
234 {
235  return _max;
236 }
237 
238 template< typename T > AABB< T >
239 AABB< T >::operator*( const T value ) const
240 {
241  AABB result = *this;
242  result *= value;
243  return result;
244 }
245 
246 template< typename T > AABB< T >
247 AABB< T >::operator/( const T value ) const
248 {
249  AABB result = *this;
250  result /= value;
251  return result;
252 }
253 
254 template< typename T > AABB< T >
255 AABB< T >::operator+( const T value ) const
256 {
257  AABB result = *this;
258  result += value;
259  return result;
260 }
261 
262 template< typename T > AABB< T >
263 AABB< T >::operator-( const T value ) const
264 {
265  AABB result = *this;
266  result -= value;
267  return result;
268 }
269 
270 template< typename T >
271 void AABB< T >::operator*=( const T value )
272 {
273  _min *= value;
274  _max *= value;
275 }
276 
277 template< typename T >
278 void AABB< T >::operator/=( const T value )
279 {
280  _min /= value;
281  _max /= value;
282 }
283 
284 template< typename T >
285 void AABB< T >::operator+=( const T value )
286 {
287  _min += value;
288  _max += value;
289 }
290 
291 template< typename T >
292 void AABB< T >::operator-=( const T value )
293 {
294  _min -= value;
295  _max -= value;
296 }
297 
298 template< typename T > template< class U > bool
299 AABB< T >::operator==( const AABB< U >& other )
300  const
301 {
302  return _min == other._min && _max == other._max;
303 }
304 
305 template< typename T > template< class U > bool
306 AABB< T >::operator!=( const AABB< U >& other )
307  const
308 {
309  return _min != other._min || _max != other._max;
310 }
311 
312 template< typename T >
313 vector< 3, T > AABB< T >::getCenter() const
314 {
315  return _min + ( ( _max - _min ) * 0.5f );
316 }
317 
318 template< typename T >
319 vector< 3, T > AABB< T >::getDimension() const
320 {
321  return _max - _min;
322 }
323 
324 template< typename T >
325 void AABB< T >::merge( const AABB<T>& aabb )
326 {
327  const vector< 3, T >& min = aabb.getMin();
328  const vector< 3, T >& max = aabb.getMax();
329 
330  if ( min.x() < _min.x() )
331  _min.x() = min.x();
332  if ( min.y() < _min.y() )
333  _min.y() = min.y();
334  if ( min.z() < _min.z() )
335  _min.z() = min.z();
336 
337  if ( max.x() > _max.x() )
338  _max.x() = max.x();
339  if ( max.y() > _max.y() )
340  _max.y() = max.y();
341  if ( max.z() > _max.z() )
342  _max.z() = max.z();
343 }
344 
345 template< typename T >
346 void AABB< T >::merge( const vector< 3, T >& point )
347 {
348  if ( point.x() < _min.x() )
349  _min.x() = point.x();
350  if ( point.y() < _min.y() )
351  _min.y() = point.y();
352  if ( point.z() < _min.z() )
353  _min.z() = point.z();
354 
355  if ( point.x() > _max.x() )
356  _max.x() = point.x();
357  if ( point.y() > _max.y() )
358  _max.y() = point.y();
359  if ( point.z() > _max.z() )
360  _max.z() = point.z();
361 }
362 
363 template< typename T >inline
364 void AABB< T >::setEmpty()
365 {
366  _min = std::numeric_limits< T >::max();
367  _max = -std::numeric_limits< T >::max();
368 }
369 
370 
371 template< typename T > inline bool AABB< T >::isEmpty() const
372 {
373  return ( _min.x() >= _max.x() || _min.y() >= _max.y() ||
374  _min.z() >= _max.x( ));
375 }
376 
377 template< typename T >
378 AABB< T > AABB< T >::makeUnitBox()
379 {
380  return AABB( vector< 3, T >::ZERO, vector< 3, T >::ONE );
381 }
382 
383 }; //namespace vmml
384 
385 #endif
STL namespace.
heavily inspired by boost::enable_if http://www.boost.org, file: boost/utility/enable_if.hpp, Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine
Definition: aabb.hpp:38
AABB()
Create an empty bounding box.
Definition: aabb.hpp:115
An axis-aligned bounding box.
Definition: aabb.hpp:48