RavEngine
Loading...
Searching...
No Matches
GuBounds.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 GU_BOUNDS_H
30#define GU_BOUNDS_H
31
32#include "foundation/PxBounds3.h"
33#include "foundation/PxFlags.h"
34#include "foundation/PxVecMath.h"
35#include "geometry/PxGeometry.h"
36#include "geometry/PxCapsuleGeometry.h"
37#include <stddef.h>
38#include "GuBox.h"
39#include "GuCenterExtents.h"
40#include "GuSphere.h"
41#include "GuCapsule.h"
42
43// PT: the PX_MAX_BOUNDS_EXTENTS value is too large and produces INF floats when the box values are squared in
44// some collision routines. Thus, for the SQ subsystem we use this alternative (smaller) value to mark empty bounds.
45// See PX-954 for details.
46#define GU_EMPTY_BOUNDS_EXTENTS PxSqrt(0.25f * 1e33f)
47
48namespace physx
49{
50namespace Gu
51{
52 PX_FORCE_INLINE void computeCapsuleBounds(PxBounds3& bounds, const PxCapsuleGeometry& capsuleGeom, const PxTransform& pose, float contactOffset=0.0f, float inflation=1.0f)
53 {
54 const PxVec3 d = pose.q.getBasisVector0();
55 PxVec3 extents;
56 for(PxU32 ax = 0; ax<3; ax++)
57 extents[ax] = (PxAbs(d[ax]) * capsuleGeom.halfHeight + capsuleGeom.radius + contactOffset)*inflation;
58 bounds.minimum = pose.p - extents;
59 bounds.maximum = pose.p + extents;
60 }
61
62 //'contactOffset' and 'inflation' should not be used at the same time, i.e. either contactOffset==0.0f, or inflation==1.0f
63 PX_PHYSX_COMMON_API void computeBounds(PxBounds3& bounds, const PxGeometry& geometry, const PxTransform& transform, float contactOffset, float inflation); //AABB in world space.
64
65 PX_FORCE_INLINE PxBounds3 computeBounds(const PxGeometry& geometry, const PxTransform& pose)
66 {
67 PxBounds3 bounds;
68 computeBounds(bounds, geometry, pose, 0.0f, 1.0f);
69 return bounds;
70 }
71
72 void computeGlobalBox(PxBounds3& bounds, PxU32 nbPrims, const PxBounds3* PX_RESTRICT boxes, const PxU32* PX_RESTRICT primitives);
73
74 PX_PHYSX_COMMON_API void computeBoundsAroundVertices(PxBounds3& bounds, PxU32 nbVerts, const PxVec3* PX_RESTRICT verts);
75 PX_PHYSX_COMMON_API void computeLocalBoundsAndGeomEpsilon(const PxVec3* vertices, PxU32 nbVerties, PxBounds3& localBounds, PxReal& geomEpsilon);
76
77 #define StoreBounds(bounds, minV, maxV) \
78 V4StoreU(minV, &bounds.minimum.x); \
79 PX_ALIGN(16, PxVec4) max4; \
80 V4StoreA(maxV, &max4.x); \
81 bounds.maximum = PxVec3(max4.x, max4.y, max4.z);
82
83 // PT: TODO: - refactor with "inflateBounds" in GuBounds.cpp if possible
84 template<const bool useSIMD>
85 PX_FORCE_INLINE void inflateBounds(PxBounds3& dst, const PxBounds3& src, float enlargement)
86 {
87 const float coeff = 0.5f * enlargement;
88 if(useSIMD)
89 {
90 using namespace physx::aos;
91
92 Vec4V minV = V4LoadU(&src.minimum.x);
93 Vec4V maxV = V4LoadU(&src.maximum.x);
94 const Vec4V eV = V4Scale(V4Sub(maxV, minV), FLoad(coeff));
95
96 minV = V4Sub(minV, eV);
97 maxV = V4Add(maxV, eV);
98
99 StoreBounds(dst, minV, maxV);
100 }
101 else
102 {
103 // PT: this clumsy but necessary second codepath is used to read the last bound of the array
104 // (making sure we don't V4LoadU invalid memory). Implementation must stay in sync with the
105 // main codepath above. No, this is not very nice.
106 const PxVec3& minV = src.minimum;
107 const PxVec3& maxV = src.maximum;
108 const PxVec3 eV = (maxV - minV) * coeff;
109 dst.minimum = minV - eV;
110 dst.maximum = maxV + eV;
111 }
112 }
113
115 {
116 public:
117
118 PX_PHYSX_COMMON_API ShapeData(const PxGeometry& g, const PxTransform& t, PxReal inflation);
119
120 // PT: used by overlaps (box, capsule, convex)
121 PX_FORCE_INLINE const PxVec3& getPrunerBoxGeomExtentsInflated() const { return mPrunerBoxGeomExtents; }
122
123 // PT: used by overlaps (box, capsule, convex)
124 PX_FORCE_INLINE const PxVec3& getPrunerWorldPos() const { return mGuBox.center; }
125
126 PX_FORCE_INLINE const PxBounds3& getPrunerInflatedWorldAABB() const { return mPrunerInflatedAABB; }
127
128 // PT: used by overlaps (box, capsule, convex)
129 PX_FORCE_INLINE const PxMat33& getPrunerWorldRot33() const { return mGuBox.rot; }
130
131 // PT: this one only used by overlaps so far (for sphere shape, pruner level)
132 PX_FORCE_INLINE const Gu::Sphere& getGuSphere() const
133 {
134 PX_ASSERT(mType == PxGeometryType::eSPHERE);
135 return reinterpret_cast<const Gu::Sphere&>(mGuSphere);
136 }
137
138 // PT: this one only used by sweeps so far (for box shape, NP level)
139 PX_FORCE_INLINE const Gu::Box& getGuBox() const
140 {
141 PX_ASSERT(mType == PxGeometryType::eBOX);
142 return mGuBox;
143 }
144
145 // PT: this one used by sweeps (NP level) and overlaps (pruner level) - for capsule shape
146 PX_FORCE_INLINE const Gu::Capsule& getGuCapsule() const
147 {
148 PX_ASSERT(mType == PxGeometryType::eCAPSULE);
149 return reinterpret_cast<const Gu::Capsule&>(mGuCapsule);
150 }
151
152 PX_FORCE_INLINE float getCapsuleHalfHeight() const
153 {
154 PX_ASSERT(mType == PxGeometryType::eCAPSULE);
155 return mGuBox.extents.x;
156 }
157
158 PX_FORCE_INLINE PxU32 isOBB() const { return PxU32(mIsOBB); }
159 PX_FORCE_INLINE PxGeometryType::Enum getType() const { return PxGeometryType::Enum(mType); }
160
161 PX_NOCOPY(ShapeData)
162 private:
163
164 // PT: box: pre-inflated box extents
165 // capsule: pre-inflated extents of box-around-capsule
166 // convex: pre-inflated extents of box-around-convex
167 // sphere: not used
168 PxVec3 mPrunerBoxGeomExtents; // used for pruners. This volume encloses but can differ from the original shape
169
170 // PT:
171 //
172 // box center = unchanged copy of initial shape's position, except for convex (position of box around convex)
173 // SIMD code will load it as a V4 (safe because member is not last of Gu structure)
174 //
175 // box rot = precomputed PxMat33 version of initial shape's rotation, except for convex (rotation of box around convex)
176 // SIMD code will load it as V4s (safe because member is not last of Gu structure)
177 //
178 // box extents = non-inflated initial box extents for box shape, half-height for capsule, otherwise not used
179 Gu::Box mGuBox;
180
181 PxBounds3 mPrunerInflatedAABB; // precomputed AABB for the pruner shape
182 PxU16 mIsOBB; // true for OBB, false for AABB. Also used as padding for mPrunerInflatedAABB, don't move.
183 PxU16 mType; // shape's type
184
185 // these union Gu shapes are only precomputed for narrow phase (not pruners), can be different from mPrunerVolume
186 // so need separate storage
187 union
188 {
189 PxU8 mGuCapsule[sizeof(Gu::Capsule)]; // 28
190 PxU8 mGuSphere[sizeof(Gu::Sphere)]; // 16
191 };
192 };
193
194// PT: please make sure it fits in "one" cache line
196
197} // namespace Gu
198
199}
200#endif
Represents an oriented bounding box.
Definition GuBox.h:72
Represents a capsule.
Definition GuCapsule.h:47
Definition GuBounds.h:115
Definition GuSphere.h:46
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
A geometry object.
Definition PxGeometry.h:79
3x3 matrix class
Definition PxMat33.h:91
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T minimum(const PxVec3T &v) const
element-wise minimum
Definition PxVec3.h:341
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T maximum(const PxVec3T &v) const
element-wise maximum
Definition PxVec3.h:357
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
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_COMPILE_TIME_ASSERT(exp)
Definition PxPreprocessor.h:428
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
Enum
Definition PxGeometry.h:52
Definition PxVecMathAoSScalar.h:65