| 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 PXC_NPTHREADCONTEXT_H |
| 32 | #define PXC_NPTHREADCONTEXT_H |
| 33 | |
| 34 | #include "geometry/PxGeometry.h" |
| 35 | #include "geomutils/GuContactBuffer.h" |
| 36 | |
| 37 | #include "PxvConfig.h" |
| 38 | #include "CmScaling.h" |
| 39 | #include "CmRenderOutput.h" |
| 40 | #include "PxcNpCacheStreamPair.h" |
| 41 | #include "PxcConstraintBlockStream.h" |
| 42 | #include "PxcThreadCoherentCache.h" |
| 43 | #include "CmBitMap.h" |
| 44 | #include "../pcm/GuPersistentContactManifold.h" |
| 45 | |
| 46 | namespace physx |
| 47 | { |
| 48 | |
| 49 | class PxsTransformCache; |
| 50 | class PxsMaterialManager; |
| 51 | |
| 52 | namespace Sc |
| 53 | { |
| 54 | class BodySim; |
| 55 | } |
| 56 | |
| 57 | /*! |
| 58 | Per-thread context used by contact generation routines. |
| 59 | */ |
| 60 | |
| 61 | struct PxcDataStreamPool |
| 62 | { |
| 63 | PxU8* mDataStream; |
| 64 | PxI32 mSharedDataIndex; |
| 65 | PxU32 mDataStreamSize; |
| 66 | PxU32 mSharedDataIndexGPU; |
| 67 | |
| 68 | bool isOverflown() const |
| 69 | { |
| 70 | //FD: my expectaton is that reading those variables is atomic, shared indices are non-decreasing, |
| 71 | //so we can only get a false overflow alert because of concurrency issues, which is not a big deal as it means |
| 72 | //it did overflow a bit later |
| 73 | return mSharedDataIndex + mSharedDataIndexGPU >= mDataStreamSize; |
| 74 | } |
| 75 | }; |
| 76 | |
| 77 | struct PxcNpContext |
| 78 | { |
| 79 | private: |
| 80 | PX_NOCOPY(PxcNpContext) |
| 81 | public: |
| 82 | |
| 83 | PxcNpContext() : |
| 84 | mNpMemBlockPool (mScratchAllocator), |
| 85 | mMeshContactMargin (0.0f), |
| 86 | mToleranceLength (0.0f), |
| 87 | mCreateContactStream (false), |
| 88 | mContactStreamPool (NULL), |
| 89 | mPatchStreamPool (NULL), |
| 90 | mForceAndIndiceStreamPool(NULL), |
| 91 | mMaterialManager (NULL) |
| 92 | { |
| 93 | } |
| 94 | |
| 95 | PxcScratchAllocator mScratchAllocator; |
| 96 | PxcNpMemBlockPool mNpMemBlockPool; |
| 97 | PxReal mMeshContactMargin; |
| 98 | PxReal mToleranceLength; |
| 99 | Cm::RenderBuffer mRenderBuffer; |
| 100 | bool mCreateContactStream; // flag to enforce that contacts are stored persistently per workunit. Used for PVD. |
| 101 | PxcDataStreamPool* mContactStreamPool; |
| 102 | PxcDataStreamPool* mPatchStreamPool; |
| 103 | PxcDataStreamPool* mForceAndIndiceStreamPool; |
| 104 | PxcDataStreamPool* mConstraintWriteBackStreamPool; |
| 105 | PxsMaterialManager* mMaterialManager; |
| 106 | |
| 107 | PX_FORCE_INLINE PxReal getToleranceLength() const { return mToleranceLength; } |
| 108 | PX_FORCE_INLINE void setToleranceLength(PxReal x) { mToleranceLength = x; } |
| 109 | PX_FORCE_INLINE PxReal getMeshContactMargin() const { return mMeshContactMargin; } |
| 110 | PX_FORCE_INLINE void setMeshContactMargin(PxReal x) { mMeshContactMargin = x; } |
| 111 | PX_FORCE_INLINE bool getCreateContactStream() { return mCreateContactStream; } |
| 112 | |
| 113 | PX_FORCE_INLINE PxcNpMemBlockPool& getNpMemBlockPool() { return mNpMemBlockPool; } |
| 114 | PX_FORCE_INLINE const PxcNpMemBlockPool& getNpMemBlockPool() const { return mNpMemBlockPool; } |
| 115 | PX_FORCE_INLINE void setMaterialManager(PxsMaterialManager* m){ mMaterialManager = m; } |
| 116 | PX_FORCE_INLINE PxsMaterialManager* getMaterialManager() const { return mMaterialManager; } |
| 117 | |
| 118 | Cm::RenderOutput getRenderOutput() { return Cm::RenderOutput(mRenderBuffer); } |
| 119 | }; |
| 120 | |
| 121 | class PxcNpThreadContext : public PxcThreadCoherentCache<PxcNpThreadContext, PxcNpContext>::EntryBase |
| 122 | { |
| 123 | PX_NOCOPY(PxcNpThreadContext) |
| 124 | public: |
| 125 | PxcNpThreadContext(PxcNpContext* params); |
| 126 | ~PxcNpThreadContext(); |
| 127 | |
| 128 | #if PX_ENABLE_SIM_STATS |
| 129 | void clearStats(); |
| 130 | #endif |
| 131 | |
| 132 | PX_FORCE_INLINE void setCreateContactStream(bool to) { mCreateContactStream = to; } |
| 133 | |
| 134 | PX_FORCE_INLINE void addLocalNewTouchCount(PxU32 newTouchCMCount) { mLocalNewTouchCount += newTouchCMCount; } |
| 135 | PX_FORCE_INLINE void addLocalLostTouchCount(PxU32 lostTouchCMCount) { mLocalLostTouchCount += lostTouchCMCount; } |
| 136 | PX_FORCE_INLINE PxU32 getLocalNewTouchCount() const { return mLocalNewTouchCount; } |
| 137 | PX_FORCE_INLINE PxU32 getLocalLostTouchCount() const { return mLocalLostTouchCount; } |
| 138 | |
| 139 | PX_FORCE_INLINE void addLocalFoundPatchCount(PxU32 foundPatchCount) { mLocalFoundPatchCount += foundPatchCount; } |
| 140 | PX_FORCE_INLINE void addLocalLostPatchCount(PxU32 lostPatchCount) { mLocalLostPatchCount += lostPatchCount; } |
| 141 | PX_FORCE_INLINE PxU32 getLocalFoundPatchCount() const { return mLocalFoundPatchCount; } |
| 142 | PX_FORCE_INLINE PxU32 getLocalLostPatchCount() const { return mLocalLostPatchCount; } |
| 143 | |
| 144 | PX_FORCE_INLINE Cm::BitMap& getLocalChangeTouch() { return mLocalChangeTouch; } |
| 145 | |
| 146 | PX_FORCE_INLINE Cm::BitMap& getLocalPatchChangeMap() { return mLocalPatchCountChange; } |
| 147 | |
| 148 | void reset(PxU32 cmCount); |
| 149 | // debugging |
| 150 | Cm::RenderOutput mRenderOutput; |
| 151 | |
| 152 | // dsequeira: Need to think about this block pool allocation a bit more. Ideally we'd be |
| 153 | // taking blocks from a single pool, except that we want to be able to selectively reclaim |
| 154 | // blocks if the user needs to defragment, depending on which artifacts they're willing |
| 155 | // to tolerate, such that the blocks we don't reclaim are contiguous. |
| 156 | #if PX_ENABLE_SIM_STATS |
| 157 | PxU32 mDiscreteContactPairs [PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT]; |
| 158 | PxU32 mModifiedContactPairs [PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT]; |
| 159 | #endif |
| 160 | PxcContactBlockStream mContactBlockStream; // constraint block pool |
| 161 | PxcNpCacheStreamPair mNpCacheStreamPair; // narrow phase pairwise data cache |
| 162 | |
| 163 | // Everything below here is scratch state. Most of it can even overlap. |
| 164 | |
| 165 | // temporary contact buffer |
| 166 | Gu::ContactBuffer mContactBuffer; |
| 167 | |
| 168 | PX_ALIGN(16, Gu::MultiplePersistentContactManifold mTempManifold); |
| 169 | |
| 170 | Gu::NarrowPhaseParams mNarrowPhaseParams; |
| 171 | |
| 172 | // DS: this stuff got moved here from the PxcNpPairContext. As Pierre says: |
| 173 | ////////// PT: those members shouldn't be there in the end, it's not necessary |
| 174 | Ps::Array<Sc::BodySim*> mBodySimPool; |
| 175 | PxsTransformCache* mTransformCache; |
| 176 | PxReal* mContactDistance; |
| 177 | bool mPCM; |
| 178 | bool mContactCache; |
| 179 | bool mCreateContactStream; // flag to enforce that contacts are stored persistently per workunit. Used for PVD. |
| 180 | bool mCreateAveragePoint; // flag to enforce whether we create average points |
| 181 | #if PX_ENABLE_SIM_STATS |
| 182 | PxU32 mCompressedCacheSize; |
| 183 | PxU32 mNbDiscreteContactPairsWithCacheHits; |
| 184 | PxU32 mNbDiscreteContactPairsWithContacts; |
| 185 | #endif |
| 186 | PxReal mDt; // AP: still needed for ccd |
| 187 | PxU32 mCCDPass; |
| 188 | PxU32 mCCDFaceIndex; |
| 189 | |
| 190 | PxU32 mMaxPatches; |
| 191 | //PxU32 mTotalContactCount; |
| 192 | PxU32 mTotalCompressedCacheSize; |
| 193 | //PxU32 mTotalPatchCount; |
| 194 | |
| 195 | PxcDataStreamPool* mContactStreamPool; |
| 196 | PxcDataStreamPool* mPatchStreamPool; |
| 197 | PxcDataStreamPool* mForceAndIndiceStreamPool; //this stream is used to store the force buffer and triangle index if we are performing mesh/heightfield contact gen |
| 198 | PxcDataStreamPool* mConstraintWriteBackStreamPool; |
| 199 | PxsMaterialManager* mMaterialManager; |
| 200 | private: |
| 201 | // change touch handling. |
| 202 | Cm::BitMap mLocalChangeTouch; |
| 203 | Cm::BitMap mLocalPatchCountChange; |
| 204 | PxU32 mLocalNewTouchCount; |
| 205 | PxU32 mLocalLostTouchCount; |
| 206 | PxU32 mLocalFoundPatchCount; |
| 207 | PxU32 mLocalLostPatchCount; |
| 208 | }; |
| 209 | |
| 210 | } |
| 211 | |
| 212 | #endif |
| 213 | |