RavEngine
Loading...
Searching...
No Matches
ScNPhaseCore.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 SC_NPHASE_CORE_H
30#define SC_NPHASE_CORE_H
31
32#include "common/PxRenderOutput.h"
33#include "foundation/PxHash.h"
34#include "foundation/PxUserAllocated.h"
35#include "foundation/PxHashSet.h"
36#include "foundation/PxHashMap.h"
37#include "foundation/PxMutex.h"
38#include "foundation/PxAtomic.h"
39#include "PxPhysXConfig.h"
40
41#include "foundation/PxPool.h"
42
43#include "PxSimulationEventCallback.h"
44#include "ScTriggerPairs.h"
45#include "ScScene.h"
46#include "ScContactReportBuffer.h"
47
48
49
50namespace physx
51{
52namespace Bp
53{
54 struct AABBOverlap;
55 struct BroadPhasePair;
56}
57
58namespace Sc
59{
60 class ActorSim;
61 class ElementSim;
62 class ShapeSimBase;
63
64 class Interaction;
65 class ElementSimInteraction;
66 class ElementInteractionMarker;
67 class TriggerInteraction;
68
69 class ShapeInteraction;
70 class ActorPair;
71 class ActorPairReport;
72
73 class ActorPairContactReportData;
74 struct ContactShapePair;
75
76 class NPhaseContext;
77 class ContactStreamManager;
78
79 struct FilterPair;
80 class FilterPairManager;
81
82 class ActorSim;
83
85 {
86 enum Enum
87 {
88 eRUN_LOST_TOUCH_LOGIC = (1 << 0), // run the lost-touch-logic for a pair that gets removed.
89 eWAKE_ON_LOST_TOUCH = (1 << 1) // a pair that lost touch should check whether the actors should get woken up
90 };
91 };
92
93 /*
94 Description: NPhaseCore encapsulates the near phase processing to allow multiple implementations(eg threading and non
95 threaded).
96
97 The broadphase inserts shape pairs into the NPhaseCore, which are then processed into contact point streams.
98 Pairs can then be processed into AxisConstraints by the GroupSolveCore.
99 */
100
102 {
103 PxU32 mSim0;
104 PxU32 mSim1;
105
106 PX_FORCE_INLINE bool operator == (const BodyPairKey& pair) const { return mSim0 == pair.mSim0 && mSim1 == pair.mSim1; }
107 };
108
109 PX_INLINE PxU32 PxComputeHash(const BodyPairKey& key)
110 {
111 const PxU32 add0 = key.mSim0;
112 const PxU32 add1 = key.mSim1;
113
114 const PxU32 base = PxU32((add0 & 0xFFFF) | (add1 << 16));
115
116 return physx::PxComputeHash(base);
117 }
118
120 {
121 ElementSim* mSim0, *mSim1;
122
123 ElementSimKey() : mSim0(NULL), mSim1(NULL)
124 {}
125
127 {
128 if(sim0 > sim1)
129 PxSwap(sim0, sim1);
130 mSim0 = sim0;
131 mSim1 = sim1;
132 }
133
134 PX_FORCE_INLINE bool operator == (const ElementSimKey& pair) const { return mSim0 == pair.mSim0 && mSim1 == pair.mSim1; }
135 };
136
137 PX_INLINE PxU32 PxComputeHash(const ElementSimKey& key)
138 {
139 PxU32 add0 = (size_t(key.mSim0)) & 0xFFFFFFFF;
140 PxU32 add1 = (size_t(key.mSim1)) & 0xFFFFFFFF;
141
142 //Clear the lower 2 bits, they will be 0s anyway
143 add0 = add0 >> 2;
144 add1 = add1 >> 2;
145
146 const PxU32 base = PxU32((add0 & 0xFFFF) | (add1 << 16));
147
148 return physx::PxComputeHash(base);
149 }
150
152 {
153 PxU8* mBuffer;
154 PxU32 mBufferSize;
155 PxU32 mCurrentBufferIndex;
156 PxU32 mCurrentOffset;
157 ContactReportBuffer& mReportBuffer;
158 PxMutex& mMutex;
159 const PxU32 mBuferBlockSize;
161 public:
162
163 ContactReportAllocationManager(ContactReportBuffer& buffer, PxMutex& mutex, const PxU32 bufferBlockSize = 16384) : mBuffer(NULL), mBufferSize(0), mCurrentBufferIndex(0),
164 mCurrentOffset(0), mReportBuffer(buffer), mMutex(mutex), mBuferBlockSize(bufferBlockSize)
165 {
166 }
167
168 PxU8* allocate(const PxU32 size, PxU32& index, PxU32 alignment = 16u)
169 {
170 //(1) fix up offsets...
171 PxU32 pad = ((mCurrentBufferIndex + alignment - 1)&~(alignment - 1)) - mCurrentBufferIndex;
172 PxU32 currOffset = mCurrentOffset + pad;
173
174 if ((currOffset + size) > mBufferSize)
175 {
176 const PxU32 allocSize = PxMax(size, mBuferBlockSize);
177
178 mMutex.lock();
179 mBuffer = mReportBuffer.allocateNotThreadSafe(allocSize, mCurrentBufferIndex, alignment);
180 mCurrentOffset = currOffset = 0;
181 mBufferSize = allocSize;
182 mMutex.unlock();
183 }
184
185 PxU8* ret = mBuffer + currOffset;
186 index = mCurrentBufferIndex + currOffset;
187 mCurrentOffset = currOffset + size;
188 return ret;
189 }
190 };
191
193 {
194 PX_NOCOPY(NPhaseCore)
195
196 public:
197 NPhaseCore(Scene& scene, const PxSceneDesc& desc);
198 ~NPhaseCore();
199
200 void onTriggerOverlapCreated(const Bp::AABBOverlap* PX_RESTRICT pairs, PxU32 pairCount);
201
202 void runOverlapFilters( PxU32 nbToProcess, const Bp::AABBOverlap* PX_RESTRICT pairs, PxFilterInfo* PX_RESTRICT filterInfo,
203 PxU32& nbToKeep, PxU32& nbToSuppress, PxU32& nbToCallback, PxU32* PX_RESTRICT keepMap, PxU32* PX_RESTRICT callbackMap);
204
205 ElementSimInteraction* onOverlapRemovedStage1(ElementSim* volume0, ElementSim* volume1);
206 void onOverlapRemoved(ElementSim* volume0, ElementSim* volume1, const PxU32 ccdPass, void* elemSim, PxsContactManagerOutputIterator& outputs);
207 void onVolumeRemoved(ElementSim* volume, PxU32 flags, PxsContactManagerOutputIterator& outputs);
208
209 void managerNewTouch(Sc::ShapeInteraction& interaction);
210
211 PxU32 getDefaultContactReportStreamBufferSize() const;
212
213 void fireCustomFilteringCallbacks(PxsContactManagerOutputIterator& outputs);
214
215 void addToDirtyInteractionList(Interaction* interaction);
216 void removeFromDirtyInteractionList(Interaction* interaction);
217 void updateDirtyInteractions(PxsContactManagerOutputIterator& outputs);
218
219 /*
220 Description: Perform trigger overlap tests.
221 */
222 void processTriggerInteractions(PxBaseTask* continuation);
223
224 /*
225 Description: Gather results from trigger overlap tests and clean up.
226 */
227 void mergeProcessedTriggerInteractions(PxBaseTask* continuation);
228
229 /*
230 Description: Check candidates for persistent touch contact events and create those events if necessary.
231 */
232 void processPersistentContactEvents(PxsContactManagerOutputIterator& outputs, PxBaseTask* continuation);
233
234 /*
235 Description: Displays visualizations associated with the near phase.
236 */
237 void visualize(PxRenderOutput& out, PxsContactManagerOutputIterator& outputs);
238
239 PX_FORCE_INLINE Scene& getScene() const { return mOwnerScene; }
240
241 PX_FORCE_INLINE void addToContactReportActorPairSet(ActorPairReport* pair) { mContactReportActorPairSet.pushBack(pair); }
242 void clearContactReportActorPairs(bool shrinkToZero);
243 PX_FORCE_INLINE PxU32 getNbContactReportActorPairs() const { return mContactReportActorPairSet.size(); }
244 PX_FORCE_INLINE ActorPairReport* const* getContactReportActorPairs() const { return mContactReportActorPairSet.begin(); }
245
246 void addToPersistentContactEventPairs(ShapeInteraction*);
247 void addToPersistentContactEventPairsDelayed(ShapeInteraction*);
248 void removeFromPersistentContactEventPairs(ShapeInteraction*);
249
250
251 PX_FORCE_INLINE PxU32 getCurrentPersistentContactEventPairCount() const { return mNextFramePersistentContactEventPairIndex; }
252 PX_FORCE_INLINE ShapeInteraction* const* getCurrentPersistentContactEventPairs() const { return mPersistentContactEventPairList.begin(); }
253 PX_FORCE_INLINE PxU32 getAllPersistentContactEventPairCount() const { return mPersistentContactEventPairList.size(); }
254 PX_FORCE_INLINE ShapeInteraction* const* getAllPersistentContactEventPairs() const { return mPersistentContactEventPairList.begin(); }
255 PX_FORCE_INLINE void preparePersistentContactEventListForNextFrame();
256
257 void addToForceThresholdContactEventPairs(ShapeInteraction*);
258 void removeFromForceThresholdContactEventPairs(ShapeInteraction*);
259
260
261 PX_FORCE_INLINE PxU32 getForceThresholdContactEventPairCount() const { return mForceThresholdContactEventPairList.size(); }
262 PX_FORCE_INLINE ShapeInteraction* const* getForceThresholdContactEventPairs() const { return mForceThresholdContactEventPairList.begin(); }
263
264 PX_FORCE_INLINE PxU8* getContactReportPairData(const PxU32& bufferIndex) const { return mContactReportBuffer.getData(bufferIndex); }
265 PxU8* reserveContactReportPairData(PxU32 pairCount, PxU32 extraDataSize, PxU32& bufferIndex, ContactReportAllocationManager* alloc = NULL);
266 PxU8* resizeContactReportPairData(PxU32 pairCount, PxU32 extraDataSize, Sc::ContactStreamManager& csm);
267 PX_FORCE_INLINE void clearContactReportStream() { mContactReportBuffer.reset(); } // Do not free memory at all
268 PX_FORCE_INLINE void freeContactReportStreamMemory() { mContactReportBuffer.flush(); }
269
270 ActorPairContactReportData* createActorPairContactReportData();
271 void releaseActorPairContactReportData(ActorPairContactReportData* data);
272
273 void reserveInteraction(PxU32 nbNewInteractions);
274 void registerInteraction(ElementSimInteraction* interaction);
275 void unregisterInteraction(ElementSimInteraction* interaction);
276
277 ElementSimInteraction* createRbElementInteraction(const PxFilterInfo& fInfo, ShapeSimBase& s0, ShapeSimBase& s1, PxsContactManager* contactManager, Sc::ShapeInteraction* shapeInteraction,
278 Sc::ElementInteractionMarker* interactionMarker, bool isTriggerPair);
279
280 void lockReports() { mReportAllocLock.lock(); }
281 void unlockReports() { mReportAllocLock.unlock(); }
282
283
284 private:
285 ElementSimInteraction* createTriggerElementInteraction(ShapeSimBase& s0, ShapeSimBase& s1);
286
287 //
288 // removedElement: points to the removed element (that is, the BP volume wrapper), if a pair gets removed or loses touch due to a removed element.
289 // NULL if not triggered by a removed element.
290 //
291 void releaseElementPair(ElementSimInteraction* pair, PxU32 flags, ElementSim* removedElement, const PxU32 ccdPass, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs);
292 void lostTouchReports(ShapeInteraction* pair, PxU32 flags, ElementSim* removedElement, const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs);
293
294 ShapeInteraction* createShapeInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags pairFlags, PxsContactManager* contactManager, Sc::ShapeInteraction* shapeInteraction);
295 TriggerInteraction* createTriggerInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags triggerFlags);
296 ElementInteractionMarker* createElementInteractionMarker(ElementSim& e0, ElementSim& e1, ElementInteractionMarker* marker);
297
298 //------------- Filtering -------------
299
300 ElementSimInteraction* refilterInteraction(ElementSimInteraction* pair, const PxFilterInfo* filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs);
301 //-------------------------------------
302
303 ElementSimInteraction* convert(ElementSimInteraction* pair, InteractionType::Enum type, PxFilterInfo& filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs);
304
305 ActorPair* findActorPair(ShapeSimBase* s0, ShapeSimBase* s1, PxIntBool isReportPair);
306 PX_FORCE_INLINE void destroyActorPairReport(ActorPairReport&);
307
308 Sc::ElementSimInteraction* findInteraction(ElementSim* _element0, ElementSim* _element1);
309
310 // Pooling
311 Scene& mOwnerScene;
312
313 PxArray<ActorPairReport*> mContactReportActorPairSet;
314 PxArray<ShapeInteraction*> mPersistentContactEventPairList; // Pairs which request events which do not get triggered by the sdk and thus need to be tested actively every frame.
315 // May also contain force threshold event pairs (see mForceThresholdContactEventPairList)
316 // This list is split in two, the elements in front are for the current frame, the elements at the
317 // back will get added next frame.
318
319
320 PxU32 mNextFramePersistentContactEventPairIndex; // start index of the pairs which need to get added to the persistent list for next frame
321
322 PxArray<ShapeInteraction*> mForceThresholdContactEventPairList; // Pairs which request force threshold contact events. A pair is only in this list if it does have contact.
323 // Note: If a pair additionally requests PxPairFlag::eNOTIFY_TOUCH_PERSISTS events, then it
324 // goes into mPersistentContactEventPairList instead. This allows to share the list index.
325
326
327 //
328 // data layout:
329 // ContactActorPair0_ExtraData, ContactShapePair0_0, ContactShapePair0_1, ... ContactShapePair0_N,
330 // ContactActorPair1_ExtraData, ContactShapePair1_0, ...
331 //
332 ContactReportBuffer mContactReportBuffer; // Shape pair information for contact reports
333
334 PxCoalescedHashSet<Interaction*> mDirtyInteractions;
335 FilterPairManager* mFilterPairManager;
336
337 // Pools
338 PxPool<ActorPair> mActorPairPool;
339 PxPool<ActorPairReport> mActorPairReportPool;
340 PxPool<ShapeInteraction> mShapeInteractionPool;
341 PxPool<TriggerInteraction> mTriggerInteractionPool;
342 PxPool<ActorPairContactReportData> mActorPairContactReportDataPool;
343 PxPool<ElementInteractionMarker> mInteractionMarkerPool;
344
346 void* mTmpTriggerProcessingBlock; // temporary memory block to process trigger pairs in parallel
347 PxMutex mTriggerWriteBackLock;
348 volatile PxI32 mTriggerPairsToDeactivateCount;
350
352
353 PxMutex mBufferAllocLock;
354 PxMutex mReportAllocLock;
355
356 friend class Sc::Scene;
357 friend class Sc::ShapeInteraction;
358 };
359
361 {
362 PX_NOCOPY(FilteringContext)
363 public:
364 FilteringContext(const Sc::Scene& scene, FilterPairManager* filterPairManager) :
365 mFilterShader (scene.getFilterShaderFast()),
366 mFilterShaderData (scene.getFilterShaderDataFast()),
367 mFilterShaderDataSize (scene.getFilterShaderDataSizeFast()),
368 mFilterCallback (scene.getFilterCallbackFast()),
369 mFilterPairManager (filterPairManager),
370 mKineKineFilteringMode (scene.getKineKineFilteringMode()),
371 mStaticKineFilteringMode(scene.getStaticKineFilteringMode())
372 {
373 }
374
375 PxSimulationFilterShader mFilterShader;
376 const void* mFilterShaderData;
377 PxU32 mFilterShaderDataSize;
378 PxSimulationFilterCallback* mFilterCallback;
379 FilterPairManager* mFilterPairManager;
380 const PxPairFilteringMode::Enum mKineKineFilteringMode;
381 const PxPairFilteringMode::Enum mStaticKineFilteringMode;
382 };
383
384 // helper function to run the filter logic after some hardwired filter criteria have been passed successfully
385 PxFilterInfo filterRbCollisionPairSecondStage(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, const Sc::ActorSim& b0, const Sc::ActorSim& b1, PxU32 filterPairIndex, bool runCallbacks,
386 bool isNonRigid);
387
388} // namespace Sc
389
390
391PX_FORCE_INLINE void Sc::NPhaseCore::preparePersistentContactEventListForNextFrame()
392{
393 // reports have been processed -> "activate" next frame candidates for persistent contact events
394 mNextFramePersistentContactEventPairIndex = mPersistentContactEventPairList.size();
395}
396
397}
398
399#endif
Definition ScNPhaseCore.cpp:58
Definition base.h:1940
Definition CmTask.h:90
Definition PxArray.h:53
Base class of all task types.
Definition PxTask.h:45
Definition PxHashSet.h:100
Definition PxHashMap.h:78
Definition PxMutex.h:89
PX_FORCE_INLINE void unlock() const
Definition PxMutex.h:149
PX_FORCE_INLINE void lock() const
Definition PxMutex.h:130
Definition PxPool.h:248
Definition PxRenderOutput.h:50
Descriptor class for scenes. See #PxScene.
Definition PxSceneDesc.h:426
Filter callback to specify handling of collision pairs.
Definition PxFiltering.h:633
Definition PxUserAllocated.h:43
Definition PxvNphaseImplementationContext.h:81
Definition PxsContactManager.h:77
Definition ScActorPair.h:45
Class shared by all shape interactions for a pair of actors if contact reports are requested.
Definition ScActorPair.h:110
Class shared by all shape interactions for a pair of actors.
Definition ScActorPair.h:69
Definition ScActorSim.h:83
Definition ScNPhaseCore.h:152
Definition ScContactReportBuffer.h:40
Contact report logic and data management.
Definition ScContactStream.h:125
Definition ScElementInteractionMarker.h:40
Definition ScElementSimInteraction.h:40
Definition ScElementSim.h:50
Definition ScInteraction.h:50
Definition ScNPhaseCore.h:193
Definition ScScene.h:240
Definition ScShapeInteraction.h:54
Definition ScShapeSimBase.h:54
Definition ScTriggerInteraction.h:41
#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
PxFilterFlags(* PxSimulationFilterShader)(PxFilterObjectAttributes attributes0, PxFilterData filterData0, PxFilterObjectAttributes attributes1, PxFilterData filterData1, PxPairFlags &pairFlags, const void *constantBlock, PxU32 constantBlockSize)
Filter method to specify how a pair of potentially colliding objects should be processed.
Definition PxFiltering.h:604
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 ScScene.h:62
Enum
Definition PxFiltering.h:717
Definition ScNPhaseCore.h:102
Definition ScNPhaseCore.h:120
Definition ScNPhaseCore.h:361
Definition ScNPhaseCore.h:85