vmmlib  1.11.0
Templatized C++ vector and matrix math library
aabb.hpp
1 /*
2  * Copyright (c) 2006-2016, 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 lunchbox { template< class T > void byteswap( T& ); }
39 
40 namespace vmml
41 {
50 template< typename T > class AABB
51 {
52 public:
54  AABB();
55 
57  AABB( const vector< 3, T >& pMin, const vector< 3, T >& pMax );
58 
60  AABB( const vector< 4, T >& sphere );
61 
63  bool isIn( const vector< 3, T >& point ) const;
64 
66  bool isIn( const vector< 4, T >& sphere ) const;
67 
69  const vector< 3, T >& getMin() const;
70 
72  const vector< 3, T >& getMax() const;
73 
75  void merge( const AABB< T >& aabb );
76 
78  void merge( const vector< 3, T >& point );
79 
81  void reset();
82 
84  bool isEmpty() const;
85 
87  bool operator==( const AABB< T >& other ) const;
88 
90  bool operator!=( const AABB< T >& other ) const;
91 
93  vector< 3, T > getCenter() const;
94 
96  vector< 3, T > getSize() const;
97 
102  void computeNearFar( const vector< 4, T >& plane, vector< 3, T >& nearPoint,
103  vector< 3, T >& farPoint ) const;
104 
106  static AABB< T > makeUnitBox();
107 
108 private:
109  vector< 3, T > _min;
110  vector< 3, T > _max;
111  template< class U > friend void lunchbox::byteswap( U& );
112 };
113 
114 template< typename T > inline
115 std::ostream& operator << ( std::ostream& os, const AABB< T >& aabb )
116 {
117  return os << aabb.getMin() << " - " << aabb.getMax();
118 }
119 
120 template< typename T > AABB< T >::AABB()
121  : _min( std::numeric_limits< T >::max( ))
122  , _max( std::numeric_limits< T >::min( ))
123 {}
124 
125 template<> inline AABB< float >::AABB()
126  : _min( std::numeric_limits< float >::max( ))
127  , _max( -std::numeric_limits< float >::max( ))
128 {}
129 
130 template<> inline AABB< double >::AABB()
131  : _min( std::numeric_limits< double >::max( ))
132  , _max( -std::numeric_limits< double >::max( ))
133 {}
134 
135 template< typename T >
137  : _min( vector< 3, T >( std::min( pMin[0], pMax[0] ),
138  std::min( pMin[1], pMax[1] ),
139  std::min( pMin[2], pMax[2] )))
140  , _max( vector< 3, T >( std::max( pMin[0], pMax[0] ),
141  std::max( pMin[1], pMax[1] ),
142  std::max( pMin[2], pMax[2] )))
143 {}
144 
145 template< typename T > AABB< T >::AABB( const vector< 4, T >& sphere )
146 {
147  _max = _min = sphere.getCenter();
148  _max += sphere.getRadius();
149  _min -= sphere.getRadius();
150 }
151 
152 template< typename T > inline bool AABB< T >::isIn( const vector< 3, T >& pos ) const
153 {
154  if ( pos.x() > _max.x() || pos.y() > _max.y() || pos.z() > _max.z() ||
155  pos.x() < _min.x() || pos.y() < _min.y() || pos.z() < _min.z( ))
156  {
157  return false;
158  }
159  return true;
160 }
161 
162 template< typename T > inline
163 bool AABB< T >::isIn( const vector< 4, T >& sphere ) const
164 {
165  const vector< 3, T >& sv = sphere.getCenter();
166  sv += sphere.getRadius();
167  if ( sv.x() > _max.x() || sv.y() > _max.y() || sv.z() > _max.z() )
168  return false;
169  sv -= sphere.getRadius() * 2.0f;
170  if ( sv.x() < _min.x() || sv.y() < _min.y() || sv.z() < _min.z() )
171  return false;
172  return true;
173 }
174 
175 template< typename T > inline const vector< 3, T >& AABB< T >::getMin() const
176 {
177  return _min;
178 }
179 
180 template< typename T > inline const vector< 3, T >& AABB< T >::getMax() const
181 {
182  return _max;
183 }
184 
185 template< typename T > inline
186 bool AABB< T >::operator==( const AABB< T >& other ) const
187 {
188  return _min == other._min && _max == other._max;
189 }
190 
191 template< typename T > inline
192 bool AABB< T >::operator!=( const AABB< T >& other ) const
193 {
194  return _min != other._min || _max != other._max;
195 }
196 
197 template< typename T > vector< 3, T > AABB< T >::getCenter() const
198 {
199  return ( _min + _max ) * 0.5f;
200 }
201 
202 template< typename T > vector< 3, T > AABB< T >::getSize() const
203 {
204  return _max - _min;
205 }
206 
207 template< typename T >
208 void AABB< T >::merge( const AABB<T>& aabb )
209 {
210  const vector< 3, T >& min = aabb.getMin();
211  const vector< 3, T >& max = aabb.getMax();
212 
213  if ( min.x() < _min.x() )
214  _min.x() = min.x();
215  if ( min.y() < _min.y() )
216  _min.y() = min.y();
217  if ( min.z() < _min.z() )
218  _min.z() = min.z();
219 
220  if ( max.x() > _max.x() )
221  _max.x() = max.x();
222  if ( max.y() > _max.y() )
223  _max.y() = max.y();
224  if ( max.z() > _max.z() )
225  _max.z() = max.z();
226 }
227 
228 template< typename T >
229 void AABB< T >::merge( const vector< 3, T >& point )
230 {
231  if ( point.x() < _min.x() )
232  _min.x() = point.x();
233  if ( point.y() < _min.y() )
234  _min.y() = point.y();
235  if ( point.z() < _min.z() )
236  _min.z() = point.z();
237 
238  if ( point.x() > _max.x() )
239  _max.x() = point.x();
240  if ( point.y() > _max.y() )
241  _max.y() = point.y();
242  if ( point.z() > _max.z() )
243  _max.z() = point.z();
244 }
245 
246 template< typename T > inline void AABB< T >::reset()
247 {
248  _min = std::numeric_limits< T >::max();
249  _max = -std::numeric_limits< T >::max();
250 }
251 
252 template< typename T > inline bool AABB< T >::isEmpty() const
253 {
254  return _min.x() >= _max.x() || _min.y() >= _max.y() || _min.z() >= _max.x();
255 }
256 
257 template< typename T > inline void
259  vector< 3, T >& farPoint ) const
260 {
261  for( size_t i = 0; i < 3; ++i )
262  {
263  if( plane[ i ] >= 0.0 )
264  {
265  nearPoint[ i ] = _min[ i ];
266  farPoint[ i ] = _max[ i ];
267  }
268  else
269  {
270  nearPoint[ i ] = _max[ i ];
271  farPoint[ i ] = _min[ i ];
272  }
273  }
274 }
275 
276 template< typename T > AABB< T > AABB< T >::makeUnitBox()
277 {
279 }
280 
281 }
282 
283 #endif
bool isIn(const vector< 3, T > &point) const
Definition: aabb.hpp:152
vector< 3, T > getSize() const
Definition: aabb.hpp:202
STL namespace.
void computeNearFar(const vector< 4, T > &plane, vector< 3, T > &nearPoint, vector< 3, T > &farPoint) const
Compute the nearest and furthest point of this box relative to the given plane.
Definition: aabb.hpp:258
static AABB< T > makeUnitBox()
Definition: aabb.hpp:276
bool operator!=(const AABB< T > &other) const
Definition: aabb.hpp:192
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:40
AABB()
Create an empty bounding box.
Definition: aabb.hpp:120
An axis-aligned bounding box.
Definition: aabb.hpp:50
const vector< 3, T > & getMin() const
Definition: aabb.hpp:175
bool operator==(const AABB< T > &other) const
Definition: aabb.hpp:186
bool isEmpty() const
Definition: aabb.hpp:252
void reset()
Clear this bounding box.
Definition: aabb.hpp:246
vector< 3, T > getCenter() const
Definition: aabb.hpp:197
const vector< 3, T > & getMax() const
Definition: aabb.hpp:180
void merge(const AABB< T > &aabb)
Create the union of this and the given bounding box.
Definition: aabb.hpp:208