PxBounds3.h

Go to the documentation of this file.
00001 //
00002 // Redistribution and use in source and binary forms, with or without
00003 // modification, are permitted provided that the following conditions
00004 // are met:
00005 //  * Redistributions of source code must retain the above copyright
00006 //    notice, this list of conditions and the following disclaimer.
00007 //  * Redistributions in binary form must reproduce the above copyright
00008 //    notice, this list of conditions and the following disclaimer in the
00009 //    documentation and/or other materials provided with the distribution.
00010 //  * Neither the name of NVIDIA CORPORATION nor the names of its
00011 //    contributors may be used to endorse or promote products derived
00012 //    from this software without specific prior written permission.
00013 //
00014 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
00015 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00017 // PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00018 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00019 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00020 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00021 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00022 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00024 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 //
00026 // Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved.
00027 // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
00028 // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
00029 
00030 #ifndef PXFOUNDATION_PXBOUNDS3_H
00031 #define PXFOUNDATION_PXBOUNDS3_H
00032 
00037 #include "foundation/PxTransform.h"
00038 #include "foundation/PxMat33.h"
00039 
00040 #if !PX_DOXYGEN
00041 namespace physx
00042 {
00043 #endif
00044 
00045 // maximum extents defined such that floating point exceptions are avoided for standard use cases
00046 #define PX_MAX_BOUNDS_EXTENTS (PX_MAX_REAL * 0.25f)
00047 
00058 class PxBounds3
00059 {
00060   public:
00065     PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3()
00066     {
00067     }
00068 
00072     PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3(const PxVec3& minimum, const PxVec3& maximum);
00073 
00077     static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 empty();
00078 
00084     static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 boundsOfPoints(const PxVec3& v0, const PxVec3& v1);
00085 
00091     static PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 centerExtents(const PxVec3& center, const PxVec3& extent);
00092 
00096     static PX_CUDA_CALLABLE PX_INLINE PxBounds3
00097     basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent);
00098 
00102     static PX_CUDA_CALLABLE PX_INLINE PxBounds3 poseExtent(const PxTransform& pose, const PxVec3& extent);
00103 
00112     static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformSafe(const PxMat33& matrix, const PxBounds3& bounds);
00113 
00122     static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformFast(const PxMat33& matrix, const PxBounds3& bounds);
00123 
00132     static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformSafe(const PxTransform& transform, const PxBounds3& bounds);
00133 
00142     static PX_CUDA_CALLABLE PX_INLINE PxBounds3 transformFast(const PxTransform& transform, const PxBounds3& bounds);
00143 
00147     PX_CUDA_CALLABLE PX_FORCE_INLINE void setEmpty();
00148 
00152     PX_CUDA_CALLABLE PX_FORCE_INLINE void setMaximal();
00153 
00158     PX_CUDA_CALLABLE PX_FORCE_INLINE void include(const PxVec3& v);
00159 
00164     PX_CUDA_CALLABLE PX_FORCE_INLINE void include(const PxBounds3& b);
00165 
00166     PX_CUDA_CALLABLE PX_FORCE_INLINE bool isEmpty() const;
00167 
00172     PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects(const PxBounds3& b) const;
00173 
00179     PX_CUDA_CALLABLE PX_FORCE_INLINE bool intersects1D(const PxBounds3& a, uint32_t axis) const;
00180 
00185     PX_CUDA_CALLABLE PX_FORCE_INLINE bool contains(const PxVec3& v) const;
00186 
00191     PX_CUDA_CALLABLE PX_FORCE_INLINE bool isInside(const PxBounds3& box) const;
00192 
00196     PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getCenter() const;
00197 
00201     PX_CUDA_CALLABLE PX_FORCE_INLINE float getCenter(uint32_t axis) const;
00202 
00206     PX_CUDA_CALLABLE PX_FORCE_INLINE float getExtents(uint32_t axis) const;
00207 
00211     PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getDimensions() const;
00212 
00216     PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getExtents() const;
00217 
00225     PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleSafe(float scale);
00226 
00234     PX_CUDA_CALLABLE PX_FORCE_INLINE void scaleFast(float scale);
00235 
00241     PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenSafe(float distance);
00242 
00248     PX_CUDA_CALLABLE PX_FORCE_INLINE void fattenFast(float distance);
00249 
00253     PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite() const;
00254 
00258     PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const;
00259 
00260     PxVec3 minimum, maximum;
00261 };
00262 
00263 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3::PxBounds3(const PxVec3& minimum_, const PxVec3& maximum_)
00264 : minimum(minimum_), maximum(maximum_)
00265 {
00266 }
00267 
00268 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 PxBounds3::empty()
00269 {
00270     return PxBounds3(PxVec3(PX_MAX_BOUNDS_EXTENTS), PxVec3(-PX_MAX_BOUNDS_EXTENTS));
00271 }
00272 
00273 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isFinite() const
00274 {
00275     return minimum.isFinite() && maximum.isFinite();
00276 }
00277 
00278 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 PxBounds3::boundsOfPoints(const PxVec3& v0, const PxVec3& v1)
00279 {
00280     return PxBounds3(v0.minimum(v1), v0.maximum(v1));
00281 }
00282 
00283 PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3 PxBounds3::centerExtents(const PxVec3& center, const PxVec3& extent)
00284 {
00285     return PxBounds3(center - extent, center + extent);
00286 }
00287 
00288 PX_CUDA_CALLABLE PX_INLINE PxBounds3
00289 PxBounds3::basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent)
00290 {
00291     // extended basis vectors
00292     PxVec3 c0 = basis.column0 * extent.x;
00293     PxVec3 c1 = basis.column1 * extent.y;
00294     PxVec3 c2 = basis.column2 * extent.z;
00295 
00296     PxVec3 w;
00297     // find combination of base vectors that produces max. distance for each component = sum of abs()
00298     w.x = PxAbs(c0.x) + PxAbs(c1.x) + PxAbs(c2.x);
00299     w.y = PxAbs(c0.y) + PxAbs(c1.y) + PxAbs(c2.y);
00300     w.z = PxAbs(c0.z) + PxAbs(c1.z) + PxAbs(c2.z);
00301 
00302     return PxBounds3(center - w, center + w);
00303 }
00304 
00305 PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::poseExtent(const PxTransform& pose, const PxVec3& extent)
00306 {
00307     return basisExtent(pose.p, PxMat33(pose.q), extent);
00308 }
00309 
00310 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::setEmpty()
00311 {
00312     minimum = PxVec3(PX_MAX_BOUNDS_EXTENTS);
00313     maximum = PxVec3(-PX_MAX_BOUNDS_EXTENTS);
00314 }
00315 
00316 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::setMaximal()
00317 {
00318     minimum = PxVec3(-PX_MAX_BOUNDS_EXTENTS);
00319     maximum = PxVec3(PX_MAX_BOUNDS_EXTENTS);
00320 }
00321 
00322 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxVec3& v)
00323 {
00324     PX_ASSERT(isValid());
00325     minimum = minimum.minimum(v);
00326     maximum = maximum.maximum(v);
00327 }
00328 
00329 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxBounds3& b)
00330 {
00331     PX_ASSERT(isValid());
00332     minimum = minimum.minimum(b.minimum);
00333     maximum = maximum.maximum(b.maximum);
00334 }
00335 
00336 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isEmpty() const
00337 {
00338     PX_ASSERT(isValid());
00339     return minimum.x > maximum.x;
00340 }
00341 
00342 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects(const PxBounds3& b) const
00343 {
00344     PX_ASSERT(isValid() && b.isValid());
00345     return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y || minimum.y > b.maximum.y ||
00346              b.minimum.z > maximum.z || minimum.z > b.maximum.z);
00347 }
00348 
00349 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects1D(const PxBounds3& a, uint32_t axis) const
00350 {
00351     PX_ASSERT(isValid() && a.isValid());
00352     return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis];
00353 }
00354 
00355 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::contains(const PxVec3& v) const
00356 {
00357     PX_ASSERT(isValid());
00358 
00359     return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y || v.z < minimum.z ||
00360              v.z > maximum.z);
00361 }
00362 
00363 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isInside(const PxBounds3& box) const
00364 {
00365     PX_ASSERT(isValid() && box.isValid());
00366     if(box.minimum.x > minimum.x)
00367         return false;
00368     if(box.minimum.y > minimum.y)
00369         return false;
00370     if(box.minimum.z > minimum.z)
00371         return false;
00372     if(box.maximum.x < maximum.x)
00373         return false;
00374     if(box.maximum.y < maximum.y)
00375         return false;
00376     if(box.maximum.z < maximum.z)
00377         return false;
00378     return true;
00379 }
00380 
00381 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getCenter() const
00382 {
00383     PX_ASSERT(isValid());
00384     return (minimum + maximum) * 0.5f;
00385 }
00386 
00387 PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getCenter(uint32_t axis) const
00388 {
00389     PX_ASSERT(isValid());
00390     return (minimum[axis] + maximum[axis]) * 0.5f;
00391 }
00392 
00393 PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getExtents(uint32_t axis) const
00394 {
00395     PX_ASSERT(isValid());
00396     return (maximum[axis] - minimum[axis]) * 0.5f;
00397 }
00398 
00399 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getDimensions() const
00400 {
00401     PX_ASSERT(isValid());
00402     return maximum - minimum;
00403 }
00404 
00405 PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getExtents() const
00406 {
00407     PX_ASSERT(isValid());
00408     return getDimensions() * 0.5f;
00409 }
00410 
00411 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleSafe(float scale)
00412 {
00413     PX_ASSERT(isValid());
00414     if(!isEmpty())
00415         scaleFast(scale);
00416 }
00417 
00418 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleFast(float scale)
00419 {
00420     PX_ASSERT(isValid());
00421     *this = centerExtents(getCenter(), getExtents() * scale);
00422 }
00423 
00424 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenSafe(float distance)
00425 {
00426     PX_ASSERT(isValid());
00427     if(!isEmpty())
00428         fattenFast(distance);
00429 }
00430 
00431 PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenFast(float distance)
00432 {
00433     PX_ASSERT(isValid());
00434     minimum.x -= distance;
00435     minimum.y -= distance;
00436     minimum.z -= distance;
00437 
00438     maximum.x += distance;
00439     maximum.y += distance;
00440     maximum.z += distance;
00441 }
00442 
00443 PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxMat33& matrix, const PxBounds3& bounds)
00444 {
00445     PX_ASSERT(bounds.isValid());
00446     return !bounds.isEmpty() ? transformFast(matrix, bounds) : bounds;
00447 }
00448 
00449 PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxMat33& matrix, const PxBounds3& bounds)
00450 {
00451     PX_ASSERT(bounds.isValid());
00452     return PxBounds3::basisExtent(matrix * bounds.getCenter(), matrix, bounds.getExtents());
00453 }
00454 
00455 PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxTransform& transform, const PxBounds3& bounds)
00456 {
00457     PX_ASSERT(bounds.isValid());
00458     return !bounds.isEmpty() ? transformFast(transform, bounds) : bounds;
00459 }
00460 
00461 PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxTransform& transform, const PxBounds3& bounds)
00462 {
00463     PX_ASSERT(bounds.isValid());
00464     return PxBounds3::basisExtent(transform.transform(bounds.getCenter()), PxMat33(transform.q), bounds.getExtents());
00465 }
00466 
00467 PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isValid() const
00468 {
00469     return (isFinite() && (((minimum.x <= maximum.x) && (minimum.y <= maximum.y) && (minimum.z <= maximum.z)) ||
00470                            ((minimum.x == PX_MAX_BOUNDS_EXTENTS) && (minimum.y == PX_MAX_BOUNDS_EXTENTS) &&
00471                             (minimum.z == PX_MAX_BOUNDS_EXTENTS) && (maximum.x == -PX_MAX_BOUNDS_EXTENTS) &&
00472                             (maximum.y == -PX_MAX_BOUNDS_EXTENTS) && (maximum.z == -PX_MAX_BOUNDS_EXTENTS))));
00473 }
00474 
00475 #if !PX_DOXYGEN
00476 } // namespace physx
00477 #endif
00478 
00480 #endif // #ifndef PXFOUNDATION_PXBOUNDS3_H


Copyright © 2008-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com