RavEngine
Loading...
Searching...
No Matches
BpBroadPhaseIntegerAABB.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 BP_BROADPHASE_INTEGER_AABB_H
30#define BP_BROADPHASE_INTEGER_AABB_H
31
32#include "BpFiltering.h"
33#include "foundation/PxBounds3.h"
34#include "foundation/PxUnionCast.h"
35
36namespace physx
37{
38namespace Bp
39{
40
41 /*
42 \brief Encode a single float value with lossless encoding to integer
43 */
44 PX_FORCE_INLINE PxU32 encodeFloat(PxU32 ir)
45 {
46 //we may need to check on -0 and 0
47 //But it should make no practical difference.
48 if(ir & PX_SIGN_BITMASK) //negative?
49 return ~ir;//reverse sequence of negative numbers
50 else
51 return ir | PX_SIGN_BITMASK; // flip sign
52 }
53
54 /*
55 \brief Encode a single float value with lossless encoding to integer
56 */
57 PX_FORCE_INLINE PxU32 decodeFloat(PxU32 ir)
58 {
59 if(ir & PX_SIGN_BITMASK) //positive?
60 return ir & ~PX_SIGN_BITMASK; //flip sign
61 else
62 return ~ir; //undo reversal
63 }
64
65
71typedef PxU32 ValType;
72
74{
75public:
76
77 enum
78 {
79 MIN_X = 0,
80 MIN_Y,
81 MIN_Z,
82 MAX_X,
83 MAX_Y,
84 MAX_Z
85 };
86
87 IntegerAABB(const PxBounds3& b, PxReal contactDistance)
88 {
89 const PxVec3 dist(contactDistance);
90 encode(PxBounds3(b.minimum - dist, b.maximum + dist));
91 }
92
93 /*
94 \brief Return the minimum along a specified axis
95 \param[in] i is the axis
96 */
97 PX_FORCE_INLINE ValType getMin(PxU32 i) const { return (mMinMax)[MIN_X+i]; }
98
99 /*
100 \brief Return the maximum along a specified axis
101 \param[in] i is the axis
102 */
103 PX_FORCE_INLINE ValType getMax(PxU32 i) const { return (mMinMax)[MAX_X+i]; }
104
105 /*
106 \brief Return one of the six min/max values of the bound
107 \param[in] isMax determines whether a min or max value is returned
108 \param[in] index is the axis
109 */
110 PX_FORCE_INLINE ValType getExtent(PxU32 isMax, PxU32 index) const
111 {
112 PX_ASSERT(isMax<=1);
113 return (mMinMax)[3*isMax+index];
114 }
115
116 /*
117 \brief Return the minimum on the x axis
118 */
119 PX_FORCE_INLINE ValType getMinX() const { return mMinMax[MIN_X]; }
120
121 /*
122 \brief Return the minimum on the y axis
123 */
124 PX_FORCE_INLINE ValType getMinY() const { return mMinMax[MIN_Y]; }
125
126 /*
127 \brief Return the minimum on the z axis
128 */
129 PX_FORCE_INLINE ValType getMinZ() const { return mMinMax[MIN_Z]; }
130
131 /*
132 \brief Return the maximum on the x axis
133 */
134 PX_FORCE_INLINE ValType getMaxX() const { return mMinMax[MAX_X]; }
135
136 /*
137 \brief Return the maximum on the y axis
138 */
139 PX_FORCE_INLINE ValType getMaxY() const { return mMinMax[MAX_Y]; }
140
141 /*
142 \brief Return the maximum on the z axis
143 */
144 PX_FORCE_INLINE ValType getMaxZ() const { return mMinMax[MAX_Z]; }
145
146 /*
147 \brief Encode float bounds so they are stored as integer bounds
148 \param[in] bounds is the bounds to be encoded
149 \note The integer values of minima are always even, while the integer values of maxima are always odd
150 \note The encoding process masks off the last four bits for minima and masks on the last four bits for maxima.
151 This keeps the bounds constant when its shape is subjected to small global pose perturbations. In turn, this helps
152 reduce computational effort in the broadphase update by reducing the amount of sorting required on near-stationary
153 bodies that are aligned along one or more axis.
154 @see decode
155 */
156 PX_FORCE_INLINE void encode(const PxBounds3& bounds)
157 {
158 const PxU32* PX_RESTRICT min = PxUnionCast<const PxU32*, const PxF32*>(&bounds.minimum.x);
159 const PxU32* PX_RESTRICT max = PxUnionCast<const PxU32*, const PxF32*>(&bounds.maximum.x);
160 //Avoid min=max by enforcing the rule that mins are even and maxs are odd.
161 mMinMax[MIN_X] = encodeFloatMin(min[0]);
162 mMinMax[MIN_Y] = encodeFloatMin(min[1]);
163 mMinMax[MIN_Z] = encodeFloatMin(min[2]);
164 mMinMax[MAX_X] = encodeFloatMax(max[0]) | (1<<2);
165 mMinMax[MAX_Y] = encodeFloatMax(max[1]) | (1<<2);
166 mMinMax[MAX_Z] = encodeFloatMax(max[2]) | (1<<2);
167 }
168
169 /*
170 \brief Decode from integer bounds to float bounds
171 \param[out] bounds is the decoded float bounds
172 \note Encode followed by decode will produce a float bound larger than the original
173 due to the masking in encode.
174 @see encode
175 */
176 PX_FORCE_INLINE void decode(PxBounds3& bounds) const
177 {
178 PxU32* PX_RESTRICT min = PxUnionCast<PxU32*, PxF32*>(&bounds.minimum.x);
179 PxU32* PX_RESTRICT max = PxUnionCast<PxU32*, PxF32*>(&bounds.maximum.x);
180 min[0] = decodeFloat(mMinMax[MIN_X]);
181 min[1] = decodeFloat(mMinMax[MIN_Y]);
182 min[2] = decodeFloat(mMinMax[MIN_Z]);
183 max[0] = decodeFloat(mMinMax[MAX_X]);
184 max[1] = decodeFloat(mMinMax[MAX_Y]);
185 max[2] = decodeFloat(mMinMax[MAX_Z]);
186 }
187
188 /*
189 \brief Encode a single minimum value from integer bounds to float bounds
190 \note The encoding process masks off the last four bits for minima
191 @see encode
192 */
193 static PX_FORCE_INLINE ValType encodeFloatMin(PxU32 source)
194 {
195 return ((encodeFloat(source) >> eGRID_SNAP_VAL) - 1) << eGRID_SNAP_VAL;
196 }
197
198 /*
199 \brief Encode a single maximum value from integer bounds to float bounds
200 \note The encoding process masks on the last four bits for maxima
201 @see encode
202 */
203 static PX_FORCE_INLINE ValType encodeFloatMax(PxU32 source)
204 {
205 return ((encodeFloat(source) >> eGRID_SNAP_VAL) + 1) << eGRID_SNAP_VAL;
206 }
207
208 /*
209 \brief Shift the encoded bounds by a specified vector
210 \param[in] shift is the vector used to shift the bounds
211 */
212 PX_FORCE_INLINE void shift(const PxVec3& shift)
213 {
214 ::physx::PxBounds3 elemBounds;
215 decode(elemBounds);
216 elemBounds.minimum -= shift;
217 elemBounds.maximum -= shift;
218 encode(elemBounds);
219 }
220
221 /*
222 \brief Test if this aabb lies entirely inside another aabb
223 \param[in] box is the other box
224 \return True if this aabb lies entirely inside box
225 */
226 PX_INLINE bool isInside(const IntegerAABB& box) const
227 {
228 if(box.mMinMax[MIN_X]>mMinMax[MIN_X]) return false;
229 if(box.mMinMax[MIN_Y]>mMinMax[MIN_Y]) return false;
230 if(box.mMinMax[MIN_Z]>mMinMax[MIN_Z]) return false;
231 if(box.mMinMax[MAX_X]<mMinMax[MAX_X]) return false;
232 if(box.mMinMax[MAX_Y]<mMinMax[MAX_Y]) return false;
233 if(box.mMinMax[MAX_Z]<mMinMax[MAX_Z]) return false;
234 return true;
235 }
236
237 /*
238 \brief Test if this aabb and another intersect
239 \param[in] b is the other box
240 \return True if this aabb and b intersect
241 */
242 PX_FORCE_INLINE bool intersects(const IntegerAABB& b) const
243 {
244 return !(b.mMinMax[MIN_X] > mMinMax[MAX_X] || mMinMax[MIN_X] > b.mMinMax[MAX_X] ||
245 b.mMinMax[MIN_Y] > mMinMax[MAX_Y] || mMinMax[MIN_Y] > b.mMinMax[MAX_Y] ||
246 b.mMinMax[MIN_Z] > mMinMax[MAX_Z] || mMinMax[MIN_Z] > b.mMinMax[MAX_Z]);
247 }
248
249 PX_FORCE_INLINE bool intersects1D(const IntegerAABB& b, const PxU32 axis) const
250 {
251 const PxU32 maxAxis = axis + 3;
252 return !(b.mMinMax[axis] > mMinMax[maxAxis] || mMinMax[axis] > b.mMinMax[maxAxis]);
253 }
254
255
256 /*
257 \brief Expand bounds to include another
258 \note This is used to compute the aggregate bounds of multiple shape bounds
259 \param[in] b is the bounds to be included
260 */
261 PX_FORCE_INLINE void include(const IntegerAABB& b)
262 {
263 mMinMax[MIN_X] = PxMin(mMinMax[MIN_X], b.mMinMax[MIN_X]);
264 mMinMax[MIN_Y] = PxMin(mMinMax[MIN_Y], b.mMinMax[MIN_Y]);
265 mMinMax[MIN_Z] = PxMin(mMinMax[MIN_Z], b.mMinMax[MIN_Z]);
266 mMinMax[MAX_X] = PxMax(mMinMax[MAX_X], b.mMinMax[MAX_X]);
267 mMinMax[MAX_Y] = PxMax(mMinMax[MAX_Y], b.mMinMax[MAX_Y]);
268 mMinMax[MAX_Z] = PxMax(mMinMax[MAX_Z], b.mMinMax[MAX_Z]);
269 }
270
271 /*
272 \brief Set the bounds to (max, max, max), (min, min, min)
273 */
275 {
276 mMinMax[MIN_X] = mMinMax[MIN_Y] = mMinMax[MIN_Z] = 0xff7fffff; //PX_IR(PX_MAX_F32);
277 mMinMax[MAX_X] = mMinMax[MAX_Y] = mMinMax[MAX_Z] = 0x00800000;
278 }
279
280 ValType mMinMax[6];
281
282private:
283
284 enum
285 {
286 eGRID_SNAP_VAL = 4
287 };
288};
289
290PX_FORCE_INLINE ValType encodeMin(const PxBounds3& bounds, PxU32 axis, PxReal contactDistance)
291{
292 const PxReal val = bounds.minimum[axis] - contactDistance;
293 const PxU32 min = PxUnionCast<PxU32, PxF32>(val);
294 const PxU32 m = IntegerAABB::encodeFloatMin(min);
295 return m;
296}
297
298PX_FORCE_INLINE ValType encodeMax(const PxBounds3& bounds, PxU32 axis, PxReal contactDistance)
299{
300 const PxReal val = bounds.maximum[axis] + contactDistance;
301 const PxU32 max = PxUnionCast<PxU32, PxF32>(val);
302 const PxU32 m = IntegerAABB::encodeFloatMax(max) | (1<<2);
303 return m;
304}
305
306} //namespace Bp
307
308} //namespace physx
309
310#endif
Definition BpBroadPhaseIntegerAABB.h:74
PX_INLINE void setEmpty()
Definition BpBroadPhaseIntegerAABB.h:274
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
3 Element vector class.
Definition PxVec3.h:50
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#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 T PxMax(T a, T b)
The return value is the greater of the two specified values.
Definition PxMath.h:72
PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMin(T a, T b)
The return value is the lesser of the two specified values.
Definition PxMath.h:88