RavEngine
Loading...
Searching...
No Matches
PxBounds3.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef PX_BOUNDS3_H
30#define PX_BOUNDS3_H
31
36#include "foundation/PxTransform.h"
37#include "foundation/PxMat33.h"
38
39#if !PX_DOXYGEN
40namespace physx
41{
42#endif
43
44// maximum extents defined such that floating point exceptions are avoided for standard use cases
45#define PX_MAX_BOUNDS_EXTENTS (PX_MAX_REAL * 0.25f)
46
58{
59 public:
64 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3()
65 {
66 }
67
71 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3(const PxVec3& minimum, const PxVec3& maximum);
72
73 PX_CUDA_CALLABLE PX_FORCE_INLINE void operator=(const PxBounds3& other)
74 {
75 minimum = other.minimum;
76 maximum = other.maximum;
77 }
78
79 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3(const PxBounds3& other)
80 {
81 minimum = other.minimum;
82 maximum = other.maximum;
83 }
84
88 static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 empty();
89
95 static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 boundsOfPoints(const PxVec3& v0, const PxVec3& v1);
96
102 static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 centerExtents(const PxVec3& center, const PxVec3& extent);
103
107 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent);
108
112 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 poseExtent(const PxTransform& pose, const PxVec3& extent);
113
122 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformSafe(const PxMat33& matrix, const PxBounds3& bounds);
123
132 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformFast(const PxMat33& matrix, const PxBounds3& bounds);
133
142 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformSafe(const PxTransform& transform, const PxBounds3& bounds);
143
152 static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformFast(const PxTransform& transform, const PxBounds3& bounds);
153
157 PX_CUDA_CALLABLE PX_FORCE_INLINE void setEmpty();
158
162 PX_CUDA_CALLABLE PX_FORCE_INLINE void setMaximal();
163
168 PX_CUDA_CALLABLE PX_FORCE_INLINE void include(const PxVec3& v);
169
174 PX_CUDA_CALLABLE PX_FORCE_INLINE void include(const PxBounds3& b);
175
176 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isEmpty() const;
177
182 PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects(const PxBounds3& b) const;
183
189 PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects1D(const PxBounds3& a, uint32_t axis) const;
190
195 PX_CUDA_CALLABLE PX_FORCE_INLINE bool contains(const PxVec3& v) const;
196
201 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isInside(const PxBounds3& box) const;
202
206 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getCenter() const;
207
211 PX_CUDA_CALLABLE PX_FORCE_INLINE float getCenter(uint32_t axis) const;
212
216 PX_CUDA_CALLABLE PX_FORCE_INLINE float getExtents(uint32_t axis) const;
217
221 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getDimensions() const;
222
226 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getExtents() const;
227
235 PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleSafe(float scale);
236
244 PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleFast(float scale);
245
251 PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenSafe(float distance);
252
258 PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenFast(float distance);
259
263 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite() const;
264
268 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const;
269
274 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 closestPoint(const PxVec3& p) const;
275
276 PxVec3 minimum, maximum;
277};
278
279PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3::PxBounds3(const PxVec3& minimum_, const PxVec3& maximum_)
280: minimum(minimum_), maximum(maximum_)
281{
282}
283
285{
286 return PxBounds3(PxVec3(PX_MAX_BOUNDS_EXTENTS), PxVec3(-PX_MAX_BOUNDS_EXTENTS));
287}
288
289PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isFinite() const
290{
291 return minimum.isFinite() && maximum.isFinite();
292}
293
295{
296 return PxBounds3(v0.minimum(v1), v0.maximum(v1));
297}
298
299PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 PxBounds3::centerExtents(const PxVec3& center, const PxVec3& extent)
300{
301 return PxBounds3(center - extent, center + extent);
302}
303
304PX_CUDA_CALLABLE PX_INLINE PxBounds3
305PxBounds3::basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent)
306{
307 // extended basis vectors
308 const PxVec3 c0 = basis.column0 * extent.x;
309 const PxVec3 c1 = basis.column1 * extent.y;
310 const PxVec3 c2 = basis.column2 * extent.z;
311
312 // find combination of base vectors that produces max. distance for each component = sum of abs()
313 const PxVec3 w( PxAbs(c0.x) + PxAbs(c1.x) + PxAbs(c2.x),
314 PxAbs(c0.y) + PxAbs(c1.y) + PxAbs(c2.y),
315 PxAbs(c0.z) + PxAbs(c1.z) + PxAbs(c2.z));
316
317 return PxBounds3(center - w, center + w);
318}
319
320PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::poseExtent(const PxTransform& pose, const PxVec3& extent)
321{
322 return basisExtent(pose.p, PxMat33(pose.q), extent);
323}
324
326{
327 minimum = PxVec3(PX_MAX_BOUNDS_EXTENTS);
328 maximum = PxVec3(-PX_MAX_BOUNDS_EXTENTS);
329}
330
332{
333 minimum = PxVec3(-PX_MAX_BOUNDS_EXTENTS);
334 maximum = PxVec3(PX_MAX_BOUNDS_EXTENTS);
335}
336
337PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxVec3& v)
338{
339 PX_ASSERT(isValid());
340 minimum = minimum.minimum(v);
341 maximum = maximum.maximum(v);
342}
343
344PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxBounds3& b)
345{
346 PX_ASSERT(isValid());
347 minimum = minimum.minimum(b.minimum);
348 maximum = maximum.maximum(b.maximum);
349}
350
351PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isEmpty() const
352{
353 PX_ASSERT(isValid());
354 return minimum.x > maximum.x;
355}
356
357PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects(const PxBounds3& b) const
358{
359 PX_ASSERT(isValid() && b.isValid());
360 return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y || minimum.y > b.maximum.y ||
361 b.minimum.z > maximum.z || minimum.z > b.maximum.z);
362}
363
364PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects1D(const PxBounds3& a, uint32_t axis) const
365{
366 PX_ASSERT(isValid() && a.isValid());
367 return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis];
368}
369
370PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::contains(const PxVec3& v) const
371{
372 PX_ASSERT(isValid());
373
374 return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y || v.z < minimum.z ||
375 v.z > maximum.z);
376}
377
378PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isInside(const PxBounds3& box) const
379{
380 PX_ASSERT(isValid() && box.isValid());
381 if(box.minimum.x > minimum.x)
382 return false;
383 if(box.minimum.y > minimum.y)
384 return false;
385 if(box.minimum.z > minimum.z)
386 return false;
387 if(box.maximum.x < maximum.x)
388 return false;
389 if(box.maximum.y < maximum.y)
390 return false;
391 if(box.maximum.z < maximum.z)
392 return false;
393 return true;
394}
395
397{
398 PX_ASSERT(isValid());
399 return (minimum + maximum) * 0.5f;
400}
401
402PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getCenter(uint32_t axis) const
403{
404 PX_ASSERT(isValid());
405 return (minimum[axis] + maximum[axis]) * 0.5f;
406}
407
408PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getExtents(uint32_t axis) const
409{
410 PX_ASSERT(isValid());
411 return (maximum[axis] - minimum[axis]) * 0.5f;
412}
413
415{
416 PX_ASSERT(isValid());
417 return maximum - minimum;
418}
419
421{
422 PX_ASSERT(isValid());
423 return getDimensions() * 0.5f;
424}
425
426PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleSafe(float scale)
427{
428 PX_ASSERT(isValid());
429 if(!isEmpty())
430 scaleFast(scale);
431}
432
433PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleFast(float scale)
434{
435 PX_ASSERT(isValid());
436 *this = centerExtents(getCenter(), getExtents() * scale);
437}
438
439PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenSafe(float distance)
440{
441 PX_ASSERT(isValid());
442 if(!isEmpty())
443 fattenFast(distance);
444}
445
446PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenFast(float distance)
447{
448 PX_ASSERT(isValid());
449 minimum.x -= distance;
450 minimum.y -= distance;
451 minimum.z -= distance;
452
453 maximum.x += distance;
454 maximum.y += distance;
455 maximum.z += distance;
456}
457
458PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxMat33& matrix, const PxBounds3& bounds)
459{
460 PX_ASSERT(bounds.isValid());
461 return !bounds.isEmpty() ? transformFast(matrix, bounds) : bounds;
462}
463
464PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxMat33& matrix, const PxBounds3& bounds)
465{
466 PX_ASSERT(bounds.isValid());
467 return PxBounds3::basisExtent(matrix * bounds.getCenter(), matrix, bounds.getExtents());
468}
469
470PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxTransform& transform, const PxBounds3& bounds)
471{
472 PX_ASSERT(bounds.isValid());
473 return !bounds.isEmpty() ? transformFast(transform, bounds) : bounds;
474}
475
476PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxTransform& transform, const PxBounds3& bounds)
477{
478 PX_ASSERT(bounds.isValid());
479 return PxBounds3::basisExtent(transform.transform(bounds.getCenter()), PxMat33(transform.q), bounds.getExtents());
480}
481
482PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isValid() const
483{
484 return (isFinite() && (((minimum.x <= maximum.x) && (minimum.y <= maximum.y) && (minimum.z <= maximum.z)) ||
485 ((minimum.x == PX_MAX_BOUNDS_EXTENTS) && (minimum.y == PX_MAX_BOUNDS_EXTENTS) &&
486 (minimum.z == PX_MAX_BOUNDS_EXTENTS) && (maximum.x == -PX_MAX_BOUNDS_EXTENTS) &&
487 (maximum.y == -PX_MAX_BOUNDS_EXTENTS) && (maximum.z == -PX_MAX_BOUNDS_EXTENTS))));
488}
489
490PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::closestPoint(const PxVec3& p) const
491{
492 return minimum.maximum(maximum.minimum(p));
493}
494
495#if !PX_DOXYGEN
496} // namespace physx
497#endif
498
500#endif
501
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
static PX_CUDA_CALLABLE PX_INLINE PxBounds3 basisExtent(const PxVec3 &center, const PxMat33 &basis, const PxVec3 &extent)
Construct from center, extent, and (not necessarily orthogonal) basis.
Definition PxBounds3.h:305
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 closestPoint(const PxVec3 &p) const
Definition PxBounds3.h:490
PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenSafe(float distance)
Definition PxBounds3.h:439
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getExtents() const
returns the extents, which are half of the width/height/depth.
Definition PxBounds3.h:420
PX_CUDA_CALLABLE PX_FORCE_INLINE void include(const PxVec3 &v)
expands the volume to include v
Definition PxBounds3.h:337
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getDimensions() const
returns the dimensions (width/height/depth) of this axis aligned box.
Definition PxBounds3.h:414
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const
Definition PxBounds3.h:482
PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleSafe(float scale)
scales the AABB.
Definition PxBounds3.h:426
static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformSafe(const PxMat33 &matrix, const PxBounds3 &bounds)
gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
Definition PxBounds3.h:458
PX_CUDA_CALLABLE PX_FORCE_INLINE void setMaximal()
Sets the bounds to maximum size [-PX_MAX_BOUNDS_EXTENTS, PX_MAX_BOUNDS_EXTENTS].
Definition PxBounds3.h:331
PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects(const PxBounds3 &b) const
indicates whether the intersection of this and b is empty or not.
Definition PxBounds3.h:357
static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 empty()
Return empty bounds.
Definition PxBounds3.h:284
PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenFast(float distance)
Definition PxBounds3.h:446
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getCenter() const
returns the center of this axis aligned box.
Definition PxBounds3.h:396
PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects1D(const PxBounds3 &a, uint32_t axis) const
computes the 1D-intersection between two AABBs, on a given axis.
Definition PxBounds3.h:364
static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformFast(const PxMat33 &matrix, const PxBounds3 &bounds)
gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
Definition PxBounds3.h:464
PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleFast(float scale)
scales the AABB.
Definition PxBounds3.h:433
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isInside(const PxBounds3 &box) const
checks a box is inside another box.
Definition PxBounds3.h:378
static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 centerExtents(const PxVec3 &center, const PxVec3 &extent)
returns the AABB from center and extents vectors.
Definition PxBounds3.h:299
PX_CUDA_CALLABLE PX_FORCE_INLINE bool contains(const PxVec3 &v) const
indicates if these bounds contain v.
Definition PxBounds3.h:370
PX_CUDA_CALLABLE PX_FORCE_INLINE float getExtents(uint32_t axis) const
get component of the box's extents along a given axis
Definition PxBounds3.h:408
static PX_CUDA_CALLABLE PX_INLINE PxBounds3 poseExtent(const PxTransform &pose, const PxVec3 &extent)
Construct from pose and extent.
Definition PxBounds3.h:320
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite() const
Definition PxBounds3.h:289
PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3()
Default constructor, not performing any initialization for performance reason.
Definition PxBounds3.h:64
static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 boundsOfPoints(const PxVec3 &v0, const PxVec3 &v1)
returns the AABB containing v0 and v1.
Definition PxBounds3.h:294
PX_CUDA_CALLABLE PX_FORCE_INLINE void setEmpty()
Sets empty to true.
Definition PxBounds3.h:325
3x3 matrix class
Definition PxMat33.h:91
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
3 Element vector class.
Definition PxVec3.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 maximum(const PxVec3 &v) const
element-wise maximum
Definition PxVec3.h:360
PX_CUDA_CALLABLE PX_INLINE bool isFinite() const
returns true if all 3 elems of the vector are finite (not NAN or INF, etc.)
Definition PxVec3.h:156
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 minimum(const PxVec3 &v) const
element-wise minimum
Definition PxVec3.h:344
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_INLINE
Definition PxPreprocessor.h:320
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109