RavEngine
Loading...
Searching...
No Matches
GuBucketPruner.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_BUCKET_PRUNER_H
30#define GU_BUCKET_PRUNER_H
31
32#include "common/PxPhysXCommonConfig.h"
33#include "GuPruner.h"
34#include "GuSqInternal.h"
35#include "GuPruningPool.h"
36#include "foundation/PxHash.h"
37
38#define FREE_PRUNER_SIZE 16
39//#define USE_REGULAR_HASH_MAP
40#ifdef USE_REGULAR_HASH_MAP
41 #include "foundation/PxHashMap.h"
42#endif
43
44namespace physx
45{
46 class PxRenderOutput;
47
48namespace Gu
49{
50 typedef PxU32 BucketWord;
51
52#if PX_VC
53 #pragma warning(push)
54 #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value.
55#endif
56
57 PX_ALIGN_PREFIX(16) struct BucketBox
58 {
59 PxVec3 mCenter;
60 PxU32 mData0; // Integer-encoded min value along sorting axis
61 PxVec3 mExtents;
62 PxU32 mData1; // Integer-encoded max value along sorting axis
63
64 #ifdef _DEBUG
65 // PT: we need the original min value for debug checks. Using the center/extents version
66 // fails because recomputing the min from them introduces FPU accuracy errors in the values.
67 float mDebugMin;
68 #endif
69
70 PX_FORCE_INLINE PxVec3 getMin() const
71 {
72 return mCenter - mExtents;
73 }
74
75 PX_FORCE_INLINE PxVec3 getMax() const
76 {
77 return mCenter + mExtents;
78 }
79
80 PX_FORCE_INLINE void setEmpty()
81 {
82 mCenter = PxVec3(0.0f);
83 mExtents = PxVec3(-PX_MAX_BOUNDS_EXTENTS);
84
85 #ifdef _DEBUG
86 mDebugMin = PX_MAX_BOUNDS_EXTENTS;
87 #endif
88 }
89 }PX_ALIGN_SUFFIX(16);
90
91 PX_ALIGN_PREFIX(16) struct BucketPrunerNode
92 {
93 BucketPrunerNode();
94
95 void classifyBoxes( float limitX, float limitZ,
96 PxU32 nb,
97 BucketBox* PX_RESTRICT boxes,
98 const PrunerPayload* PX_RESTRICT objects,
99 const PxTransform* PX_RESTRICT transforms,
100 BucketBox* PX_RESTRICT sortedBoxes,
101 PrunerPayload* PX_RESTRICT sortedObjects,
102 PxTransform* PX_RESTRICT sortedTransforms,
103 bool isCrossBucket, PxU32 sortAxis);
104
105 PX_FORCE_INLINE void initCounters()
106 {
107 for(PxU32 i=0;i<5;i++)
108 mCounters[i] = 0;
109 for(PxU32 i=0;i<5;i++)
110 mOffsets[i] = 0;
111 }
112
113 BucketWord mCounters[5]; // Number of objects in each of the 5 children
114 BucketWord mOffsets[5]; // Start index of objects for each of the 5 children
115 BucketBox mBucketBox[5]; // AABBs around objects for each of the 5 children
116 PxU16 mOrder[8]; // PNS: 5 children => 3 bits/index => 3*5=15 bits total, for each of the 8 canonical directions
117 }PX_ALIGN_SUFFIX(16);
118
119 PX_FORCE_INLINE PxU32 PxComputeHash(const PrunerPayload& payload)
120 {
121#if PX_P64_FAMILY
122// const PxU32 h0 = PxHash((const void*)payload.data[0]);
123// const PxU32 h1 = PxHash((const void*)payload.data[1]);
124 const PxU32 h0 = PxU32(PX_MAX_U32 & payload.data[0]);
125 const PxU32 h1 = PxU32(PX_MAX_U32 & payload.data[1]);
126 return physx::PxComputeHash(PxU64(h0)|(PxU64(h1)<<32));
127#else
128 return physx::PxComputeHash(PxU64(payload.data[0])|(PxU64(payload.data[1])<<32));
129#endif
130 }
131
132#ifdef USE_REGULAR_HASH_MAP
133 struct BucketPrunerPair : public PxUserAllocated
134 {
135 PX_FORCE_INLINE BucketPrunerPair() {}
136 PX_FORCE_INLINE BucketPrunerPair(PxU32 index, PxU32 stamp) : mCoreIndex(index), mTimeStamp(stamp) {}
137 PxU32 mCoreIndex; // index in mCoreObjects
138 PxU32 mTimeStamp;
139 };
140 typedef PxHashMap<PrunerPayload, BucketPrunerPair> BucketPrunerMap;
141#else
143 {
144 PrunerPayload mData;
145 PxU32 mCoreIndex; // index in mCoreObjects
146 PxU32 mTimeStamp;
147 };
148
149 // Custom hash-map - currently faster than the regular hash-map (PxHashMap), in particular for 'find-and-erase' operations.
151 {
152 public:
155
156 void purge();
157 void shrinkMemory();
158
159 BucketPrunerPair* addPair (const PrunerPayload& payload, PxU32 coreIndex, PxU32 timeStamp);
160 bool removePair (const PrunerPayload& payload, PxU32& coreIndex, PxU32& timeStamp);
161 const BucketPrunerPair* findPair (const PrunerPayload& payload) const;
162 PX_FORCE_INLINE PxU32 getPairIndex(const BucketPrunerPair* pair) const
163 {
164 return (PxU32((size_t(pair) - size_t(mActivePairs)))/sizeof(BucketPrunerPair));
165 }
166
167 PxU32 mHashSize;
168 PxU32 mMask;
169 PxU32 mNbActivePairs;
170 PxU32* mHashTable;
171 PxU32* mNext;
172 BucketPrunerPair* mActivePairs;
173 PxU32 mReservedMemory;
174
175 PX_FORCE_INLINE BucketPrunerPair* findPair(const PrunerPayload& payload, PxU32 hashValue) const;
176 void removePairInternal(const PrunerPayload& payload, PxU32 hashValue, PxU32 pairIndex);
177 void reallocPairs();
178 void reserveMemory(PxU32 memSize);
179 };
180#endif
181
183 {
184 public:
185 PX_PHYSX_COMMON_API BucketPrunerCore(bool externalMemory=true);
186 PX_PHYSX_COMMON_API ~BucketPrunerCore();
187
188 void release();
189
190 void setExternalMemory(PxU32 nbObjects, PxBounds3* boxes, PrunerPayload* objects, PxTransform* transforms);
191
192 PX_PHYSX_COMMON_API bool addObject(const PrunerPayload& object, const PxBounds3& worldAABB, const PxTransform& transform, PxU32 timeStamp=0);
193 bool removeObject(const PrunerPayload& object, PxU32& timeStamp);
194 bool updateObject(const PxBounds3& worldAABB, const PrunerPayload& object, const PxTransform& transform);
195
196 // PT: look for objects marked with input timestamp everywhere in the structure, and remove them. This is the same
197 // as calling 'removeObject' individually for all these objects, but much more efficient. Returns number of removed objects.
198 PxU32 removeMarkedObjects(PxU32 timeStamp);
199
200 PX_PHYSX_COMMON_API bool raycast(const PxVec3& origin, const PxVec3& unitDir, PxReal& inOutDistance, PrunerRaycastCallback&) const;
201 PX_PHYSX_COMMON_API bool overlap(const ShapeData& queryVolume, PrunerOverlapCallback&) const;
202 PX_PHYSX_COMMON_API bool sweep(const ShapeData& queryVolume, const PxVec3& unitDir, PxReal& inOutDistance, PrunerRaycastCallback&) const;
203
204 void getGlobalBounds(PxBounds3& bounds) const;
205
206 void shiftOrigin(const PxVec3& shift);
207
208 void visualize(PxRenderOutput& out, PxU32 color) const;
209
210 PX_FORCE_INLINE void build() { classifyBoxes(); }
211
212#ifdef FREE_PRUNER_SIZE
213 PX_FORCE_INLINE PxU32 getNbObjects() const { return mNbFree + mCoreNbObjects; }
214#else
215 PX_FORCE_INLINE PxU32 getNbObjects() const { return mCoreNbObjects; }
216#endif
217
218// private:
219 PxU32 mCoreNbObjects; // Current number of objects in core arrays
220 PxU32 mCoreCapacity; // Capacity of core arrays
221 PxBounds3* mCoreBoxes; // Core array
222 PrunerPayload* mCoreObjects; // Core array
223 PxTransform* mCoreTransforms;
224 PxU32* mCoreRemap; // Remaps core index to sorted index, i.e. sortedIndex = mCoreRemap[coreIndex]
225
226 BucketBox* mSortedWorldBoxes; // Sorted array
227 PrunerPayload* mSortedObjects; // Sorted array
228 PxTransform* mSortedTransforms;
229#ifdef FREE_PRUNER_SIZE
230 PxU32 mNbFree; // Current number of objects in the "free array" (mFreeObjects/mFreeBounds)
231 PrunerPayload mFreeObjects[FREE_PRUNER_SIZE]; // mNbFree objects are stored here
232 PxBounds3 mFreeBounds[FREE_PRUNER_SIZE]; // mNbFree object bounds are stored here
233 PxTransform mFreeTransforms[FREE_PRUNER_SIZE]; // mNbFree transforms are stored here
234 PxU32 mFreeStamps[FREE_PRUNER_SIZE];
235#endif
236 BucketPrunerMap mMap; // Maps (PrunerPayload) object to corresponding index in core array.
237 // Objects in the free array do not appear in this map.
238 PxU32 mSortedNb;
239 PxU32 mSortedCapacity;
240 PxU32 mSortAxis;
241
242 BucketBox mGlobalBox; // Global bounds around all objects in the structure (except the ones in the "free" array)
243 BucketPrunerNode mLevel1;
244 BucketPrunerNode mLevel2[5];
245 BucketPrunerNode mLevel3[5][5];
246
247 bool mDirty;
248 bool mOwnMemory;
249 private:
250 PX_PHYSX_COMMON_API void classifyBoxes();
251 void allocateSortedMemory(PxU32 nb);
252 void resizeCore();
253 PX_FORCE_INLINE void addObjectInternal(const PrunerPayload& object, const PxBounds3& worldAABB, const PxTransform& transform, PxU32 timeStamp);
254 };
255
256#if PX_VC
257 #pragma warning(pop)
258#endif
259
260 class BucketPruner : public Pruner
261 {
262 public:
263 PX_PHYSX_COMMON_API BucketPruner(PxU64 contextID);
264 virtual ~BucketPruner();
265
266 // BasePruner
267 DECLARE_BASE_PRUNER_API
268 //~BasePruner
269
270 // Pruner
271 DECLARE_PRUNER_API_COMMON
272 //~Pruner
273
274 private:
275 BucketPrunerCore mCore;
276 PruningPool mPool;
277 };
278
279}
280
281}
282
283#endif
Definition GuBucketPruner.h:183
Definition GuBucketPruner.h:151
Definition GuBucketPruner.h:261
Definition GuPruner.h:76
Definition GuPruningPool.h:55
Definition GuBounds.h:115
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
Definition PxRenderOutput.h:50
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
Definition PxUserAllocated.h:43
3 Element vector class.
Definition PxVec3.h:50
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
Definition GuBucketPruner.h:143
Definition GuPruner.h:55
Definition GuPrunerPayload.h:43
Definition GuPruner.h:47