1 | #ifndef NX_FOUNDATION_NXBOUNDS3
|
---|
2 | #define NX_FOUNDATION_NXBOUNDS3
|
---|
3 | /*----------------------------------------------------------------------------*\
|
---|
4 | |
|
---|
5 | | Public Interface to NovodeX Technology
|
---|
6 | |
|
---|
7 | | www.novodex.com
|
---|
8 | |
|
---|
9 | \*----------------------------------------------------------------------------*/
|
---|
10 | /** \addtogroup foundation
|
---|
11 | @{
|
---|
12 | */
|
---|
13 |
|
---|
14 | #include "Nxf.h"
|
---|
15 | #include "NxVec3.h"
|
---|
16 | #include "NxMat33.h"
|
---|
17 |
|
---|
18 | /**
|
---|
19 | \brief Class representing 3D range or axis aligned bounding box.
|
---|
20 |
|
---|
21 | Stored as minimum and maximum extent corners. Alternate representation
|
---|
22 | would be center and dimensions.
|
---|
23 | May be empty or nonempty. If not empty, min <= max has to hold.
|
---|
24 | */
|
---|
25 | class NxBounds3
|
---|
26 | {
|
---|
27 | public:
|
---|
28 | NX_INLINE NxBounds3();
|
---|
29 | NX_INLINE ~NxBounds3();
|
---|
30 |
|
---|
31 | /**
|
---|
32 | \brief Sets empty to true
|
---|
33 | */
|
---|
34 | NX_INLINE void setEmpty();
|
---|
35 |
|
---|
36 | /**
|
---|
37 | \brief Sets infinite bounds
|
---|
38 | */
|
---|
39 | NX_INLINE void setInfinite();
|
---|
40 |
|
---|
41 | /**
|
---|
42 | \brief low level assignment.
|
---|
43 |
|
---|
44 | \param minx Minimum X value
|
---|
45 | \param miny Minimum Y value
|
---|
46 | \param minz Minimum Z value
|
---|
47 | \param maxx Maximum X value
|
---|
48 | \param maxy Maximum Y value
|
---|
49 | \param maxz Maximum Z value
|
---|
50 | */
|
---|
51 | NX_INLINE void set(NxReal minx, NxReal miny, NxReal minz, NxReal maxx, NxReal maxy,NxReal maxz);
|
---|
52 |
|
---|
53 | /**
|
---|
54 | \brief vector assignment.
|
---|
55 |
|
---|
56 | \param min Minimum point of bounds.
|
---|
57 | \param max Maximum point of bounds.
|
---|
58 | */
|
---|
59 | NX_INLINE void set(const NxVec3& min, const NxVec3& max);
|
---|
60 |
|
---|
61 | /**
|
---|
62 | \brief expands the volume to include v
|
---|
63 |
|
---|
64 | \param v Point to expand to.
|
---|
65 | */
|
---|
66 | NX_INLINE void include(const NxVec3 &v);
|
---|
67 |
|
---|
68 | /**
|
---|
69 | \brief sets this to the intersection of this and b2.
|
---|
70 | */
|
---|
71 | //NX_INLINE void intersect(const NxBounds3 &b2);
|
---|
72 |
|
---|
73 | /**
|
---|
74 | \brief sets this to the union of this and b2.
|
---|
75 |
|
---|
76 | \param b2 Bounds to perform union with.
|
---|
77 | */
|
---|
78 | NX_INLINE void combine(const NxBounds3 &b2);
|
---|
79 |
|
---|
80 | /**
|
---|
81 | \brief sets this to the AABB of the OBB passed.
|
---|
82 |
|
---|
83 | \param orientation Orientation of the OBB.
|
---|
84 | \param translation Translation of the OBB.
|
---|
85 | \param halfDims radii of the OBB.
|
---|
86 | */
|
---|
87 | NX_INLINE void boundsOfOBB(const NxMat33 & orientation, const NxVec3 & translation, const NxVec3 & halfDims);
|
---|
88 |
|
---|
89 | /**
|
---|
90 | \brief transforms this volume as if it was an axis aligned bounding box, and then assigns the results' bounds to this.
|
---|
91 |
|
---|
92 | \param orientation Orientation to apply.
|
---|
93 | \param translation Translation to apply(applied after orientation transform)
|
---|
94 | */
|
---|
95 | NX_INLINE void transform(const NxMat33 & orientation, const NxVec3 & translation);
|
---|
96 |
|
---|
97 | NX_INLINE bool isEmpty() const;
|
---|
98 |
|
---|
99 | /**
|
---|
100 | \brief indicates whether the intersection of this and b is empty or not.
|
---|
101 |
|
---|
102 | \param b Bounds to test for intersection.
|
---|
103 | */
|
---|
104 | NX_INLINE bool intersects(const NxBounds3 &b) const;
|
---|
105 |
|
---|
106 | /**
|
---|
107 | \brief indicates whether the intersection of this and b is empty or not in the plane orthogonal to the axis passed (X = 0, Y = 1 or Z = 2).
|
---|
108 |
|
---|
109 | \param b Bounds to test for intersection.
|
---|
110 | \param axisToIgnore Axis to ignore when performing the intersection test.
|
---|
111 | */
|
---|
112 | NX_INLINE bool intersects2D(const NxBounds3 &b, unsigned axisToIgnore) const;
|
---|
113 |
|
---|
114 | /**
|
---|
115 | \brief indicates if these bounds contain v.
|
---|
116 |
|
---|
117 | \param v Point to test against bounds.
|
---|
118 | */
|
---|
119 | NX_INLINE bool contain(const NxVec3 &v) const;
|
---|
120 |
|
---|
121 | /**
|
---|
122 | \brief returns the center of this axis aligned box.
|
---|
123 |
|
---|
124 | \param center The centre of the bounds.
|
---|
125 | */
|
---|
126 | NX_INLINE void getCenter(NxVec3 & center) const;
|
---|
127 |
|
---|
128 | /**
|
---|
129 | \brief returns the dimensions (width/height/depth) of this axis aligned box.
|
---|
130 |
|
---|
131 | \param dims The dimensions of the bounds.
|
---|
132 | */
|
---|
133 | NX_INLINE void getDimensions(NxVec3 & dims) const;
|
---|
134 |
|
---|
135 | /**
|
---|
136 | \brief returns the extents, which are half of the width/height/depth.
|
---|
137 |
|
---|
138 | \param extents The extents/radii of the bounds.
|
---|
139 | */
|
---|
140 | NX_INLINE void getExtents(NxVec3 & extents) const;
|
---|
141 |
|
---|
142 | /**
|
---|
143 | \brief setups an AABB from center & extents vectors.
|
---|
144 |
|
---|
145 | \param c Centre vector
|
---|
146 | \param e Extents vector
|
---|
147 | */
|
---|
148 | NX_INLINE void setCenterExtents(const NxVec3& c, const NxVec3& e);
|
---|
149 |
|
---|
150 | /**
|
---|
151 | \brief scales the AABB.
|
---|
152 |
|
---|
153 | \param scale Factor to scale AABB by.
|
---|
154 | */
|
---|
155 | NX_INLINE void scale(NxF32 scale);
|
---|
156 |
|
---|
157 | /**
|
---|
158 | fattens the AABB in all 3 dimensions by the given distance.
|
---|
159 | */
|
---|
160 | NX_INLINE void fatten(NxReal distance);
|
---|
161 |
|
---|
162 |
|
---|
163 | NX_INLINE void combine(NxReal extension);
|
---|
164 |
|
---|
165 | NxVec3 min, max;
|
---|
166 | };
|
---|
167 |
|
---|
168 |
|
---|
169 | NX_INLINE NxBounds3::NxBounds3()
|
---|
170 | {
|
---|
171 | // Default to empty boxes for compatibility TODO: PT: remove this if useless
|
---|
172 | setEmpty();
|
---|
173 | }
|
---|
174 |
|
---|
175 |
|
---|
176 | NX_INLINE NxBounds3::~NxBounds3()
|
---|
177 | {
|
---|
178 | //nothing
|
---|
179 | }
|
---|
180 |
|
---|
181 |
|
---|
182 | NX_INLINE void NxBounds3::setEmpty()
|
---|
183 | {
|
---|
184 | // We know use this particular pattern for empty boxes
|
---|
185 | set(NX_MAX_REAL, NX_MAX_REAL, NX_MAX_REAL,
|
---|
186 | NX_MIN_REAL, NX_MIN_REAL, NX_MIN_REAL);
|
---|
187 | }
|
---|
188 |
|
---|
189 | NX_INLINE void NxBounds3::setInfinite()
|
---|
190 | {
|
---|
191 | set(NX_MIN_REAL, NX_MIN_REAL, NX_MIN_REAL,
|
---|
192 | NX_MAX_REAL, NX_MAX_REAL, NX_MAX_REAL);
|
---|
193 | }
|
---|
194 |
|
---|
195 | NX_INLINE void NxBounds3::set(NxReal minx, NxReal miny, NxReal minz, NxReal maxx, NxReal maxy,NxReal maxz)
|
---|
196 | {
|
---|
197 | min.set(minx, miny, minz);
|
---|
198 | max.set(maxx, maxy, maxz);
|
---|
199 | }
|
---|
200 |
|
---|
201 | NX_INLINE void NxBounds3::set(const NxVec3& _min, const NxVec3& _max)
|
---|
202 | {
|
---|
203 | min = _min;
|
---|
204 | max = _max;
|
---|
205 | }
|
---|
206 |
|
---|
207 | NX_INLINE void NxBounds3::include(const NxVec3 &v)
|
---|
208 | {
|
---|
209 | max.max(v);
|
---|
210 | min.min(v);
|
---|
211 | }
|
---|
212 |
|
---|
213 | NX_INLINE void NxBounds3::combine(const NxBounds3 &b2)
|
---|
214 | {
|
---|
215 | // - if we're empty, min = MAX,MAX,MAX => min will be b2 in all cases => it will copy b2, ok
|
---|
216 | // - if b2 is empty, the opposite happens => keep us unchanged => ok
|
---|
217 | // => same behaviour as before, automatically
|
---|
218 | min.min(b2.min);
|
---|
219 | max.max(b2.max);
|
---|
220 | }
|
---|
221 |
|
---|
222 | NX_INLINE void NxBounds3::boundsOfOBB(const NxMat33 & orientation, const NxVec3 & translation, const NxVec3 & halfDims)
|
---|
223 | {
|
---|
224 | NxReal dimx = halfDims[0];
|
---|
225 | NxReal dimy = halfDims[1];
|
---|
226 | NxReal dimz = halfDims[2];
|
---|
227 |
|
---|
228 | NxReal x = NxMath::abs(orientation(0,0) * dimx) + NxMath::abs(orientation(0,1) * dimy) + NxMath::abs(orientation(0,2) * dimz);
|
---|
229 | NxReal y = NxMath::abs(orientation(1,0) * dimx) + NxMath::abs(orientation(1,1) * dimy) + NxMath::abs(orientation(1,2) * dimz);
|
---|
230 | NxReal z = NxMath::abs(orientation(2,0) * dimx) + NxMath::abs(orientation(2,1) * dimy) + NxMath::abs(orientation(2,2) * dimz);
|
---|
231 |
|
---|
232 | set(-x + translation[0], -y + translation[1], -z + translation[2], x + translation[0], y + translation[1], z + translation[2]);
|
---|
233 | }
|
---|
234 |
|
---|
235 | NX_INLINE void NxBounds3::transform(const NxMat33 & orientation, const NxVec3 & translation)
|
---|
236 | {
|
---|
237 | // convert to center and extents form
|
---|
238 | NxVec3 center, extents;
|
---|
239 | getCenter(center);
|
---|
240 | getExtents(extents);
|
---|
241 |
|
---|
242 | center = orientation * center + translation;
|
---|
243 | boundsOfOBB(orientation, center, extents);
|
---|
244 | }
|
---|
245 |
|
---|
246 | NX_INLINE bool NxBounds3::isEmpty() const
|
---|
247 | {
|
---|
248 | // Consistency condition for (Min, Max) boxes: min < max
|
---|
249 | // TODO: PT: should we test against the explicit pattern ?
|
---|
250 | if(min.x < max.x) return false;
|
---|
251 | if(min.y < max.y) return false;
|
---|
252 | if(min.z < max.z) return false;
|
---|
253 | return true;
|
---|
254 | }
|
---|
255 |
|
---|
256 | NX_INLINE bool NxBounds3::intersects(const NxBounds3 &b) const
|
---|
257 | {
|
---|
258 | if ((b.min.x > max.x) || (min.x > b.max.x)) return false;
|
---|
259 | if ((b.min.y > max.y) || (min.y > b.max.y)) return false;
|
---|
260 | if ((b.min.z > max.z) || (min.z > b.max.z)) return false;
|
---|
261 | return true;
|
---|
262 | }
|
---|
263 |
|
---|
264 | NX_INLINE bool NxBounds3::intersects2D(const NxBounds3 &b, unsigned axis) const
|
---|
265 | {
|
---|
266 | // TODO: PT: could be static and like this:
|
---|
267 | // static unsigned i[3] = { 1,2,0,1 };
|
---|
268 | // const unsigned ii = i[axis];
|
---|
269 | // const unsigned jj = i[axis+1];
|
---|
270 | const unsigned i[3] = { 1,0,0 };
|
---|
271 | const unsigned j[3] = { 2,2,1 };
|
---|
272 | const unsigned ii = i[axis];
|
---|
273 | const unsigned jj = j[axis];
|
---|
274 | if ((b.min[ii] > max[ii]) || (min[ii] > b.max[ii])) return false;
|
---|
275 | if ((b.min[jj] > max[jj]) || (min[jj] > b.max[jj])) return false;
|
---|
276 | return true;
|
---|
277 | }
|
---|
278 |
|
---|
279 | NX_INLINE bool NxBounds3::contain(const NxVec3 &v) const
|
---|
280 | {
|
---|
281 | if ((v.x < min.x) || (v.x > max.x)) return false;
|
---|
282 | if ((v.y < min.y) || (v.y > max.y)) return false;
|
---|
283 | if ((v.z < min.z) || (v.z > max.z)) return false;
|
---|
284 | return true;
|
---|
285 | }
|
---|
286 |
|
---|
287 | NX_INLINE void NxBounds3::getCenter(NxVec3 & center) const
|
---|
288 | {
|
---|
289 | center.add(min,max);
|
---|
290 | center *= NxReal(0.5);
|
---|
291 | }
|
---|
292 |
|
---|
293 | NX_INLINE void NxBounds3::getDimensions(NxVec3 & dims) const
|
---|
294 | {
|
---|
295 | dims.subtract(max,min);
|
---|
296 | }
|
---|
297 |
|
---|
298 | NX_INLINE void NxBounds3::getExtents(NxVec3 & extents) const
|
---|
299 | {
|
---|
300 | extents.subtract(max,min);
|
---|
301 | extents *= NxReal(0.5);
|
---|
302 | }
|
---|
303 |
|
---|
304 | NX_INLINE void NxBounds3::setCenterExtents(const NxVec3& c, const NxVec3& e)
|
---|
305 | {
|
---|
306 | min = c - e;
|
---|
307 | max = c + e;
|
---|
308 | }
|
---|
309 |
|
---|
310 | NX_INLINE void NxBounds3::scale(NxF32 scale)
|
---|
311 | {
|
---|
312 | min *= scale;
|
---|
313 | max *= scale;
|
---|
314 | }
|
---|
315 |
|
---|
316 | NX_INLINE void NxBounds3::fatten(NxReal distance)
|
---|
317 | {
|
---|
318 | min.x -= distance;
|
---|
319 | min.y -= distance;
|
---|
320 | min.z -= distance;
|
---|
321 |
|
---|
322 | max.x += distance;
|
---|
323 | max.y += distance;
|
---|
324 | max.z += distance;
|
---|
325 | }
|
---|
326 |
|
---|
327 | #endif
|
---|
328 |
|
---|
329 |
|
---|
330 | //AGCOPYRIGHTBEGIN
|
---|
331 | ///////////////////////////////////////////////////////////////////////////
|
---|
332 | // Copyright © 2005 AGEIA Technologies.
|
---|
333 | // All rights reserved. www.ageia.com
|
---|
334 | ///////////////////////////////////////////////////////////////////////////
|
---|
335 | //AGCOPYRIGHTEND
|
---|
336 |
|
---|