RavEngine
Loading...
Searching...
No Matches
PxsCCD.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#include "geometry/PxGeometry.h"
30#include "foundation/PxHashMap.h"
31#include "foundation/PxUserAllocated.h"
32#include "GuCCDSweepConvexMesh.h"
33#include "PxsIslandSim.h"
34
35#ifndef PXS_CCD_H
36#define PXS_CCD_H
37
38#define CCD_DEBUG_PRINTS 0
39#define CCD_POST_DEPENETRATE_DIST 0.001f
40#define CCD_ROTATION_LOCKING 0
41#define CCD_MIN_TIME_LEFT 0.01f
42
43#define DEBUG_RENDER_CCD 0
44
45#if CCD_DEBUG_PRINTS
46namespace physx {
47 extern void printCCDDebug(const char* msg, const PxsRigidBody* atom0, PxGeometryType::Enum g0, bool printPtr = true);
48 extern void printShape(PxsRigidBody* atom0, PxGeometryType::Enum g0, const char* annotation, PxReal dt, PxU32 pass, bool printPtr = true);
49}
50#define PRINTCCDSHAPE(x) printShape x
51#define PRINTCCDDEBUG(x) printCCDDebug x
52#else
53#define PRINTCCDSHAPE(x)
54#define PRINTCCDDEBUG(x)
55#endif
56
57namespace physx
58{
59 float computeCCDThreshold(const PxGeometry& geometry);
60
61// ------------------------------------------------------------------------------------------------------------
62// a fraction of objects will be CCD active so this is dynamic, not a member of PsxRigidBody
63// CCD code builds a temporary array of PxsCCDPair objects (allocated in blocks)
64// this is done to gather scattered data from memory and also to reduce PxsRidigBody permanent memory footprint
65// we have to do it every pass since new CMs can become fast moving after each pass (and sometimes cease to be)
66//
67struct PxsCCDBody;
68class PxsRigidBody;
69struct PxsShapeCore;
70struct PxsRigidCore;
71class PxsContactManager;
72class PxsContext;
73class PxCCDContactModifyCallback;
74class PxcNpThreadContext;
75
76class PxvNphaseImplementationContext;
77
78namespace Dy
79{
80 class ThresholdStream;
81}
82
87{
88 //The body the interaction relates to
89 PxsCCDBody* mBody;
90 //The next interaction in the list
91 PxsCCDOverlap* mNext;
92};
93
101{
102public:
103 const PxsShapeCore* mShapeCore; //Shape core (can be shared)
104 const PxsRigidCore* mRigidCore; //Rigid body core
105 PxNodeIndex mNodeIndex;
106
111 PxTransform getAbsPose(const PxsRigidBody* atom) const;
116 PxTransform getLastCCDAbsPose(const PxsRigidBody* atom) const;
117};
118
123{
124 Cm::SpatialVector mPreSolverVelocity;
125 PxU16 mIndex; //The CCD body's index
126 bool mPassDone; //Whether it has been processed in the current CCD pass
127 bool mHasAnyPassDone; //Whether this body was influenced by any passes
128 PxReal mTimeLeft; //CCD time left to elapse (normalized in range 0-1)
129 PxsRigidBody* mBody; //The rigid body
130 PxsCCDOverlap* mOverlappingObjects; //A list of overlapping bodies for island update
131 PxU32 mUpdateCount; //How many times this body has eben updated in the CCD. This is correlated with CCD shapes' update counts.
132 PxU32 mNbInteractionsThisPass; //How many interactions this pass
133
138 PX_FORCE_INLINE PxU32 getIndex() const { return mIndex; }
139
145 bool overlaps(PxsCCDBody* body) const
146 {
147 PxsCCDOverlap* overlaps = mOverlappingObjects;
148
149 while(overlaps)
150 {
151 if(overlaps->mBody == body)
152 return true;
153 overlaps = overlaps->mNext;
154 }
155 return false;
156 }
157
163 {
164 overlap->mNext = mOverlappingObjects;
165 mOverlappingObjects = overlap;
166 }
167
168};
169
176template<typename T, int BLOCK_SIZE>
178{
182 struct Block : PxUserAllocated { T items[BLOCK_SIZE]; };
187 {
188 Block* block;
189 PxU32 count; // number of elements in this block
190 BlockInfo(Block* aBlock, PxU32 aCount) : block(aBlock), count(aCount) {}
191 };
192 /*
193 \brief An array of block headers
194 */
195 PxArray<BlockInfo> blocks;
200
205 {
206 blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
207 }
208
213 {
214 for (PxU32 i = 0; i < blocks.size(); i++)
215 {
216 PX_DELETE(blocks[i].block);
217 }
218 currentBlock = 0;
219 }
220
225 void clear()
226 {
227 for (PxU32 i = 0; i < blocks.size(); i++)
228 {
229 PX_DELETE(blocks[i].block);
230 }
231 blocks.clear();
232 blocks.pushBack(BlockInfo(PX_NEW(Block), 0)); // at least one block is expected to always be present in the array
233 currentBlock = 0;
234 }
235
240 {
241 currentBlock = 0;
242 blocks[0].count = 0;
243 }
244
250 {
251 PxU32 numBlocks = blocks.size();
252 if (blocks[currentBlock].count == BLOCK_SIZE)
253 {
254 if((currentBlock + 1) == numBlocks)
255 {
256 blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
257 numBlocks ++;
258 }
259 currentBlock++;
260 blocks[currentBlock].count = 0;
261 }
262 const PxU32 count = blocks[currentBlock].count ++;
263
264 return blocks[currentBlock].block->items[count];
265 }
266
272 T& pushBack(T& data)
273 {
274 PxU32 numBlocks = blocks.size();
275 if (blocks[currentBlock].count == BLOCK_SIZE)
276 {
277 if((currentBlock + 1) == numBlocks)
278 {
279 blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
280 numBlocks ++;
281 }
282 currentBlock++;
283 blocks[currentBlock].count = 0;
284 }
285 const PxU32 count = blocks[currentBlock].count ++;
286 blocks[currentBlock].block->items[count] = data;
287 return blocks[currentBlock].block->items[count];
288 }
289
293 void popBack()
294 {
295 PX_ASSERT(blocks[currentBlock].count > 0);
296 if (blocks[currentBlock].count > 1)
297 blocks[currentBlock].count --;
298 else
299 {
300 PX_DELETE(blocks[currentBlock].block);
301 blocks.popBack();
302 currentBlock--;
303 }
304 }
305
310 PxU32 size() const
311 {
312 return (currentBlock)*BLOCK_SIZE + blocks[currentBlock].count;
313 }
314
320 T& operator[] (PxU32 index) const
321 {
322 PX_ASSERT(index/BLOCK_SIZE < blocks.size());
323 PX_ASSERT(index%BLOCK_SIZE < blocks[index/BLOCK_SIZE].count);
324 return blocks[index/BLOCK_SIZE].block->items[index%BLOCK_SIZE];
325 }
326};
327
332{
340 {
341 eEstimate,
342 ePrecise
343 };
344 PxsRigidBody* mBa0; // Body A. Can be NULL for statics
345 PxsRigidBody* mBa1; // Body B. Can be NULL for statics
346 PxsCCDShape* mCCDShape0; // Shape A
347 PxsCCDShape* mCCDShape1; // Shape B
348 PxVec3 mMinToiNormal; // The contact normal. Only valid for precise results. On the surface of body/shape A
349 PxReal mMinToi; // Min TOI. Valid for both precise and estimated results but estimates may be too early (i.e. conservative).
350 PxReal mPenetrationPostStep; // Valid only for precise sweeps. Only used for initial intersections (i.e. at TOI = 0).
351 PxVec3 mMinToiPoint; // The contact point. Only valid for precise sweep results.
352 PxReal mPenetration; // The penetration. Only valid for precise sweep results.
353 PxsContactManager* mCm; // The contact manager.
354 PxU32 mIslandId; // The index of the island this pair is in
355 PxGeometryType::Enum mG0, mG1; // The geometry types for shapes 0 and 1
356 bool mIsEarliestToiHit; // Indicates this was the earliest hit for one of the bodies in the pair
357 bool mIsModifiable; // Indicates whether this contact is modifiable
358 PxU32 mFaceIndex; // The face index. Only valid for precise sweeps involving meshes or heightfields.
359 PxU16 mMaterialIndex0; // The material index for shape 0
360 PxU16 mMaterialIndex1; // The material index for shape 1
361 PxReal mDynamicFriction; // The dynamic friction coefficient
362 PxReal mStaticFriction; // The static friction coefficient
363 PxReal mRestitution; // The restitution coefficient
364 PxU32 mEstimatePass; // The current estimation pass. Used after a sweep hit was found to determine if the pair needs re-estimating.
365 PxReal mAppliedForce; // The applied force for this pair. Only valid if the pair has been responded to.
366 PxReal mMaxImpulse; // The maximum impulse to be applied
367
368 E_TOIType mToiType; // The TOI type (estimate, precise).
369 bool mHasFriction; // Whether we want to simulate CCD friction for this pair
370
378 PxReal sweepFindToi(PxcNpThreadContext& threadContext, PxReal dt, PxU32 pass, PxReal ccdThreshold);
383 PxReal sweepEstimateToi(PxReal ccdThreshold);
390 bool sweepAdvanceToToi(PxReal dt, bool clipTrajectoryToToi);
394 void updateShapes();
395};
396
413
418
423{
424public:
429 PxsCCDContext(PxsContext* context, Dy::ThresholdStream& thresholdStream, PxvNphaseImplementationContext& nPhaseContext, PxReal ccdThreshold);
434
439 PX_FORCE_INLINE PxCCDContactModifyCallback* getCCDContactModifyCallback() const { return mCCDContactModifyCallback; }
449 PX_FORCE_INLINE PxU32 getCCDMaxPasses() const { return mCCDMaxPasses; }
454 PX_FORCE_INLINE void setCCDMaxPasses(PxU32 ccdMaxPasses) { mCCDMaxPasses = ccdMaxPasses; }
459 PX_FORCE_INLINE PxU32 getCurrentCCDPass() const { return miCCDPass; }
464 PX_FORCE_INLINE PxI32 getNumSweepHits() const { return mSweepTotalHits; }
469 PX_FORCE_INLINE PxU32 getNumUpdatedBodies() const { return mUpdatedCCDBodies.size(); }
474 PX_FORCE_INLINE PxsRigidBody*const* getUpdatedBodies() const { return mUpdatedCCDBodies.begin(); }
475
479 PX_FORCE_INLINE void clearUpdatedBodies() { mUpdatedCCDBodies.forceSize_Unsafe(0); }
480
481 PX_FORCE_INLINE PxReal getCCDThreshold() const { return mCCDThreshold; }
482 PX_FORCE_INLINE void setCCDThreshold(PxReal t) { mCCDThreshold = t; }
483
495 void runCCDModifiableContact(PxModifiableContact* PX_RESTRICT contacts, PxU32 contactCount, const PxsShapeCore* PX_RESTRICT shapeCore0,
496 const PxsShapeCore* PX_RESTRICT shapeCore1, const PxsRigidCore* PX_RESTRICT rigidCore0, const PxsRigidCore* PX_RESTRICT rigidCore1,
497 const PxsRigidBody* PX_RESTRICT rigid0, const PxsRigidBody* PX_RESTRICT rigid1);
498
508 void updateCCD(PxReal dt, PxBaseTask* continuation, IG::IslandSim& islandSim, bool disableResweep, PxI32 numFastMovingShapes);
509
513 void updateCCDBegin();
514
519
520private:
521
525 void verifyCCDBegin();
526
530 void updateCCDEnd();
531
536 void postCCDSweep(PxBaseTask* continuation);
541 void postCCDAdvance(PxBaseTask* continuation);
546 void postCCDDepenetrate(PxBaseTask* continuation);
547
548 typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDSweep> PostCCDSweepTask;
549 typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDAdvance> PostCCDAdvanceTask;
550 typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDDepenetrate> PostCCDDepenetrateTask;
551
552 PostCCDSweepTask mPostCCDSweepTask;
553 PostCCDAdvanceTask mPostCCDAdvanceTask;
554 PostCCDDepenetrateTask mPostCCDDepenetrateTask;
555
556 PxCCDContactModifyCallback* mCCDContactModifyCallback;
557
558 // CCD global data
559 bool mDisableCCDResweep;
560 PxU32 miCCDPass;
561 PxI32 mSweepTotalHits;
562
563 // a fraction of objects will be CCD active so PxsCCDBody is dynamic, not a member of PxsRigidBody
564 PxsCCDBodyArray mCCDBodies;
565 PxsCCDOverlapArray mCCDOverlaps;
566 PxsCCDShapeArray mCCDShapes;
567 PxArray<PxsCCDBody*> mIslandBodies;
568 PxArray<PxU16> mIslandSizes;
569 PxArray<PxsRigidBody*> mUpdatedCCDBodies;
570 PxHashMap<PxsRigidShapePair, PxsCCDShape*> mMap;
571
572 // temporary array updated during CCD update
573 //Array<PxsCCDPair> mCCDPairs;
574 PxsCCDPairArray mCCDPairs;
575 PxArray<PxsCCDPair*> mCCDPtrPairs;
576 // number of pairs per island
577 PxArray<PxU32> mCCDIslandHistogram;
578 // thread context valid during CCD update
579 PxcNpThreadContext* mCCDThreadContext;
580 // number of pairs to process per thread
581 PxU32 mCCDPairsPerBatch;
582 PxU32 mCCDMaxPasses;
583
584 PxsContext* mContext;
585 Dy::ThresholdStream& mThresholdStream;
586
587 PxvNphaseImplementationContext& mNphaseContext;
588
589 PxMutex mMutex;
590
591 PxReal mCCDThreshold;
592
593private:
594
595 PX_NOCOPY(PxsCCDContext)
596};
597
598
599}
600
601
602
603#endif
604
Definition base.h:1940
Definition CmSpatialVector.h:46
Definition DyThresholdTable.h:81
Definition PxArray.h:53
PX_FORCE_INLINE uint32_t size() const
Definition PxArray.h:242
PX_INLINE void clear()
Definition PxArray.h:250
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE T popBack()
Definition PxArray.h:311
An interface class that the user can implement in order to modify CCD contact constraints.
Definition PxContactModifyCallback.h:500
PxNodeIndex.
Definition PxNodeIndex.h:51
Definition PxBasicTemplates.h:67
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 PxcNpThreadContext.h:119
CCD context object.
Definition PxsCCD.h:423
void resetContactManagers()
Resets the CCD contact state in any contact managers that previously had a reported CCD touch....
Definition PxsCCD.cpp:1379
PX_FORCE_INLINE void setCCDContactModifyCallback(PxCCDContactModifyCallback *c)
Sets the CCD contact modification callback.
Definition PxsCCD.h:444
PX_FORCE_INLINE PxsRigidBody *const * getUpdatedBodies() const
Returns The update bodies array.
Definition PxsCCD.h:474
PX_FORCE_INLINE PxI32 getNumSweepHits() const
Returns The number of swept hits reported.
Definition PxsCCD.h:464
PX_FORCE_INLINE void setCCDMaxPasses(PxU32 ccdMaxPasses)
Sets the maximum number of CCD passes.
Definition PxsCCD.h:454
PX_FORCE_INLINE PxU32 getCurrentCCDPass() const
Returns the current CCD pass.
Definition PxsCCD.h:459
PX_FORCE_INLINE void clearUpdatedBodies()
Returns Clears the updated bodies array.
Definition PxsCCD.h:479
PX_FORCE_INLINE PxCCDContactModifyCallback * getCCDContactModifyCallback() const
Returns the CCD contact modification callback.
Definition PxsCCD.h:439
PX_FORCE_INLINE PxU32 getCCDMaxPasses() const
Returns the maximum number of CCD passes.
Definition PxsCCD.h:449
void runCCDModifiableContact(PxModifiableContact *PX_RESTRICT contacts, PxU32 contactCount, const PxsShapeCore *PX_RESTRICT shapeCore0, const PxsShapeCore *PX_RESTRICT shapeCore1, const PxsRigidCore *PX_RESTRICT rigidCore0, const PxsRigidCore *PX_RESTRICT rigidCore1, const PxsRigidBody *PX_RESTRICT rigid0, const PxsRigidBody *PX_RESTRICT rigid1)
Runs the CCD contact modification.
Definition PxsCCD.cpp:2122
~PxsCCDContext()
Destructor for PxsCCDContext.
Definition PxsCCD.cpp:337
PX_FORCE_INLINE PxU32 getNumUpdatedBodies() const
Returns The number of updated bodies.
Definition PxsCCD.h:469
void updateCCDBegin()
Signals the beginning of a CCD multi-pass update.
Definition PxsCCD.cpp:1319
void updateCCD(PxReal dt, PxBaseTask *continuation, IG::IslandSim &islandSim, bool disableResweep, PxI32 numFastMovingShapes)
Performs a single CCD update This occurs after broad phase and is responsible for creating islands,...
Definition PxsCCD.cpp:1425
Definition PxsContactManager.h:77
Definition PxsContext.h:92
Definition PxsRigidBody.h:43
Definition PxvNphaseImplementationContext.h:120
#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
PxPair< const PxsRigidCore *, const PxsShapeCore * > PxsRigidShapePair
Pair structure to be able to look-up a rigid body-shape pair in a map.
Definition PxsCCD.h:417
PxsCCDBlockArray< PxsCCDPair, 128 > PxsCCDPairArray
Block array of CCD pairs.
Definition PxsCCD.h:404
PxsCCDBlockArray< PxsCCDOverlap, 128 > PxsCCDOverlapArray
Block array of CCD overlaps.
Definition PxsCCD.h:408
PxsCCDBlockArray< PxsCCDBody, 128 > PxsCCDBodyArray
Block array of CCD bodies.
Definition PxsCCD.h:400
PxsCCDBlockArray< PxsCCDShape, 128 > PxsCCDShapeArray
Block array of CCD shapes.
Definition PxsCCD.h:412
Definition GuCCDSweepConvexMesh.h:89
Enum
Definition PxGeometry.h:52
A header for a block of data.
Definition PxsCCD.h:187
A block of data.
Definition PxsCCD.h:182
a container class used in the CCD that minimizes frequency of hitting the allocator.
Definition PxsCCD.h:178
void clear_NoDelete()
Clears this block array but does not release the memory.
Definition PxsCCD.h:239
T & pushBack(T &data)
Pushes a new element onto the back of this array, intitializing it to match the data.
Definition PxsCCD.h:272
void popBack()
Pops the last element from the list.
Definition PxsCCD.h:293
T & pushBack()
Push a new element onto the back of the block array.
Definition PxsCCD.h:249
void clear()
Clears this block array.
Definition PxsCCD.h:225
PxU32 size() const
Returns the current size of the array.
Definition PxsCCD.h:310
T & operator[](PxU32 index) const
Returns the element at a given index in the array.
Definition PxsCCD.h:320
PxsCCDBlockArray()
Constructor.
Definition PxsCCD.h:204
~PxsCCDBlockArray()
Destructor.
Definition PxsCCD.h:212
PxU32 currentBlock
The current block.
Definition PxsCCD.h:199
Structure to represent a body in the CCD system.
Definition PxsCCD.h:123
bool overlaps(PxsCCDBody *body) const
Tests whether this body has already registered an overlap with a given body.
Definition PxsCCD.h:145
void addOverlap(PxsCCDOverlap *overlap)
Registers an overlap with a given body.
Definition PxsCCD.h:162
PX_FORCE_INLINE PxU32 getIndex() const
Returns the CCD body's index.
Definition PxsCCD.h:138
structure to represent interactions between a given body and another body.
Definition PxsCCD.h:87
A structure to represent a potential CCD interaction between a pair of shapes.
Definition PxsCCD.h:332
bool sweepAdvanceToToi(PxReal dt, bool clipTrajectoryToToi)
Advances this pair to the TOI.
Definition PxsCCD.cpp:644
PxReal sweepFindToi(PxcNpThreadContext &threadContext, PxReal dt, PxU32 pass, PxReal ccdThreshold)
Perform a precise sweep for this pair.
Definition PxsCCD.cpp:358
E_TOIType
Defines whether this is an estimated TOI or an accurate TOI.
Definition PxsCCD.h:340
PxReal sweepEstimateToi(PxReal ccdThreshold)
Performs a sweep estimation for this pair.
Definition PxsCCD.cpp:570
void updateShapes()
Updates the transforms of the shapes involved in this pair.
Definition PxsCCD.cpp:525
Temporary CCD representation for a shape.
Definition PxsCCD.h:101
PxTransform getLastCCDAbsPose(const PxsRigidBody *atom) const
Returns the world-space previous pose for this shape.
Definition PxsCCD.cpp:351
PxTransform getAbsPose(const PxsRigidBody *atom) const
Returns the world-space pose for this shape.
Definition PxsCCD.cpp:341
Definition PxvDynamics.h:48
Definition PxvGeometry.h:221