1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29
30
31#ifndef PXS_CONTEXT_H
32#define PXS_CONTEXT_H
33
34#include "PxVisualizationParameter.h"
35#include "PxSceneDesc.h"
36
37#include "CmPool.h"
38
39#include "PxvNphaseImplementationContext.h"
40#include "PxvSimStats.h"
41#include "PxsContactManager.h"
42#include "PxcNpBatch.h"
43#include "PxcConstraintBlockStream.h"
44#include "PxcNpCacheStreamPair.h"
45#include "PxcNpMemBlockPool.h"
46#include "CmRenderOutput.h"
47#include "CmUtils.h"
48#include "CmTask.h"
49
50#include "PxContactModifyCallback.h"
51
52#include "PxsTransformCache.h"
53#include "GuPersistentContactManifold.h"
54#include "DyArticulation.h"
55
56
57#if PX_SUPPORT_GPU_PHYSX
58namespace physx
59{
60 class PxCudaContextManager;
61}
62#endif
63
64namespace physx
65{
66
67class PxsRigidBody;
68struct PxcConstraintBlock;
69class PxsMaterialManager;
70class PxsCCDContext;
71struct PxsContactManagerOutput;
72struct PxvContactManagerTouchEvent;
73
74namespace Cm
75{
76 class FlushPool;
77}
78
79namespace IG
80{
81 class SimpleIslandManager;
82 typedef PxU32 EdgeIndex;
83}
84
85enum PxsTouchEventCount
86{
87 PXS_LOST_TOUCH_COUNT = 0,
88 PXS_NEW_TOUCH_COUNT = 1,
89 PXS_CCD_RETOUCH_COUNT = 2, // pairs that are touching at a CCD pass and were touching at discrete collision or at a previous CCD pass already
90 // (but they could have lost touch in between)
91 PXS_PATCH_FOUND_COUNT = 3,
92 PXS_PATCH_LOST_COUNT = 4,
93 PXS_TOUCH_EVENT_COUNT = 5
94};
95
96class PxsContext : public Ps::UserAllocated, public PxcNpContext
97{
98 PX_NOCOPY(PxsContext)
99public:
100 PxsContext( const PxSceneDesc& desc, PxTaskManager*, Cm::FlushPool&, PxCudaContextManager*, PxU64 contextID);
101 ~PxsContext();
102
103 void removeRigidBody(PxsRigidBody&);
104
105 Dy::Articulation* createArticulation();
106 void destroyArticulation(Dy::Articulation&);
107
108 void createTransformCache(Ps::VirtualAllocatorCallback& allocatorCallback);
109
110 PxsContactManager* createContactManager(PxsContactManager* contactManager, const bool useCCD);
111 void createCache(Gu::Cache& cache, PxsContactManager* cm, PxU8 geomType0, PxU8 geomType1);
112 void destroyCache(Gu::Cache& cache);
113 void destroyContactManager(PxsContactManager* cm);
114
115
116 PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
117
118 // Collision properties
119 PX_FORCE_INLINE PxContactModifyCallback* getContactModifyCallback() const { return mContactModifyCallback; }
120 PX_FORCE_INLINE void setContactModifyCallback(PxContactModifyCallback* c) { mContactModifyCallback = c; mNpImplementationContext->setContactModifyCallback(c);}
121
122
123 // resource-related
124 void setScratchBlock(void* addr, PxU32 size);
125
126 void setContactDistance(Ps::Array<PxReal, Ps::VirtualAllocator>* contactDistance);
127
128 // Task-related
129 void updateContactManager(PxReal dt, bool hasBoundsArrayChanged, bool hasContactDistanceChanged, PxBaseTask* continuation, PxBaseTask* firstPassContinuation);
130 void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation);
131 void fetchUpdateContactManager();
132 void swapStreams();
133
134 void resetThreadContexts();
135
136 // Manager status change
137 bool getManagerTouchEventCount(int* newTouch, int* lostTouch, int* ccdTouch) const;
138 bool fillManagerTouchEvents(
139 PxvContactManagerTouchEvent* newTouch, PxI32& newTouchCount,
140 PxvContactManagerTouchEvent* lostTouch, PxI32& lostTouchCount,
141 PxvContactManagerTouchEvent* ccdTouch, PxI32& ccdTouchCount);
142
143 PX_FORCE_INLINE void getManagerPatchEventCount(PxU32& foundPatch, PxU32& lostPatch) const { foundPatch = mCMTouchEventCount[PXS_PATCH_FOUND_COUNT]; lostPatch = mCMTouchEventCount[PXS_PATCH_LOST_COUNT]; }
144 bool fillManagerPatchChangedEvents(
145 PxsContactManager** foundPatch, PxU32& foundPatchCount,
146 PxsContactManager** lostPatch, PxU32& lostPatchCount);
147
148 void beginUpdate();
149
150 // PX_ENABLE_SIM_STATS
151 PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; }
152 PX_FORCE_INLINE const PxvSimStats& getSimStats() const { return mSimStats; }
153
154 PX_FORCE_INLINE Cm::FlushPool& getTaskPool() const { return mTaskPool; }
155 PX_FORCE_INLINE Cm::RenderBuffer& getRenderBuffer() { return mRenderBuffer; }
156
157 PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const;
158 void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value);
159
160 PX_FORCE_INLINE void setVisualizationCullingBox(const PxBounds3& box) { mVisualizationCullingBox = box; }
161 PX_FORCE_INLINE const PxBounds3& getVisualizationCullingBox()const { return mVisualizationCullingBox; }
162
163 PX_FORCE_INLINE PxReal getRenderScale() const { return mVisualizationParams[PxVisualizationParameter::eSCALE]; }
164 Cm::RenderOutput getRenderOutput() { return Cm::RenderOutput(mRenderBuffer); }
165 PX_FORCE_INLINE bool getPCM() const { return mPCM; }
166 PX_FORCE_INLINE bool getContactCacheFlag() const { return mContactCache; }
167 PX_FORCE_INLINE bool getCreateAveragePoint() const { return mCreateAveragePoint; }
168
169 // general stuff
170 void shiftOrigin(const PxVec3& shift);
171
172 void setCreateContactStream(bool to);
173 PX_FORCE_INLINE void setPCM(bool enabled) { mPCM = enabled; }
174 PX_FORCE_INLINE void setContactCache(bool enabled) { mContactCache = enabled; }
175
176 PX_FORCE_INLINE PxcScratchAllocator& getScratchAllocator() { return mScratchAllocator; }
177 PX_FORCE_INLINE PxsTransformCache& getTransformCache() { return *mTransformCache; }
178 PX_FORCE_INLINE PxReal* getContactDistance() { return mContactDistance->begin(); }
179
180 PX_FORCE_INLINE PxvNphaseImplementationContext* getNphaseImplementationContext() const
181 {
182 return mNpImplementationContext;
183 }
184
185 PX_FORCE_INLINE void setNphaseImplementationContext(PxvNphaseImplementationContext* ctx)
186 {
187 mNpImplementationContext = ctx;
188 }
189
190 PX_FORCE_INLINE PxvNphaseImplementationContext* getNphaseFallbackImplementationContext() const
191 {
192 return mNpFallbackImplementationContext;
193 }
194
195 PX_FORCE_INLINE void setNphaseFallbackImplementationContext(PxvNphaseImplementationContext* ctx)
196 {
197 mNpFallbackImplementationContext = ctx;
198 }
199
200 PxU32 getTotalCompressedContactSize() const { return mTotalCompressedCacheSize; }
201 PxU32 getMaxPatchCount() const { return mMaxPatches; }
202
203 PX_FORCE_INLINE PxcThreadCoherentCache<PxcNpThreadContext, PxcNpContext>& getNpThreadContextPool()
204 {
205 return mNpThreadContextPool;
206 }
207
208 PX_FORCE_INLINE PxcNpThreadContext* getNpThreadContext()
209 {
210 // We may want to conditional compile to exclude this on single threaded implementations
211 // if it is determined to be a performance hit.
212 return mNpThreadContextPool.get();
213 }
214
215 PX_FORCE_INLINE void putNpThreadContext(PxcNpThreadContext* threadContext)
216 { mNpThreadContextPool.put(item: threadContext); }
217 PX_FORCE_INLINE Ps::Mutex& getLock() { return mLock; }
218
219 PX_FORCE_INLINE PxTaskManager& getTaskManager()
220 {
221 PX_ASSERT(mTaskManager);
222 return *mTaskManager;
223 }
224
225 PX_FORCE_INLINE PxCudaContextManager* getCudaContextManager()
226 {
227 return mCudaContextManager;
228 }
229
230 PX_FORCE_INLINE void clearManagerTouchEvents();
231
232 PX_FORCE_INLINE Cm::PoolList<PxsContactManager, PxsContext>& getContactManagerPool()
233 {
234 return this->mContactManagerPool;
235 }
236
237 PX_FORCE_INLINE void setActiveContactManager(const PxsContactManager* manager)
238 {
239 const PxU32 index = manager->getIndex();
240 if (index >= mActiveContactManager.size())
241 {
242 PxU32 newSize = (2 * index + 256)&~255;
243 mActiveContactManager.resize(newBitCount: newSize);
244 }
245 mActiveContactManager.set(index);
246
247 //Record any pairs that have CCD enabled!
248 if (manager->getCCD())
249 {
250 if (index >= mActiveContactManagersWithCCD.size())
251 {
252 PxU32 newSize = (2 * index + 256)&~255;
253 mActiveContactManagersWithCCD.resize(newBitCount: newSize);
254 }
255 mActiveContactManagersWithCCD.set(index);
256 }
257 }
258
259
260private:
261 void mergeCMDiscreteUpdateResults(PxBaseTask* continuation);
262
263 PxU32 mIndex;
264
265 // Threading
266 PxcThreadCoherentCache<PxcNpThreadContext, PxcNpContext>
267 mNpThreadContextPool;
268
269 // Contact managers
270 Cm::PoolList<PxsContactManager, PxsContext> mContactManagerPool;
271 Ps::Pool<Gu::LargePersistentContactManifold> mManifoldPool;
272 Ps::Pool<Gu::SpherePersistentContactManifold> mSphereManifoldPool;
273
274 Cm::BitMap mActiveContactManager;
275 Cm::BitMap mActiveContactManagersWithCCD; //KS - adding to filter any pairs that had a touch
276 Cm::BitMap mContactManagersWithCCDTouch; //KS - adding to filter any pairs that had a touch
277 Cm::BitMap mContactManagerTouchEvent;
278 Cm::BitMap mContactManagerPatchChangeEvent;
279 PxU32 mCMTouchEventCount[PXS_TOUCH_EVENT_COUNT];
280
281 Ps::Mutex mLock;
282
283
284
285 PxContactModifyCallback* mContactModifyCallback;
286
287 // narrowphase platform-dependent implementations support
288 PxvNphaseImplementationContext* mNpImplementationContext;
289 PxvNphaseImplementationContext* mNpFallbackImplementationContext;
290
291
292 // debug rendering (CS TODO: MS would like to have these wrapped into a class)
293 PxReal mVisualizationParams[PxVisualizationParameter::eNUM_VALUES];
294
295 PxBounds3 mVisualizationCullingBox;
296
297 PxTaskManager* mTaskManager;
298 Cm::FlushPool& mTaskPool;
299
300 PxCudaContextManager* mCudaContextManager;
301
302 // PxU32 mTouchesLost;
303 // PxU32 mTouchesFound;
304
305 // PX_ENABLE_SIM_STATS
306 PxvSimStats mSimStats;
307 bool mPCM;
308 bool mContactCache;
309 bool mCreateAveragePoint;
310
311 PxsTransformCache* mTransformCache;
312 Ps::Array<PxReal, Ps::VirtualAllocator>* mContactDistance;
313
314
315 PxU32 mMaxPatches;
316 PxU32 mTotalCompressedCacheSize;
317
318 PxU64 mContextID;
319
320 friend class PxsCCDContext;
321 friend class PxsNphaseImplementationContext;
322 friend class PxgNphaseImplementationContext; //FDTODO ideally it shouldn't be here..
323};
324
325
326PX_FORCE_INLINE void PxsContext::clearManagerTouchEvents()
327{
328 mContactManagerTouchEvent.clear();
329 mContactManagerPatchChangeEvent.clear();
330 for(PxU32 i = 0; i < PXS_TOUCH_EVENT_COUNT; ++i)
331 {
332 mCMTouchEventCount[i] = 0;
333 }
334}
335
336
337}
338
339#endif
340

source code of qtquick3dphysics/src/3rdparty/PhysX/source/lowlevel/software/include/PxsContext.h