CCollisionAABBBox.h
Go to the documentation of this file.
1 //==============================================================================
2 /*
3  Software License Agreement (BSD License)
4  Copyright (c) 2003-2016, CHAI3D.
5  (www.chai3d.org)
6 
7  All rights reserved.
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions
11  are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above
17  copyright notice, this list of conditions and the following
18  disclaimer in the documentation and/or other materials provided
19  with the distribution.
20 
21  * Neither the name of CHAI3D nor the names of its contributors may
22  be used to endorse or promote products derived from this software
23  without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  POSSIBILITY OF SUCH DAMAGE.
37 
38  \author <http://www.chai3d.org>
39  \author Chris Sewell
40  \author Charity Lu
41  \author Francois Conti
42  \version 3.2.0 $Rev: 1869 $
43 */
44 //==============================================================================
45 
46 //------------------------------------------------------------------------------
47 #ifndef CCollisionAABBBoxH
48 #define CCollisionAABBBoxH
49 //------------------------------------------------------------------------------
50 #include "graphics/CGenericArray.h"
51 #include "graphics/CDraw3D.h"
52 #include "math/CMaths.h"
53 //------------------------------------------------------------------------------
54 #include <vector>
55 //------------------------------------------------------------------------------
56 
57 //------------------------------------------------------------------------------
58 namespace chai3d {
59 //------------------------------------------------------------------------------
60 
61 //==============================================================================
68 //==============================================================================
69 
70 //==============================================================================
83 //==============================================================================
85 {
86  //--------------------------------------------------------------------------
87  // CONSTRUCTOR & DESTRUCTOR:
88  //--------------------------------------------------------------------------
89 
90 public:
91 
94 
97  const cVector3d& a_max)
98  {
99  setValue(a_min, a_max);
100  }
101 
103  virtual ~cCollisionAABBBox() {};
104 
105 
106  //--------------------------------------------------------------------------
107  // METHODS:
108  //--------------------------------------------------------------------------
109 
110 public:
111 
112  //--------------------------------------------------------------------------
122  //--------------------------------------------------------------------------
123  inline cVector3d getCenter() const
124  {
125  return (m_center);
126  }
127 
128 
129  //--------------------------------------------------------------------------
139  //--------------------------------------------------------------------------
140  inline cVector3d getExtent() const
141  {
142  return (m_extent);
143  }
144 
145 
146  //--------------------------------------------------------------------------
156  //--------------------------------------------------------------------------
157  inline void setCenter(const cVector3d& a_center)
158  {
159  m_center = a_center;
160  }
161 
162 
163  //--------------------------------------------------------------------------
173  //--------------------------------------------------------------------------
174  inline void setExtent(const cVector3d& a_extent)
175  {
176  m_extent = a_extent;
177  }
178 
179 
180  //--------------------------------------------------------------------------
193  //--------------------------------------------------------------------------
194  inline void setValue(const cVector3d& a_min, const cVector3d& a_max)
195  {
196  m_extent = cMul(0.5, cSub(a_max, a_min));
197  m_center = cAdd(a_min, m_extent);
198  m_min = a_min;
199  m_max = a_max;
200  }
201 
202 
203  //--------------------------------------------------------------------------
217  //--------------------------------------------------------------------------
218  inline bool intersect(const cCollisionAABBBox& a_box) const
219  {
220  // check for overlap along each axis
221  if (a_box.getLowerX() > getUpperX()) return (false);
222  if (a_box.getLowerY() > getUpperY()) return (false);
223  if (a_box.getLowerZ() > getUpperZ()) return (false);
224  if (a_box.getUpperX() < getLowerX()) return (false);
225  if (a_box.getUpperY() < getLowerY()) return (false);
226  if (a_box.getUpperZ() < getLowerZ()) return (false);
227 
228  // if the boxes are not separated along any axis, a collision has occurred
229  return (true);
230  }
231 
232 
233  //--------------------------------------------------------------------------
247  //--------------------------------------------------------------------------
248  inline bool intersect(const cVector3d& a_segmentPointA, const cVector3d& a_segmentPointB) const
249  {
250  const int RIGHT = 0;
251  const int LEFT = 1;
252  const int MIDDLE = 2;
253 
254  double coord[3];
255  char inside = true;
256  char quadrant[3];
257  int i;
258  int whichPlane;
259  double maxT[3];
260  double candidatePlane[3];
261  double dir[3];
262  dir[0] = a_segmentPointB(0) - a_segmentPointA(0);
263  dir[1] = a_segmentPointB(1) - a_segmentPointA(1);
264  dir[2] = a_segmentPointB(2) - a_segmentPointA(2);
265 
266  // find candidate planes; this loop can be avoided if rays cast all from
267  // the eye (assume perspective view)
268  for (i=0; i<3; i++)
269  {
270  if(a_segmentPointA(i) < m_min(i))
271  {
272  quadrant[i] = LEFT;
273  candidatePlane[i] = m_min(i);
274  inside = false;
275  }
276  else if (a_segmentPointA(i) > m_max(i))
277  {
278  quadrant[i] = RIGHT;
279  candidatePlane[i] = m_max(i);
280  inside = false;
281  }
282  else
283  {
284  quadrant[i] = MIDDLE;
285  }
286  }
287 
288  // ray origin inside boundary box
289  if (inside)
290  {
291  return (true);
292  }
293 
294  // calculate T distances to candidate planes
295  for (i=0; i<3; i++)
296  {
297  if (quadrant[i] != MIDDLE && dir[i] !=0.)
298  maxT[i] = (candidatePlane[i]-a_segmentPointA(i)) / dir[i];
299  else
300  maxT[i] = -1.;
301  }
302 
303  // get largest of the maxT's for final choice of intersection
304  whichPlane = 0;
305  for (i=1; i<3; i++)
306  if (maxT[whichPlane] < maxT[i])
307  whichPlane = i;
308 
309  // check final candidate actually inside box
310  if (maxT[whichPlane] < 0.)
311  {
312  return (false);
313  }
314 
315  for (i=0; i<3; i++)
316  {
317  if (whichPlane != i)
318  {
319  coord[i] = a_segmentPointA(i) + maxT[whichPlane] * dir[i];
320  if (coord[i] < m_min(i) || coord[i] > m_max(i))
321  {
322  return (false);
323  }
324  }
325  else
326  {
327  coord[i] = candidatePlane[i];
328  }
329  }
330 
331  // ray hits box
332  return (true);
333  }
334 
335 
336  //--------------------------------------------------------------------------
349  //--------------------------------------------------------------------------
350  inline bool contains(const cVector3d& a_point) const
351  {
352  // check that each of the point's coordinates are within the box's range
353  if ((a_point(0) > m_min(0)) && (a_point(1) > m_min(1)) && (a_point(2) > m_min(2)) &&
354  (a_point(0) < m_max(0)) && (a_point(1) < m_max(1)) && (a_point(2) < m_max(2)))
355  {
356  return (true);
357  }
358  else
359  {
360  return (false);
361  }
362  }
363 
364 
365  //--------------------------------------------------------------------------
378  //--------------------------------------------------------------------------
379  inline void enclose(const cCollisionAABBBox& a_boxA,
380  const cCollisionAABBBox& a_boxB)
381  {
382  // find the minimum coordinate along each axis
383  cVector3d lower(cMin(a_boxA.getLowerX(), a_boxB.getLowerX()),
384  cMin(a_boxA.getLowerY(), a_boxB.getLowerY()),
385  cMin(a_boxA.getLowerZ(), a_boxB.getLowerZ()));
386 
387  // find the maximum coordinate along each axis
388  cVector3d upper(cMax(a_boxA.getUpperX(), a_boxB.getUpperX()),
389  cMax(a_boxA.getUpperY(), a_boxB.getUpperY()),
390  cMax(a_boxA.getUpperZ(), a_boxB.getUpperZ()));
391 
392  // set the center and extent of this box to enclose the two extreme points
393  setValue(lower, upper);
394  }
395 
396 
397  //--------------------------------------------------------------------------
409  //--------------------------------------------------------------------------
410  inline void enclose (const cVector3d& a_point)
411  {
412  // decrease coordinates as needed to include given point
413  cVector3d lower(cMin(getLowerX(), a_point(0) ),
414  cMin(getLowerY(), a_point(1) ),
415  cMin(getLowerZ(), a_point(2)));
416 
417  // increase coordinates as needed to include given point
418  cVector3d upper(cMax(getUpperX(), a_point(0) ),
419  cMax(getUpperY(), a_point(1) ),
420  cMax(getUpperZ(), a_point(2)));
421 
422  // set the center and extent of this box to enclose the given point
423  setValue(lower, upper);
424  }
425 
426 
427  //--------------------------------------------------------------------------
437  //--------------------------------------------------------------------------
438  inline void enclose(const cCollisionAABBBox& a_box)
439  {
440  enclose(*this, a_box);
441  }
442 
443 
444  //--------------------------------------------------------------------------
452  //--------------------------------------------------------------------------
453  inline void setEmpty()
454  {
455  const double C_INFINITY = 1.0e50;
456  m_center.zero();
457  m_extent = cVector3d(-C_INFINITY,-C_INFINITY,-C_INFINITY);
458  m_min.set( C_INFINITY, C_INFINITY, C_INFINITY);
459  m_max.set(-C_INFINITY,-C_INFINITY,-C_INFINITY);
460  }
461 
462 
463  //--------------------------------------------------------------------------
473  //--------------------------------------------------------------------------
474  inline double getLowerX() const
475  {
476  return (m_min(0) );
477  }
478 
479 
480  //--------------------------------------------------------------------------
490  //--------------------------------------------------------------------------
491  inline double getUpperX() const
492  {
493  return (m_max(0) );
494  }
495 
496 
497  //--------------------------------------------------------------------------
507  //--------------------------------------------------------------------------
508  inline double getLowerY() const
509  {
510  return (m_min(1) );
511  }
512 
513 
514  //--------------------------------------------------------------------------
524  //--------------------------------------------------------------------------
525  inline double getUpperY() const
526  {
527  return (m_max(1) );
528  }
529 
530 
531  //--------------------------------------------------------------------------
541  //--------------------------------------------------------------------------
542  inline double getLowerZ() const
543  {
544  return (m_min(2));
545  }
546 
547 
548  //--------------------------------------------------------------------------
558  //--------------------------------------------------------------------------
559  inline double getUpperZ() const
560  {
561  return (m_max(2));
562  }
563 
564 
565  //--------------------------------------------------------------------------
575  //--------------------------------------------------------------------------
576  inline int getLongestAxis() const
577  {
578  // if extent of x axis is greatest, return index 0
579  if ((m_extent(0) >= m_extent(1)) && (m_extent(0) >= m_extent(2)))
580  {
581  return (0);
582  }
583  else if ((m_extent(1) >= m_extent(0)) && (m_extent(1) >= m_extent(2)))
584  {
585  return (1);
586  }
587  else
588  {
589  return (2);
590  }
591  }
592 
593 
594  //--------------------------------------------------------------------------
603  //--------------------------------------------------------------------------
604  inline void render()
605  {
606  cDrawWireBox(m_min(0), m_max(0), m_min(1), m_max(1), m_min(2), m_max(2));
607  }
608 
609 
610  //--------------------------------------------------------------------------
611  // PUBLIC MEMBERS:
612  //--------------------------------------------------------------------------
613 
614 public:
615 
618 
621 
624 
627 };
628 
629 
630 //------------------------------------------------------------------------------
631 } // namespace chai3d
632 //------------------------------------------------------------------------------
633 
634 //------------------------------------------------------------------------------
635 #endif
636 //------------------------------------------------------------------------------
637 
This class implements a 3D vector.
Definition: CVector3d.h:88
void enclose(const cCollisionAABBBox &a_boxA, const cCollisionAABBBox &a_boxB)
This method initializes the boundary box to bound two given boundary boxes passed as argument...
Definition: CCollisionAABBBox.h:379
Implements general math utility functions.
double getLowerX() const
This method returns the smallest coordinate along X axis.
Definition: CCollisionAABBBox.h:474
cVector3d getCenter() const
This method returns the center of the boundary box.
Definition: CCollisionAABBBox.h:123
bool contains(const cVector3d &a_point) const
This method tests whether this box contains a point passed as argument.
Definition: CCollisionAABBBox.h:350
void zero()
This method clears all vector components with zeros.
Definition: CVector3d.h:256
double getUpperZ() const
This method return the largest coordinate along Z axis.
Definition: CCollisionAABBBox.h:559
void enclose(const cVector3d &a_point)
This method resizes the boundary box to bound a new point passed as argument.
Definition: CCollisionAABBBox.h:410
Implements an abstract class for describing elements composed of vertices.
void cDrawWireBox(const double &a_xMin, const double &a_xMax, const double &a_yMin, const double &a_yMax, const double &a_zMin, const double &a_zMax)
This function draws a box using lines.
Definition: CDraw3D.cpp:327
cVector3d cAdd(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the addition of two vectors.
Definition: CMaths.h:708
cVector3d m_center
The center of the boundary box.
Definition: CCollisionAABBBox.h:617
double getLowerZ() const
This returns the smallest coordinate along Z axis.
Definition: CCollisionAABBBox.h:542
int getLongestAxis() const
This method returns the index of the longest axis of the boundary box.
Definition: CCollisionAABBBox.h:576
cCollisionAABBBox(const cVector3d &a_min, const cVector3d &a_max)
Constructor of cCollisionAABBBox.
Definition: CCollisionAABBBox.h:96
cVector3d cSub(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the subtraction of two vectors.
Definition: CMaths.h:769
double getLowerY() const
This method returns the smallest coordinate along Y axis.
Definition: CCollisionAABBBox.h:508
void setCenter(const cVector3d &a_center)
This method sets the center of the boundary box.
Definition: CCollisionAABBBox.h:157
bool intersect(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB) const
This method determines whether the given ray intersects the boundary box.
Definition: CCollisionAABBBox.h:248
void set(const double &a_x, const double &a_y, const double &a_z)
This method initializes this vector with components x, y, and z passed as arguments.
Definition: CVector3d.h:298
double getUpperX() const
This method returns the largest coordinate along X axis.
Definition: CCollisionAABBBox.h:491
cCollisionAABBBox()
Default constructor of cCollisionAABBBox.
Definition: CCollisionAABBBox.h:93
cVector3d cMul(const double &a_value, const cVector3d &a_vector)
This function computes the multiplication of a vector by a scalar.
Definition: CMaths.h:824
void setEmpty()
This method empties this boundary box.
Definition: CCollisionAABBBox.h:453
cVector3d m_min
The minimum point (along each axis) of the boundary box.
Definition: CCollisionAABBBox.h:623
Implements OpenGL drawing macros.
virtual ~cCollisionAABBBox()
Destructor of cCollisionAABBBox.
Definition: CCollisionAABBBox.h:103
cVector3d m_max
The maximum point (along each axis) of the boundary box.
Definition: CCollisionAABBBox.h:626
cVector3d getExtent() const
This method returns the extent (half the width) of the boundary box.
Definition: CCollisionAABBBox.h:140
T cMin(const T &a_value1, const T &a_value2)
This function computes the minimum value between two values.
Definition: CMaths.h:242
This structure implements the boundary nodes of an axis-aligned bounding box.
Definition: CCollisionAABBBox.h:84
cVector3d m_extent
The extent (half the width) of the boundary box.
Definition: CCollisionAABBBox.h:620
double getUpperY() const
This method returns the largest coordinate along Y axis.
Definition: CCollisionAABBBox.h:525
Definition: CAudioBuffer.cpp:56
bool intersect(const cCollisionAABBBox &a_box) const
This method determines whether this box and an input box passed as argument intersect each other...
Definition: CCollisionAABBBox.h:218
void setValue(const cVector3d &a_min, const cVector3d &a_max)
This method initializes the boundary box by passing a minimum and maximum point.
Definition: CCollisionAABBBox.h:194
void setExtent(const cVector3d &a_extent)
This method sets the extent (half the width) of the boundary box.
Definition: CCollisionAABBBox.h:174
void enclose(const cCollisionAABBBox &a_box)
This method resizes the boundary box to bound a new point passed as argument.
Definition: CCollisionAABBBox.h:438
void render()
This method renders graphically the edges of the boundary box.
Definition: CCollisionAABBBox.h:604
T cMax(const T &a_value1, const T &a_value2)
This function computes the maximum value between two values.
Definition: CMaths.h:220