Saga3D API Documentation  1.0-RC4
aabbox3d.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __IRR_AABBOX_3D_H_INCLUDED__
6 #define __IRR_AABBOX_3D_H_INCLUDED__
7 
8 #include "plane3d.h"
9 #include "line3d.h"
10 
11 namespace saga
12 {
13 namespace core
14 {
15 
17 
19 template <class T>
20 class aabbox3d
21 {
22  public:
23 
25  aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {}
27  aabbox3d(const glm::vec3& min, const glm::vec3& max): MinEdge(min), MaxEdge(max) {}
29  aabbox3d(const glm::vec3& init): MinEdge(init), MaxEdge(init) {}
31  aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {}
32 
33  // operators
35 
37  inline bool operator==(const aabbox3d<T>& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
39 
41  inline bool operator!=(const aabbox3d<T>& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
42 
43  // functions
44 
46 
49  void reset(T x, T y, T z)
50  {
51  MaxEdge = { x,y,z };
52  MinEdge = MaxEdge;
53  }
54 
56 
57  void reset(const aabbox3d<T>& initValue)
58  {
59  *this = initValue;
60  }
61 
63 
64  void reset(const glm::vec3& initValue)
65  {
66  MaxEdge = initValue;
67  MinEdge = initValue;
68  }
69 
71 
73  void addInternalPoint(const glm::vec3& p)
74  {
75  addInternalPoint(p.x, p.y, p.z);
76  }
77 
79 
81  void addInternalBox(const aabbox3d<T>& b)
82  {
85  }
86 
88 
92  void addInternalPoint(T x, T y, T z)
93  {
94  if (x>MaxEdge.x) MaxEdge.x = x;
95  if (y>MaxEdge.y) MaxEdge.y = y;
96  if (z>MaxEdge.z) MaxEdge.z = z;
97 
98  if (x<MinEdge.x) MinEdge.x = x;
99  if (y<MinEdge.y) MinEdge.y = y;
100  if (z<MinEdge.z) MinEdge.z = z;
101  }
102 
104 
105  glm::vec3 getCenter() const
106  {
107  return (MinEdge + MaxEdge) * 0.5f;
108  }
109 
111 
112  glm::vec3 getExtent() const
113  {
114  return MaxEdge - MinEdge;
115  }
116 
118 
119  T getRadius() const
120  {
121  const T radius = getExtent().getLength() / 2;
122  return radius;
123  }
124 
126 
128  bool isEmpty() const
129  {
130  return glm::all(glm::equal(MinEdge, MaxEdge));
131  }
132 
134  T getVolume() const
135  {
136  const glm::vec3 e = getExtent();
137  return e.x * e.y * e.z;
138  }
139 
141  T getArea() const
142  {
143  const glm::vec3 e = getExtent();
144  return 2*(e.x*e.y + e.x*e.z + e.y*e.z);
145  }
146 
148 
149  void getEdges(glm::vec3 *edges) const
150  {
151  const glm::vec3 middle = getCenter();
152  const glm::vec3 diag = middle - MaxEdge;
153 
154  /*
155  Edges are stored in this way:
156  Hey, am I an ascii artist, or what? :) niko.
157  /3--------/7
158  / | / |
159  / | / |
160  1---------5 |
161  | /2- - -|- -6
162  | / | /
163  |/ | /
164  0---------4/
165  */
166 
167  edges[0] = { middle.x + diag.x, middle.y + diag.y, middle.z + diag.z };
168  edges[1] = { middle.x + diag.x, middle.y - diag.y, middle.z + diag.z };
169  edges[2] = { middle.x + diag.x, middle.y + diag.y, middle.z - diag.z };
170  edges[3] = { middle.x + diag.x, middle.y - diag.y, middle.z - diag.z };
171  edges[4] = { middle.x - diag.x, middle.y + diag.y, middle.z + diag.z };
172  edges[5] = { middle.x - diag.x, middle.y - diag.y, middle.z + diag.z };
173  edges[6] = { middle.x - diag.x, middle.y + diag.y, middle.z - diag.z };
174  edges[7] = { middle.x - diag.x, middle.y - diag.y, middle.z - diag.z };
175  }
176 
178 
179  void repair()
180  {
181  T t;
182 
183  if (MinEdge.x > MaxEdge.x)
184  { t=MinEdge.x; MinEdge.x = MaxEdge.x; MaxEdge.x=t; }
185  if (MinEdge.y > MaxEdge.y)
186  { t=MinEdge.y; MinEdge.y = MaxEdge.y; MaxEdge.y=t; }
187  if (MinEdge.z > MaxEdge.z)
188  { t=MinEdge.z; MinEdge.z = MaxEdge.z; MaxEdge.z=t; }
189  }
190 
192 
197  aabbox3d<T> getInterpolated(const aabbox3d<T>& other, float d) const
198  {
199  float inv = 1.0f - d;
200  return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d),
201  (other.MaxEdge*inv) + (MaxEdge*d));
202  }
203 
205 
208  bool isPointInside(const glm::vec3& p) const
209  {
210  return (p.x >= MinEdge.x && p.x <= MaxEdge.x &&
211  p.y >= MinEdge.y && p.y <= MaxEdge.y &&
212  p.z >= MinEdge.z && p.z <= MaxEdge.z);
213  }
214 
216 
219  bool isPointTotalInside(const glm::vec3& p) const
220  {
221  return (p.x > MinEdge.x && p.x < MaxEdge.x &&
222  p.y > MinEdge.y && p.y < MaxEdge.y &&
223  p.z > MinEdge.z && p.z < MaxEdge.z);
224  }
225 
227 
230  bool isFullInside(const aabbox3d<T>& other) const
231  {
232  return (MinEdge.x >= other.MinEdge.x && MinEdge.y >= other.MinEdge.y && MinEdge.z >= other.MinEdge.z &&
233  MaxEdge.x <= other.MaxEdge.x && MaxEdge.y <= other.MaxEdge.y && MaxEdge.z <= other.MaxEdge.z);
234  }
235 
237  aabbox3d<T> intersect(const aabbox3d<T>& other) const
238  {
239  aabbox3d<T> out;
240 
241  if (!intersectsWithBox(other))
242  return out;
243 
244  out.MaxEdge.x = min_(MaxEdge.x, other.MaxEdge.x);
245  out.MaxEdge.y = min_(MaxEdge.y, other.MaxEdge.y);
246  out.MaxEdge.z = min_(MaxEdge.z, other.MaxEdge.z);
247 
248  out.MinEdge.x = max_(MinEdge.x, other.MinEdge.x);
249  out.MinEdge.y = max_(MinEdge.y, other.MinEdge.y);
250  out.MinEdge.z = max_(MinEdge.z, other.MinEdge.z);
251 
252  return out;
253  }
254 
256 
259  bool intersectsWithBox(const aabbox3d<T>& other) const
260  {
261  return (MinEdge.x <= other.MaxEdge.x && MinEdge.y <= other.MaxEdge.y && MinEdge.z <= other.MaxEdge.z &&
262  MaxEdge.x >= other.MinEdge.x && MaxEdge.y >= other.MinEdge.y && MaxEdge.z >= other.MinEdge.z);
263  }
264 
266 
268  bool intersectsWithLine(const line3d<T>& line) const
269  {
270  return intersectsWithLine(line.getMiddle(), line.getVector().normalize(),
271  (T)(line.getLength() * 0.5));
272  }
273 
275 
279  bool intersectsWithLine(const glm::vec3& linemiddle,
280  const glm::vec3& linevect, T halflength) const
281  {
282  const glm::vec3 e = getExtent() * (T)0.5;
283  const glm::vec3 t = getCenter() - linemiddle;
284 
285  if ((fabs(t.x) > e.x + halflength * fabs(linevect.x)) ||
286  (fabs(t.y) > e.y + halflength * fabs(linevect.y)) ||
287  (fabs(t.z) > e.z + halflength * fabs(linevect.z)))
288  return false;
289 
290  T r = e.y * (T)fabs(linevect.z) + e.z * (T)fabs(linevect.y);
291  if (fabs(t.y*linevect.z - t.z*linevect.y) > r)
292  return false;
293 
294  r = e.x * (T)fabs(linevect.z) + e.z * (T)fabs(linevect.x);
295  if (fabs(t.z*linevect.x - t.x*linevect.z) > r)
296  return false;
297 
298  r = e.x * (T)fabs(linevect.y) + e.y * (T)fabs(linevect.x);
299  if (fabs(t.x*linevect.y - t.y*linevect.x) > r)
300  return false;
301 
302  return true;
303  }
304 
306 
311  {
312  glm::vec3 nearPoint(MaxEdge);
313  glm::vec3 farPoint(MinEdge);
314 
315  if (plane.Normal.x > (T)0)
316  {
317  nearPoint.x = MinEdge.x;
318  farPoint.x = MaxEdge.x;
319  }
320 
321  if (plane.Normal.y > (T)0)
322  {
323  nearPoint.y = MinEdge.y;
324  farPoint.y = MaxEdge.y;
325  }
326 
327  if (plane.Normal.z > (T)0)
328  {
329  nearPoint.z = MinEdge.z;
330  farPoint.z = MaxEdge.z;
331  }
332 
333  if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0)
334  return ISREL3D_FRONT;
335 
336  if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0)
337  return ISREL3D_CLIPPED;
338 
339  return ISREL3D_BACK;
340  }
341 
343  glm::vec3 MinEdge;
344 
346  glm::vec3 MaxEdge;
347 };
348 
353 
354 } // namespace core
355 } // namespace saga
356 
357 #endif
358 
plane3d.h
saga::core::plane3d
Template plane class with some intersection testing methods.
Definition: plane3d.h:34
saga::core::aabbox3d::repair
void repair()
Repairs the box.
Definition: aabbox3d.h:179
saga::core::ISREL3D_FRONT
@ ISREL3D_FRONT
Definition: plane3d.h:20
saga::core::aabbox3di
aabbox3d< std::int32_t > aabbox3di
Typedef for an integer 3d bounding box.
Definition: aabbox3d.h:352
saga::core::line3d::getLength
T getLength() const
Get length of line.
Definition: line3d.h:55
saga::core::aabbox3d::intersectsWithBox
bool intersectsWithBox(const aabbox3d< T > &other) const
Determines if the axis-aligned box intersects with another axis-aligned box.
Definition: aabbox3d.h:259
saga::core::aabbox3d::getRadius
T getRadius() const
Get radius of the bounding sphere.
Definition: aabbox3d.h:119
saga::core::aabbox3d::isPointInside
bool isPointInside(const glm::vec3 &p) const
Determines if a point is within this box.
Definition: aabbox3d.h:208
saga::core::aabbox3d::classifyPlaneRelation
EIntersectionRelation3D classifyPlaneRelation(const plane3d< T > &plane) const
Classifies a relation with a plane.
Definition: aabbox3d.h:310
saga::core::aabbox3d::operator==
bool operator==(const aabbox3d< T > &other) const
Equality operator.
Definition: aabbox3d.h:37
saga::core::aabbox3d::addInternalPoint
void addInternalPoint(T x, T y, T z)
Adds a point to the bounding box.
Definition: aabbox3d.h:92
saga::core::aabbox3d::MinEdge
glm::vec3 MinEdge
The near edge.
Definition: aabbox3d.h:343
saga::core::aabbox3d::getInterpolated
aabbox3d< T > getInterpolated(const aabbox3d< T > &other, float d) const
Calculates a new interpolated bounding box.
Definition: aabbox3d.h:197
saga::core::EIntersectionRelation3D
EIntersectionRelation3D
Enumeration for intersection relations of 3d objects.
Definition: plane3d.h:18
saga::core::aabbox3d::getExtent
glm::vec3 getExtent() const
Get extent of the box (maximal distance of two points in the box)
Definition: aabbox3d.h:112
saga::core::aabbox3d::isEmpty
bool isEmpty() const
Check if the box is empty.
Definition: aabbox3d.h:128
saga::core::line3d
3D line between two points with intersection methods.
Definition: line3d.h:17
saga::core::plane3d::D
T D
Distance from origin.
Definition: plane3d.h:244
saga::core::aabbox3d::intersect
aabbox3d< T > intersect(const aabbox3d< T > &other) const
Returns the intersection of this box with another, if possible.
Definition: aabbox3d.h:237
saga::core::aabbox3df
aabbox3d< float > aabbox3df
Typedef for a float 3d bounding box.
Definition: aabbox3d.h:350
saga::core::aabbox3d::aabbox3d
aabbox3d()
Default Constructor.
Definition: aabbox3d.h:25
saga::core::aabbox3d::getArea
T getArea() const
Get the surface area of the box in squared units.
Definition: aabbox3d.h:141
saga::core::aabbox3d::intersectsWithLine
bool intersectsWithLine(const line3d< T > &line) const
Tests if the box intersects with a line.
Definition: aabbox3d.h:268
saga::core::aabbox3d
Axis aligned bounding box in 3d dimensional space.
Definition: aabbox3d.h:20
saga::core::aabbox3d::aabbox3d
aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz)
Constructor with min edge and max edge as single values, not vectors.
Definition: aabbox3d.h:31
saga::core::aabbox3d::reset
void reset(T x, T y, T z)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:49
saga::core::line3d::getVector
glm::vec3 getVector() const
Get vector of line.
Definition: line3d.h:70
saga::core::aabbox3d::getEdges
void getEdges(glm::vec3 *edges) const
Stores all 8 edges of the box into an array.
Definition: aabbox3d.h:149
saga::core::aabbox3d::operator!=
bool operator!=(const aabbox3d< T > &other) const
Inequality operator.
Definition: aabbox3d.h:41
saga::core::aabbox3d::aabbox3d
aabbox3d(const glm::vec3 &init)
Constructor with only one point.
Definition: aabbox3d.h:29
saga::core::aabbox3d::intersectsWithLine
bool intersectsWithLine(const glm::vec3 &linemiddle, const glm::vec3 &linevect, T halflength) const
Tests if the box intersects with a line.
Definition: aabbox3d.h:279
saga::core::aabbox3d::getVolume
T getVolume() const
Get the volume enclosed by the box in cubed units.
Definition: aabbox3d.h:134
saga::core::aabbox3d::getCenter
glm::vec3 getCenter() const
Get center of the bounding box.
Definition: aabbox3d.h:105
saga::core::max_
const T & max_(const T &a, const T &b)
returns maximum of two values. Own implementation to get rid of the STL (VS6 problems)
Definition: irrMath.h:177
saga::core::aabbox3d::addInternalBox
void addInternalBox(const aabbox3d< T > &b)
Adds another bounding box.
Definition: aabbox3d.h:81
saga::core::aabbox3d::MaxEdge
glm::vec3 MaxEdge
The far edge.
Definition: aabbox3d.h:346
saga::core::aabbox3d::isFullInside
bool isFullInside(const aabbox3d< T > &other) const
Check if this box is completely inside the 'other' box.
Definition: aabbox3d.h:230
saga::core::aabbox3d::addInternalPoint
void addInternalPoint(const glm::vec3 &p)
Adds a point to the bounding box.
Definition: aabbox3d.h:73
saga::core::aabbox3d::reset
void reset(const aabbox3d< T > &initValue)
Resets the bounding box.
Definition: aabbox3d.h:57
line3d.h
saga::core::min_
const T & min_(const T &a, const T &b)
returns minimum of two values. Own implementation to get rid of the STL (VS6 problems)
Definition: irrMath.h:163
saga::core::aabbox3d::aabbox3d
aabbox3d(const glm::vec3 &min, const glm::vec3 &max)
Constructor with min edge and max edge.
Definition: aabbox3d.h:27
saga::core::line3d::getMiddle
glm::vec3 getMiddle() const
Get middle of line.
Definition: line3d.h:63
saga::core::ISREL3D_BACK
@ ISREL3D_BACK
Definition: plane3d.h:21
saga::core::plane3d::Normal
glm::vec3 Normal
Normal vector of the plane.
Definition: plane3d.h:241
saga::core::aabbox3d::reset
void reset(const glm::vec3 &initValue)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:64
saga
Definition: aabbox3d.h:11
saga::core::ISREL3D_CLIPPED
@ ISREL3D_CLIPPED
Definition: plane3d.h:24
saga::core::aabbox3d::isPointTotalInside
bool isPointTotalInside(const glm::vec3 &p) const
Determines if a point is within this box and not its borders.
Definition: aabbox3d.h:219