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 |
58 | namespace physx |
59 | { |
60 | class PxCudaContextManager; |
61 | } |
62 | #endif |
63 | |
64 | namespace physx |
65 | { |
66 | |
67 | class PxsRigidBody; |
68 | struct PxcConstraintBlock; |
69 | class PxsMaterialManager; |
70 | class PxsCCDContext; |
71 | struct PxsContactManagerOutput; |
72 | struct PxvContactManagerTouchEvent; |
73 | |
74 | namespace Cm |
75 | { |
76 | class FlushPool; |
77 | } |
78 | |
79 | namespace IG |
80 | { |
81 | class SimpleIslandManager; |
82 | typedef PxU32 EdgeIndex; |
83 | } |
84 | |
85 | enum 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 | |
96 | class PxsContext : public Ps::UserAllocated, public PxcNpContext |
97 | { |
98 | PX_NOCOPY(PxsContext) |
99 | public: |
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 | |
260 | private: |
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 | |
326 | PX_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 | |