Irrlicht 3D Engine
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 "irrMath.h"
9 #include "plane3d.h"
10 #include "line3d.h"
11 
12 namespace irr
13 {
14 namespace core
15 {
16 
18 
20 template <class T>
21 class aabbox3d
22 {
23  public:
24 
26  aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {}
28  aabbox3d(const vector3d<T>& min, const vector3d<T>& max): MinEdge(min), MaxEdge(max) {}
30  aabbox3d(const vector3d<T>& init): MinEdge(init), MaxEdge(init) {}
32  aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {}
33 
34  // operators
36 
38  inline bool operator==(const aabbox3d<T>& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
40 
42  inline bool operator!=(const aabbox3d<T>& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
43 
44  // functions
45 
47 
50  void reset(T x, T y, T z)
51  {
52  MaxEdge.set(x,y,z);
53  MinEdge = MaxEdge;
54  }
55 
57 
58  void reset(const aabbox3d<T>& initValue)
59  {
60  *this = initValue;
61  }
62 
64 
65  void reset(const vector3d<T>& initValue)
66  {
67  MaxEdge = initValue;
68  MinEdge = initValue;
69  }
70 
72 
75  {
76  addInternalPoint(p.X, p.Y, p.Z);
77  }
78 
80 
82  void addInternalBox(const aabbox3d<T>& b)
83  {
86  }
87 
89 
93  void addInternalPoint(T x, T y, T z)
94  {
95  if (x>MaxEdge.X) MaxEdge.X = x;
96  if (y>MaxEdge.Y) MaxEdge.Y = y;
97  if (z>MaxEdge.Z) MaxEdge.Z = z;
98 
99  if (x<MinEdge.X) MinEdge.X = x;
100  if (y<MinEdge.Y) MinEdge.Y = y;
101  if (z<MinEdge.Z) MinEdge.Z = z;
102  }
103 
105 
107  {
108  return (MinEdge + MaxEdge) / 2;
109  }
110 
112 
114  {
115  return MaxEdge - MinEdge;
116  }
117 
119 
120  T getRadius() const
121  {
122  const T radius = getExtent().getLength() / 2;
123  return radius;
124  }
125 
127 
129  bool isEmpty() const
130  {
131  return MinEdge.equals ( MaxEdge );
132  }
133 
135  T getVolume() const
136  {
137  const vector3d<T> e = getExtent();
138  return e.X * e.Y * e.Z;
139  }
140 
142  T getArea() const
143  {
144  const vector3d<T> e = getExtent();
145  return 2*(e.X*e.Y + e.X*e.Z + e.Y*e.Z);
146  }
147 
149 
150  void getEdges(vector3d<T> *edges) const
151  {
152  const core::vector3d<T> middle = getCenter();
153  const core::vector3d<T> diag = middle - MaxEdge;
154 
155  /*
156  Edges are stored in this way:
157  Hey, am I an ascii artist, or what? :) niko.
158  /3--------/7
159  / | / |
160  / | / |
161  1---------5 |
162  | /2- - -|- -6
163  | / | /
164  |/ | /
165  0---------4/
166  */
167 
168  edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
169  edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
170  edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
171  edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
172  edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
173  edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
174  edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
175  edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
176  }
177 
179 
180  void repair()
181  {
182  T t;
183 
184  if (MinEdge.X > MaxEdge.X)
185  { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; }
186  if (MinEdge.Y > MaxEdge.Y)
187  { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; }
188  if (MinEdge.Z > MaxEdge.Z)
189  { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; }
190  }
191 
192  // Check if MaxEdge > MinEdge
193  bool isValid() const
194  {
195  if (MinEdge.X > MaxEdge.X) return false;
196  if (MinEdge.Y > MaxEdge.Y) return false;
197  if (MinEdge.Z > MaxEdge.Z) return false;
198 
199  return true;
200  }
201 
203 
209  {
210  f32 inv = 1.0f - d;
211  return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d),
212  (other.MaxEdge*inv) + (MaxEdge*d));
213  }
214 
216 
219  bool isPointInside(const vector3d<T>& 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 isPointTotalInside(const vector3d<T>& p) const
231  {
232  return (p.X > MinEdge.X && p.X < MaxEdge.X &&
233  p.Y > MinEdge.Y && p.Y < MaxEdge.Y &&
234  p.Z > MinEdge.Z && p.Z < MaxEdge.Z);
235  }
236 
238 
241  bool isFullInside(const aabbox3d<T>& other) const
242  {
243  return (MinEdge.X >= other.MinEdge.X && MinEdge.Y >= other.MinEdge.Y && MinEdge.Z >= other.MinEdge.Z &&
244  MaxEdge.X <= other.MaxEdge.X && MaxEdge.Y <= other.MaxEdge.Y && MaxEdge.Z <= other.MaxEdge.Z);
245  }
246 
248  aabbox3d<T> intersect(const aabbox3d<T>& other) const
249  {
250  aabbox3d<T> out;
251 
252  if (!intersectsWithBox(other))
253  return out;
254 
255  out.MaxEdge.X = min_(MaxEdge.X, other.MaxEdge.X);
256  out.MaxEdge.Y = min_(MaxEdge.Y, other.MaxEdge.Y);
257  out.MaxEdge.Z = min_(MaxEdge.Z, other.MaxEdge.Z);
258 
259  out.MinEdge.X = max_(MinEdge.X, other.MinEdge.X);
260  out.MinEdge.Y = max_(MinEdge.Y, other.MinEdge.Y);
261  out.MinEdge.Z = max_(MinEdge.Z, other.MinEdge.Z);
262 
263  return out;
264  }
265 
267 
270  bool intersectsWithBox(const aabbox3d<T>& other) const
271  {
272  return (MinEdge.X <= other.MaxEdge.X && MinEdge.Y <= other.MaxEdge.Y && MinEdge.Z <= other.MaxEdge.Z &&
273  MaxEdge.X >= other.MinEdge.X && MaxEdge.Y >= other.MinEdge.Y && MaxEdge.Z >= other.MinEdge.Z);
274  }
275 
277 
279  bool intersectsWithLine(const line3d<T>& line) const
280  {
281  return intersectsWithLine(line.getMiddle(), line.getVector().normalize(),
282  (T)(line.getLength() * 0.5));
283  }
284 
286 
290  bool intersectsWithLine(const vector3d<T>& linemiddle,
291  const vector3d<T>& linevect, T halflength) const
292  {
293  const vector3d<T> e = getExtent() * (T)0.5;
294  const vector3d<T> t = getCenter() - linemiddle;
295 
296  if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) ||
297  (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) ||
298  (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) )
299  return false;
300 
301  T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y);
302  if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r )
303  return false;
304 
305  r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X);
306  if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r )
307  return false;
308 
309  r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X);
310  if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r)
311  return false;
312 
313  return true;
314  }
315 
317 
322  {
323  vector3d<T> nearPoint(MaxEdge);
324  vector3d<T> farPoint(MinEdge);
325 
326  if (plane.Normal.X > (T)0)
327  {
328  nearPoint.X = MinEdge.X;
329  farPoint.X = MaxEdge.X;
330  }
331 
332  if (plane.Normal.Y > (T)0)
333  {
334  nearPoint.Y = MinEdge.Y;
335  farPoint.Y = MaxEdge.Y;
336  }
337 
338  if (plane.Normal.Z > (T)0)
339  {
340  nearPoint.Z = MinEdge.Z;
341  farPoint.Z = MaxEdge.Z;
342  }
343 
344  if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0)
345  return ISREL3D_FRONT;
346 
347  if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0)
348  return ISREL3D_CLIPPED;
349 
350  return ISREL3D_BACK;
351  }
352 
355 
358 };
359 
364 
365 } // end namespace core
366 } // end namespace irr
367 
368 #endif
369 
aabbox3d(const vector3d< T > &min, const vector3d< T > &max)
Constructor with min edge and max edge.
Definition: aabbox3d.h:28
T D
Distance from origin.
Definition: plane3d.h:231
vector3d< T > MaxEdge
The far edge.
Definition: aabbox3d.h:357
T Y
Y coordinate of the vector.
Definition: vector3d.h:413
bool intersectsWithBox(const aabbox3d< T > &other) const
Determines if the axis-aligned box intersects with another axis-aligned box.
Definition: aabbox3d.h:270
T getRadius() const
Get radius of the bounding sphere.
Definition: aabbox3d.h:120
float f32
32 bit floating point variable.
Definition: irrTypes.h:108
bool intersectsWithLine(const line3d< T > &line) const
Tests if the box intersects with a line.
Definition: aabbox3d.h:279
vector3d< T > Normal
Normal vector of the plane.
Definition: plane3d.h:228
EIntersectionRelation3D
Enumeration for intersection relations of 3d objects.
Definition: plane3d.h:17
T X
X coordinate of the vector.
Definition: vector3d.h:410
void reset(const vector3d< T > &initValue)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:65
vector3d< T > & set(const T nx, const T ny, const T nz)
Definition: vector3d.h:113
Everything in the Irrlicht Engine can be found in this namespace.
Definition: aabbox3d.h:12
bool isPointInside(const vector3d< T > &p) const
Determines if a point is within this box.
Definition: aabbox3d.h:219
3d vector template class with lots of operators and methods.
Definition: vector3d.h:22
3D line between two points with intersection methods.
Definition: line3d.h:18
void reset(T x, T y, T z)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:50
vector3d< T > getExtent() const
Get extent of the box (maximal distance of two points in the box)
Definition: aabbox3d.h:113
vector3d< T > getVector() const
Get vector of line.
Definition: line3d.h:71
aabbox3d< T > intersect(const aabbox3d< T > &other) const
Returns the intersection of this box with another, if possible.
Definition: aabbox3d.h:248
aabbox3d< T > getInterpolated(const aabbox3d< T > &other, f32 d) const
Calculates a new interpolated bounding box.
Definition: aabbox3d.h:208
EIntersectionRelation3D classifyPlaneRelation(const plane3d< T > &plane) const
Classifies a relation with a plane.
Definition: aabbox3d.h:321
aabbox3d(const vector3d< T > &init)
Constructor with only one point.
Definition: aabbox3d.h:30
bool isFullInside(const aabbox3d< T > &other) const
Check if this box is completely inside the 'other' box.
Definition: aabbox3d.h:241
bool isValid() const
Definition: aabbox3d.h:193
void addInternalBox(const aabbox3d< T > &b)
Adds another bounding box.
Definition: aabbox3d.h:82
aabbox3d< f32 > aabbox3df
Typedef for a f32 3d bounding box.
Definition: aabbox3d.h:361
aabbox3d< s32 > aabbox3di
Typedef for an integer 3d bounding box.
Definition: aabbox3d.h:363
T getVolume() const
Get the volume enclosed by the box in cubed units.
Definition: aabbox3d.h:135
vector3d< T > getMiddle() const
Get middle of line.
Definition: line3d.h:64
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:32
bool isPointTotalInside(const vector3d< T > &p) const
Determines if a point is within this box and not its borders.
Definition: aabbox3d.h:230
bool operator!=(const aabbox3d< T > &other) const
Inequality operator.
Definition: aabbox3d.h:42
Template plane class with some intersection testing methods.
Definition: plane3d.h:33
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:124
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:138
T getArea() const
Get the surface area of the box in squared units.
Definition: aabbox3d.h:142
vector3d< T > MinEdge
The near edge.
Definition: aabbox3d.h:354
void addInternalPoint(T x, T y, T z)
Adds a point to the bounding box.
Definition: aabbox3d.h:93
void getEdges(vector3d< T > *edges) const
Stores all 8 edges of the box into an array.
Definition: aabbox3d.h:150
void addInternalPoint(const vector3d< T > &p)
Adds a point to the bounding box.
Definition: aabbox3d.h:74
void reset(const aabbox3d< T > &initValue)
Resets the bounding box.
Definition: aabbox3d.h:58
bool isEmpty() const
Check if the box is empty.
Definition: aabbox3d.h:129
T Z
Z coordinate of the vector.
Definition: vector3d.h:416
vector3d< T > getCenter() const
Get center of the bounding box.
Definition: aabbox3d.h:106
Axis aligned bounding box in 3d dimensional space.
Definition: aabbox3d.h:21
void repair()
Repairs the box.
Definition: aabbox3d.h:180
bool operator==(const aabbox3d< T > &other) const
Equality operator.
Definition: aabbox3d.h:38
bool intersectsWithLine(const vector3d< T > &linemiddle, const vector3d< T > &linevect, T halflength) const
Tests if the box intersects with a line.
Definition: aabbox3d.h:290
T getLength() const
Get length of line.
Definition: line3d.h:56
aabbox3d()
Default Constructor.
Definition: aabbox3d.h:26