RavEngine
Loading...
Searching...
No Matches
BpAABBManagerBase.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_AABBMANAGER_BASE_H
30#define BP_AABBMANAGER_BASE_H
31
32#include "foundation/PxPinnedArray.h"
33#include "foundation/PxBitMap.h"
34#include "foundation/PxSList.h"
35#include "foundation/PxBitUtils.h"
36#include "BpVolumeData.h"
37#include "BpBroadPhaseUpdate.h"
38#include "GuBounds.h"
39#include "PxFiltering.h"
40#include "PxAggregate.h"
41
42namespace physx
43{
44class PxcScratchAllocator;
45class PxRenderOutput;
46class PxBaseTask;
47
48namespace Cm
49{
50 class FlushPool;
51}
52
53namespace Bp
54{
55 typedef PxU32 BoundsIndex;
56 //typedef PxU32 ActorHandle;
57
64 {
66 PX_FORCE_INLINE AABBOverlap(void* userData0, void* userData1/*, ActorHandle pairHandle*/) : mUserData0(userData0), mUserData1(userData1)/*, mPairHandle(pairHandle)*/
67 {
68 // PT: TODO: why is this forbidden?
69 PX_ASSERT(userData0 != userData1);
70 }
71
72 void* mUserData0;
73 void* mUserData1;
74 /* union
75 {
76 ActorHandle mPairHandle; //For created pairs, this is the index into the pair in the pair manager
77 void* mUserData; //For deleted pairs, this is the user data written by the application to the pair
78 };*/
79 void* mPairUserData; //For deleted pairs, this is the user data written by the application to the pair
80 };
81
82 struct BpCacheData : public PxSListEntry
83 {
84 PxArray<AABBOverlap> mCreatedPairs[2];
85 PxArray<AABBOverlap> mDeletedPairs[2];
86
87 void reset()
88 {
89 mCreatedPairs[0].resizeUninitialized(0);
90 mCreatedPairs[1].resizeUninitialized(0);
91 mDeletedPairs[0].resizeUninitialized(0);
92 mDeletedPairs[1].resizeUninitialized(0);
93 }
94 };
95
99
101 {
102 PX_NOCOPY(BoundsArray)
103 public:
104 BoundsArray(PxVirtualAllocator& allocator) : mBounds(allocator) {}
105
106 PX_FORCE_INLINE void initEntry(PxU32 index)
107 {
108 index++; // PT: always pretend we need one more entry, to make sure reading the last used entry will be SIMD-safe.
109 const PxU32 oldCapacity = mBounds.capacity();
110 if (index >= oldCapacity)
111 {
112 const PxU32 newCapacity = PxNextPowerOfTwo(index);
113 mBounds.reserve(newCapacity);
114 mBounds.forceSize_Unsafe(newCapacity);
115 }
116 }
117
118 PX_FORCE_INLINE void updateBounds(const PxTransform& transform, const PxGeometry& geom, PxU32 index)
119 {
120 Gu::computeBounds(mBounds[index], geom, transform, 0.0f, 1.0f);
121 mHasAnythingChanged = true;
122 }
123
124 PX_FORCE_INLINE void setBounds(const PxBounds3& bounds, PxU32 index)
125 {
126 // PX_CHECK_AND_RETURN(bounds.isValid() && !bounds.isEmpty(), "BoundsArray::setBounds - illegal bounds\n");
127 mBounds[index] = bounds;
128 mHasAnythingChanged = true;
129 }
130
131 PX_FORCE_INLINE const PxBounds3* begin() const { return mBounds.begin(); }
132 PX_FORCE_INLINE PxBounds3* begin() { return mBounds.begin(); }
133 PX_FORCE_INLINE PxBoundsArrayPinned& getBounds() { return mBounds; }
134 PX_FORCE_INLINE const PxBounds3& getBounds(PxU32 index) const { return mBounds[index]; }
135 PX_FORCE_INLINE PxU32 getCapacity() const { return mBounds.size(); }
136 PX_FORCE_INLINE bool hasChanged() const { return mHasAnythingChanged; }
137 PX_FORCE_INLINE void resetChangedState() { mHasAnythingChanged = false; }
138 PX_FORCE_INLINE void setChangedState() { mHasAnythingChanged = true; }
139
140 void shiftOrigin(const PxVec3& shift)
141 {
142 // we shift some potential NaNs here because we don't know what's active, but should be harmless
143 const PxU32 nbBounds = mBounds.size();
144 for(PxU32 i=0; i<nbBounds; i++)
145 {
146 mBounds[i].minimum -= shift;
147 mBounds[i].maximum -= shift;
148 }
149 mHasAnythingChanged = true;
150 }
151 private:
152 PxBoundsArrayPinned mBounds;
153 bool mHasAnythingChanged;
154 };
155
165 {
166 PX_NOCOPY(AABBManagerBase)
167 public:
168 AABBManagerBase(BroadPhase& bp, BoundsArray& boundsArray, PxFloatArrayPinned& contactDistance,
169 PxU32 maxNbAggregates, PxU32 maxNbShapes, PxVirtualAllocator& allocator, PxU64 contextID,
170 PxPairFilteringMode::Enum kineKineFilteringMode, PxPairFilteringMode::Enum staticKineFilteringMode);
171
172 virtual ~AABBManagerBase() {}
173
174 virtual void destroy() = 0;
175
176 virtual AggregateHandle createAggregate(BoundsIndex index, Bp::FilterGroup::Enum group, void* userData, PxU32 maxNumShapes, PxAggregateFilterHint filterHint) = 0;
177 virtual bool destroyAggregate(BoundsIndex& index, Bp::FilterGroup::Enum& group, AggregateHandle aggregateHandle) = 0;
178
179 virtual bool addBounds(BoundsIndex index, PxReal contactDistance, Bp::FilterGroup::Enum group, void* userdata, AggregateHandle aggregateHandle, ElementType::Enum volumeType) = 0;
180 virtual bool removeBounds(BoundsIndex index) = 0;
181
182 void reserveSpaceForBounds(BoundsIndex index);
183
184 PX_FORCE_INLINE PxIntBool isMarkedForRemove(BoundsIndex index) const { return mRemovedHandleMap.boundedTest(index); }
185// PX_FORCE_INLINE PxIntBool isMarkedForAdd(BoundsIndex index) const { return mAddedHandleMap.boundedTest(index); }
186 PX_FORCE_INLINE BroadPhase* getBroadPhase() const { return &mBroadPhase; }
187 PX_FORCE_INLINE BoundsArray& getBoundsArray() { return mBoundsArray; }
188 PX_FORCE_INLINE PxU32 getNbActiveAggregates() const { return mNbAggregates; }
189 PX_FORCE_INLINE const float* getContactDistances() const { return mContactDistance.begin(); }
190 PX_FORCE_INLINE PxBitMapPinned& getChangedAABBMgActorHandleMap() { return mChangedHandleMap; }
191 PX_FORCE_INLINE void* getUserData(const BoundsIndex index) const { return (index<mVolumeData.size()) ? mVolumeData[index].getUserData() : NULL; }
192
193 void setContactDistance(BoundsIndex handle, PxReal offset)
194 {
195 // PT: this works even for aggregated shapes, since the corresponding bit will also be set in the 'updated' map.
196 mContactDistance.begin()[handle] = offset;
197 setPersistentStateChanged();
198 mChangedHandleMap.growAndSet(handle);
199 }
200
201/* void setVolumeType(BoundsIndex handle, ElementType::Enum volumeType)
202 {
203 mVolumeData[handle].setVolumeType(volumeType);
204 }*/
205
206 void setBPGroup(BoundsIndex index, Bp::FilterGroup::Enum group)
207 {
208 PX_ASSERT((index + 1) < mVolumeData.size());
209 PX_ASSERT(group != Bp::FilterGroup::eINVALID); // PT: we use group == Bp::FilterGroup::eINVALID to mark removed/invalid entries
210 mGroups[index] = group;
211 }
212
213 virtual void updateBPFirstPass(PxU32 numCpuTasks, Cm::FlushPool& flushPool, bool hasContactDistanceUpdated, PxBaseTask* continuation) = 0;
214 virtual void updateBPSecondPass(PxU32 numCpuTasks, PxcScratchAllocator* scratchAllocator, PxBaseTask* continuation) = 0;
215
216 virtual void postBroadPhase(PxBaseTask*, Cm::FlushPool& flushPool) = 0;
217 virtual void reallocateChangedAABBMgActorHandleMap(const PxU32 size) = 0;
218
219 AABBOverlap* getCreatedOverlaps(ElementType::Enum type, PxU32& count)
220 {
221 PX_ASSERT(type < ElementType::eCOUNT);
222 count = mCreatedOverlaps[type].size();
223 return mCreatedOverlaps[type].begin();
224 }
225
226 AABBOverlap* getDestroyedOverlaps(ElementType::Enum type, PxU32& count)
227 {
228 PX_ASSERT(type < ElementType::eCOUNT);
229 count = mDestroyedOverlaps[type].size();
230 return mDestroyedOverlaps[type].begin();
231 }
232
233 void freeBuffers();
234
235 void** getOutOfBoundsObjects(PxU32& nbOutOfBoundsObjects)
236 {
237 nbOutOfBoundsObjects = mOutOfBoundsObjects.size();
238 return mOutOfBoundsObjects.begin();
239 }
240
241 void clearOutOfBoundsObjects()
242 {
243 mOutOfBoundsObjects.clear();
244 }
245
246 void** getOutOfBoundsAggregates(PxU32& nbOutOfBoundsAggregates)
247 {
248 nbOutOfBoundsAggregates = mOutOfBoundsAggregates.size();
249 return mOutOfBoundsAggregates.begin();
250 }
251
252 void clearOutOfBoundsAggregates()
253 {
254 mOutOfBoundsAggregates.clear();
255 }
256
257 void shiftOrigin(const PxVec3& shift);
258
259 virtual void visualize(PxRenderOutput& out) = 0;
260
261 virtual void releaseDeferredAggregateIds() = 0;
262 virtual void setGPUStateChanged() {}
263 virtual void setPersistentStateChanged() {}
264
265 protected:
266 void reserveShapeSpace(PxU32 nbShapes);
267
268 // PT: we have bitmaps here probably to quickly handle added/removed objects during same frame.
269 // PT: TODO: consider replacing with plain arrays (easier to parse, already existing below, etc)
270 PxBitMapPinned mAddedHandleMap; // PT: indexed by BoundsIndex
271 PxBitMapPinned mRemovedHandleMap; // PT: indexed by BoundsIndex
272 PxBitMapPinned mChangedHandleMap;
273
274 //Returns true if the bounds was pending insert, false otherwise
275 PX_FORCE_INLINE bool removeBPEntry(BoundsIndex index) // PT: only for objects passed to the BP
276 {
277 if (mAddedHandleMap.test(index)) // PT: if object had been added this frame...
278 {
279 mAddedHandleMap.reset(index); // PT: ...then simply revert the previous operation locally (it hasn't been passed to the BP yet).
280 return true;
281 }
282 else
283 mRemovedHandleMap.set(index); // PT: else we need to remove it from the BP
284 return false;
285 }
286
287 PX_FORCE_INLINE void addBPEntry(BoundsIndex index)
288 {
289 if (mRemovedHandleMap.test(index))
290 mRemovedHandleMap.reset(index);
291 else
292 mAddedHandleMap.set(index);
293 }
294
295 //ML: we create mGroups and mContactDistance in the AABBManager constructor. PxArray will take PxVirtualAllocator as a parameter. Therefore, if GPU BP is using,
296 //we will passed a pinned host memory allocator, otherwise, we will just pass a normal allocator.
297 GroupsArrayPinned mGroups; // NOTE: we stick Bp::FilterGroup::eINVALID in this slot to indicate that the entry is invalid (removed or never inserted.)
298 PxFloatArrayPinned& mContactDistance;
299 VolumeDataArrayPinned mVolumeData;
300 BpFilter mFilters;
301
302 PX_FORCE_INLINE void initEntry(BoundsIndex index, PxReal contactDistance, Bp::FilterGroup::Enum group, void* userData)
303 {
304 if ((index + 1) >= mVolumeData.size())
305 reserveShapeSpace(index + 1);
306
307 // PT: TODO: why is this needed at all? Why aren't size() and capacity() enough?
308 mUsedSize = PxMax(index + 1, mUsedSize);
309
310 PX_ASSERT(group != Bp::FilterGroup::eINVALID); // PT: we use group == Bp::FilterGroup::eINVALID to mark removed/invalid entries
311 mGroups[index] = group;
312 mContactDistance.begin()[index] = contactDistance;
313 mVolumeData[index].setUserData(userData);
314 }
315
316 PX_FORCE_INLINE void resetEntry(BoundsIndex index)
317 {
318 mGroups[index] = Bp::FilterGroup::eINVALID;
319 mContactDistance.begin()[index] = 0.0f;
320 mVolumeData[index].reset();
321 }
322
323 // PT: TODO: remove confusion between BoundsIndex and ShapeHandle here!
324 ShapeHandleArrayPinned mAddedHandles;
325 ShapeHandleArrayPinned mUpdatedHandles; // PT: TODO: only on CPU
326 ShapeHandleArrayPinned mRemovedHandles;
327
328 BroadPhase& mBroadPhase;
329 BoundsArray& mBoundsArray;
330
331 PxArray<void*> mOutOfBoundsObjects; // PT: TODO: only on CPU
332 PxArray<void*> mOutOfBoundsAggregates; // PT: TODO: only on CPU
333 PxArray<AABBOverlap> mCreatedOverlaps[ElementType::eCOUNT];
334 PxArray<AABBOverlap> mDestroyedOverlaps[ElementType::eCOUNT];
335
336 PxU32 mUsedSize; // highest used value + 1
337 PxU32 mNbAggregates;
338
339#ifdef BP_USE_AGGREGATE_GROUP_TAIL
340 // PT: TODO: even in the 3.4 trunk this stuff is a clumsy mess: groups are "BpHandle" suddenly passed
341 // to BroadPhaseUpdateData as "ShapeHandle".
342 //Free aggregate group ids.
343 PxU32 mAggregateGroupTide;
344 PxArray<Bp::FilterGroup::Enum> mFreeAggregateGroups; // PT: TODO: remove this useless array
345#endif
346 PxU64 mContextID;
347 bool mOriginShifted;
348
349#ifdef BP_USE_AGGREGATE_GROUP_TAIL
350 PX_FORCE_INLINE void releaseAggregateGroup(const Bp::FilterGroup::Enum group)
351 {
352 PX_ASSERT(group != Bp::FilterGroup::eINVALID);
353 mFreeAggregateGroups.pushBack(group);
354 }
355
356 PX_FORCE_INLINE Bp::FilterGroup::Enum getAggregateGroup()
357 {
358 PxU32 id;
359 if (mFreeAggregateGroups.size())
360 id = mFreeAggregateGroups.popBack();
361 else
362 {
363 id = mAggregateGroupTide--;
364 id <<= BP_FILTERING_TYPE_SHIFT_BIT;
365 id |= FilterType::AGGREGATE;
366 }
367 const Bp::FilterGroup::Enum group = Bp::FilterGroup::Enum(id);
368 PX_ASSERT(group != Bp::FilterGroup::eINVALID);
369 return group;
370 }
371#endif
372 };
373
374} //namespace Bp
375} //namespace physx
376
377#endif //BP_AABBMANAGER_BASE_H
A structure responsible for: storing an aabb representation for each active shape in the related scen...
Definition BpAABBManagerBase.h:165
Definition BpAABBManagerBase.h:101
Definition BpFiltering.h:119
Definition BpBroadPhase.h:99
Definition CmFlushPool.h:49
Definition PxArray.h:53
PX_FORCE_INLINE uint32_t size() const
Definition PxArray.h:242
PX_FORCE_INLINE void forceSize_Unsafe(uint32_t size)
Definition PxArray.h:507
PX_INLINE void reset()
Definition PxArray.h:460
PX_INLINE void clear()
Definition PxArray.h:250
PX_FORCE_INLINE ConstIterator begin() const
Definition PxArray.h:176
PX_FORCE_INLINE uint32_t capacity() const
Definition PxArray.h:497
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE void reserve(const uint32_t capacity)
Definition PxArray.h:486
PX_INLINE T popBack()
Definition PxArray.h:311
Base class of all task types.
Definition PxTask.h:45
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
A geometry object.
Definition PxGeometry.h:79
Definition PxRenderOutput.h:50
Definition PxSList.h:53
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
Definition PxAllocator.h:158
Definition PxcScratchAllocator.h:42
#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
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
Changes to the configuration of overlap pairs are reported as void* pairs.
Definition BpAABBManagerBase.h:64
Definition BpAABBManagerBase.h:83
Enum
Definition PxFiltering.h:717