feat(physics): wire physx sdk into build
This commit is contained in:
2144
engine/third_party/physx/source/lowlevel/software/src/PxsCCD.cpp
vendored
Normal file
2144
engine/third_party/physx/source/lowlevel/software/src/PxsCCD.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
64
engine/third_party/physx/source/lowlevel/software/src/PxsContactManager.cpp
vendored
Normal file
64
engine/third_party/physx/source/lowlevel/software/src/PxsContactManager.cpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxsContactManager.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxsContactManager::PxsContactManager(PxU32 index) : mFlags(0), mCmIndex(index)
|
||||
{
|
||||
// PT: TODO: any reason why we don't initialize all members here, e.g. shapeCore pointers?
|
||||
// PT: it might be because of the way we preallocate contact managers in the pipeline, and release the ones
|
||||
// we filtered out. Maybe properly initializing everything "for no reason" in that case is costly.
|
||||
// Still, it is unclear why we initialize *some* of the members there then.
|
||||
mNpUnit.mRigidCore0 = NULL;
|
||||
mNpUnit.mRigidCore1 = NULL;
|
||||
mNpUnit.mRestDistance = 0;
|
||||
mNpUnit.mFrictionDataPtr = NULL;
|
||||
mNpUnit.mFrictionPatchCount = 0;
|
||||
|
||||
mNpUnit.mFlags = 0;
|
||||
mNpUnit.setDominance0(1u);
|
||||
mNpUnit.setDominance1(1u);
|
||||
}
|
||||
|
||||
PxsContactManager::~PxsContactManager()
|
||||
{
|
||||
}
|
||||
|
||||
void PxsContactManager::setCCD(bool enable)
|
||||
{
|
||||
PxU32 flags = mFlags & (~PXS_CM_CCD_CONTACT);
|
||||
if (enable)
|
||||
flags |= PXS_CM_CCD_LINEAR;
|
||||
else
|
||||
flags &= ~PXS_CM_CCD_LINEAR;
|
||||
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
599
engine/third_party/physx/source/lowlevel/software/src/PxsContext.cpp
vendored
Normal file
599
engine/third_party/physx/source/lowlevel/software/src/PxsContext.cpp
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "common/PxProfileZone.h"
|
||||
#include "PxvConfig.h"
|
||||
#include "PxcContactCache.h"
|
||||
#include "PxsRigidBody.h"
|
||||
#include "PxsContactManager.h"
|
||||
#include "PxsContext.h"
|
||||
#include "PxPhysXConfig.h"
|
||||
|
||||
#include "foundation/PxBitMap.h"
|
||||
#include "CmFlushPool.h"
|
||||
|
||||
#include "PxsMaterialManager.h"
|
||||
#include "PxSceneDesc.h"
|
||||
#include "PxsCCD.h"
|
||||
#include "PxvGeometry.h"
|
||||
#include "PxvManager.h"
|
||||
#include "PxsSimpleIslandManager.h"
|
||||
|
||||
#if PX_SUPPORT_GPU_PHYSX
|
||||
#include "PxPhysXGpu.h"
|
||||
#endif
|
||||
|
||||
#include "PxcNpContactPrepShared.h"
|
||||
#include "PxcNpCache.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxsContext::PxsContext(const PxSceneDesc& desc, PxTaskManager* taskManager, Cm::FlushPool& taskPool, PxCudaContextManager* cudaContextManager, PxU32 poolSlabSize, PxU64 contextID) :
|
||||
mNpThreadContextPool (this),
|
||||
mContactManagerPool ("mContactManagerPool", poolSlabSize),
|
||||
mManifoldPool ("mManifoldPool", poolSlabSize),
|
||||
mSphereManifoldPool ("mSphereManifoldPool", poolSlabSize),
|
||||
mContactModifyCallback (NULL),
|
||||
mNpImplementationContext (NULL),
|
||||
mNpFallbackImplementationContext(NULL),
|
||||
mTaskManager (taskManager),
|
||||
mTaskPool (taskPool),
|
||||
mCudaContextManager (cudaContextManager),
|
||||
mPCM (desc.flags & PxSceneFlag::eENABLE_PCM),
|
||||
mContactCache (false),
|
||||
mCreateAveragePoint (desc.flags & PxSceneFlag::eENABLE_AVERAGE_POINT),
|
||||
mContextID (contextID)
|
||||
{
|
||||
clearManagerTouchEvents();
|
||||
mVisualizationCullingBox.setEmpty();
|
||||
|
||||
PxMemZero(mVisualizationParams, sizeof(PxReal) * PxVisualizationParameter::eNUM_VALUES);
|
||||
|
||||
mNpMemBlockPool.init(desc.nbContactDataBlocks, desc.maxNbContactDataBlocks);
|
||||
}
|
||||
|
||||
PxsContext::~PxsContext()
|
||||
{
|
||||
PX_DELETE(mTransformCache);
|
||||
mContactManagerPool.destroy(); //manually destroy the contact manager pool, otherwise pool deletion order is random and we can get into trouble with references into other pools needed during destruction.
|
||||
}
|
||||
|
||||
// =========================== Create methods
|
||||
namespace physx
|
||||
{
|
||||
const bool gEnablePCMCaching[][PxGeometryType::eGEOMETRY_COUNT] =
|
||||
{
|
||||
//eSPHERE,
|
||||
{
|
||||
false, //eSPHERE
|
||||
false, //ePLANE
|
||||
false, //eCAPSULE
|
||||
false, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
true, //eTRIANGLEMESH
|
||||
true, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//ePLANE
|
||||
{
|
||||
false, //eSPHERE
|
||||
false, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//eCAPSULE,
|
||||
{
|
||||
false, //eSPHERE
|
||||
true, //ePLANE
|
||||
false, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
true, //eTRIANGLEMESH
|
||||
true, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//eBOX,
|
||||
{
|
||||
false, //eSPHERE
|
||||
true, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
true, //eTRIANGLEMESH
|
||||
true, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//eCONVEX,
|
||||
{
|
||||
false, //eSPHERE
|
||||
false, //ePLANE
|
||||
false, //eCAPSULE
|
||||
false, //eBOX
|
||||
false, //eCONVEX
|
||||
false, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
false, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
false, //eCUSTOM
|
||||
},
|
||||
|
||||
//eCONVEXMESH,
|
||||
{
|
||||
true, //eSPHERE
|
||||
true, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
true, //eTRIANGLEMESH
|
||||
true, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//ePARTICLESYSTEM
|
||||
{
|
||||
false, //eSPHERE
|
||||
false, //ePLANE
|
||||
false, //eCAPSULE
|
||||
false, //eBOX
|
||||
false, //eCONVEX
|
||||
false, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
false, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
false, //eCUSTOM
|
||||
},
|
||||
|
||||
//eSOFTBODY
|
||||
{
|
||||
false, //eSPHERE
|
||||
false, //ePLANE
|
||||
false, //eCAPSULE
|
||||
false, //eBOX
|
||||
false, //eCONVEX
|
||||
false, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
false, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
false, //eCUSTOM
|
||||
},
|
||||
|
||||
//eTRIANGLEMESH,
|
||||
{
|
||||
true, //eSPHERE
|
||||
false, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//eHEIGHTFIELD,
|
||||
{
|
||||
true, //eSPHERE
|
||||
false, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
true, //eSOFTBODY,
|
||||
false, //eTRIANGLEMESH
|
||||
false, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
},
|
||||
|
||||
//eCUSTOM,
|
||||
{
|
||||
true, //eSPHERE
|
||||
true, //ePLANE
|
||||
true, //eCAPSULE
|
||||
true, //eBOX
|
||||
false, //eCONVEX
|
||||
true, //eCONVEXMESH
|
||||
false, //ePARTICLESYSTEM
|
||||
false, //eSOFTBODY,
|
||||
true, //eTRIANGLEMESH
|
||||
true, //eHEIGHTFIELD
|
||||
true, //eCUSTOM
|
||||
}
|
||||
};
|
||||
PX_COMPILE_TIME_ASSERT(sizeof(gEnablePCMCaching) / sizeof(gEnablePCMCaching[0]) == PxGeometryType::eGEOMETRY_COUNT);
|
||||
}
|
||||
|
||||
void PxsContext::createTransformCache(PxVirtualAllocatorCallback& allocatorCallback)
|
||||
{
|
||||
mTransformCache = PX_NEW(PxsTransformCache)(allocatorCallback);
|
||||
}
|
||||
|
||||
PxsContactManager* PxsContext::createContactManager(PxsContactManager* contactManager, bool useCCD)
|
||||
{
|
||||
PxsContactManager* cm = contactManager? contactManager : mContactManagerPool.get();
|
||||
if(cm)
|
||||
{
|
||||
cm->getWorkUnit().clearCachedState();
|
||||
|
||||
if(!contactManager)
|
||||
setActiveContactManager(cm, useCCD);
|
||||
}
|
||||
else
|
||||
{
|
||||
PX_WARN_ONCE("Reached limit of contact pairs.");
|
||||
}
|
||||
|
||||
return cm;
|
||||
}
|
||||
|
||||
void PxsContext::createCache(Gu::Cache& cache, PxGeometryType::Enum geomType0, PxGeometryType::Enum geomType1)
|
||||
{
|
||||
if(mPCM)
|
||||
{
|
||||
if(gEnablePCMCaching[geomType0][geomType1])
|
||||
{
|
||||
if(geomType0 <= PxGeometryType::eCONVEXMESH && geomType1 <= PxGeometryType::eCONVEXMESH)
|
||||
{
|
||||
if(geomType0 == PxGeometryType::eSPHERE || geomType1 == PxGeometryType::eSPHERE)
|
||||
{
|
||||
Gu::PersistentContactManifold* manifold = mSphereManifoldPool.allocate();
|
||||
PX_PLACEMENT_NEW(manifold, Gu::SpherePersistentContactManifold());
|
||||
cache.setManifold(manifold);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gu::PersistentContactManifold* manifold = mManifoldPool.allocate();
|
||||
PX_PLACEMENT_NEW(manifold, Gu::LargePersistentContactManifold());
|
||||
cache.setManifold(manifold);
|
||||
|
||||
}
|
||||
cache.getManifold().clearManifold();
|
||||
}
|
||||
else
|
||||
{
|
||||
//ML: raised 1 to indicate the manifold is multiManifold which is for contact gen in mesh/height field
|
||||
//cache.manifold = 1;
|
||||
cache.setMultiManifold(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//cache.manifold = 0;
|
||||
cache.mCachedData = NULL;
|
||||
cache.mManifoldFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PxsContext::destroyContactManager(PxsContactManager* cm)
|
||||
{
|
||||
const PxU32 idx = cm->getIndex();
|
||||
if(cm->getCCD())
|
||||
mActiveContactManagersWithCCD.growAndReset(idx);
|
||||
//mActiveContactManager.growAndReset(idx);
|
||||
mContactManagerTouchEvent.growAndReset(idx);
|
||||
mContactManagerPool.put(cm);
|
||||
}
|
||||
|
||||
void PxsContext::destroyCache(Gu::Cache& cache)
|
||||
{
|
||||
if(cache.isManifold())
|
||||
{
|
||||
if(!cache.isMultiManifold())
|
||||
{
|
||||
Gu::PersistentContactManifold& manifold = cache.getManifold();
|
||||
if(manifold.mCapacity == GU_SPHERE_MANIFOLD_CACHE_SIZE)
|
||||
mSphereManifoldPool.deallocate(static_cast<Gu::SpherePersistentContactManifold*>(&manifold));
|
||||
else
|
||||
mManifoldPool.deallocate(static_cast<Gu::LargePersistentContactManifold*>(&manifold));
|
||||
}
|
||||
cache.mCachedData = NULL;
|
||||
cache.mManifoldFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PxsContext::setScratchBlock(void* addr, PxU32 size)
|
||||
{
|
||||
mScratchAllocator.setBlock(addr, size);
|
||||
}
|
||||
|
||||
void PxsContext::shiftOrigin(const PxVec3& shift)
|
||||
{
|
||||
// transform cache
|
||||
mTransformCache->shiftTransforms(-shift);
|
||||
|
||||
#if 0
|
||||
if (getContactCacheFlag())
|
||||
{
|
||||
//Iterate all active contact managers
|
||||
PxBitMap::Iterator it(mActiveContactManager);
|
||||
PxU32 index = it.getNext();
|
||||
while(index != PxBitMap::Iterator::DONE)
|
||||
{
|
||||
PxsContactManager* cm = mContactManagerPool.findByIndexFast(index);
|
||||
|
||||
PxcNpWorkUnit& npwUnit = cm->getWorkUnit();
|
||||
|
||||
// contact cache
|
||||
if(!npwUnit.pairCache.isManifold())
|
||||
{
|
||||
PxU8* contactCachePtr = npwUnit.pairCache.mCachedData;
|
||||
if (contactCachePtr)
|
||||
{
|
||||
PxcLocalContactsCache* lcc;
|
||||
PxU8* contacts = PxcNpCacheRead(npwUnit.pairCache, lcc);
|
||||
#if PX_DEBUG
|
||||
PxcLocalContactsCache testCache;
|
||||
PxU32 testBytes;
|
||||
const PxU8* testPtr = PxcNpCacheRead2(npwUnit.pairCache, testCache, testBytes);
|
||||
#endif
|
||||
lcc->mTransform0.p -= shift;
|
||||
lcc->mTransform1.p -= shift;
|
||||
|
||||
const PxU32 nbContacts = lcc->mNbCachedContacts;
|
||||
const bool sameNormal = lcc->mSameNormal;
|
||||
const bool useFaceIndices = lcc->mUseFaceIndices;
|
||||
|
||||
for(PxU32 i=0; i < nbContacts; i++)
|
||||
{
|
||||
if (i != nbContacts-1)
|
||||
PxPrefetchLine(contacts, 128);
|
||||
|
||||
if(!i || !sameNormal)
|
||||
contacts += sizeof(PxVec3);
|
||||
|
||||
PxVec3* cachedPoint = reinterpret_cast<PxVec3*>(contacts);
|
||||
*cachedPoint -= shift;
|
||||
contacts += sizeof(PxVec3);
|
||||
contacts += sizeof(PxReal);
|
||||
|
||||
if(useFaceIndices)
|
||||
contacts += 2 * sizeof(PxU32);
|
||||
}
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(contacts == (testPtr + testBytes));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
index = it.getNext();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// adjust visualization culling box
|
||||
if(!mVisualizationCullingBox.isEmpty())
|
||||
{
|
||||
mVisualizationCullingBox.minimum -= shift;
|
||||
mVisualizationCullingBox.maximum -= shift;
|
||||
}
|
||||
}
|
||||
|
||||
void PxsContext::swapStreams()
|
||||
{
|
||||
mNpMemBlockPool.swapNpCacheStreams();
|
||||
}
|
||||
|
||||
void PxsContext::mergeCMDiscreteUpdateResults(PxBaseTask* /*continuation*/)
|
||||
{
|
||||
PX_PROFILE_ZONE("Sim.narrowPhaseMerge", mContextID);
|
||||
|
||||
mNpImplementationContext->appendContactManagers();
|
||||
|
||||
//Note: the iterator extracts all the items and returns them to the cache on destruction(for thread safety).
|
||||
PxcThreadCoherentCacheIterator<PxcNpThreadContext, PxcNpContext> threadContextIt(mNpThreadContextPool);
|
||||
|
||||
for(PxcNpThreadContext* threadContext = threadContextIt.getNext(); threadContext; threadContext = threadContextIt.getNext())
|
||||
{
|
||||
mCMTouchEventCount[PXS_LOST_TOUCH_COUNT] += threadContext->getLocalLostTouchCount();
|
||||
mCMTouchEventCount[PXS_NEW_TOUCH_COUNT] += threadContext->getLocalNewTouchCount();
|
||||
|
||||
#if PX_ENABLE_SIM_STATS
|
||||
for(PxU32 i=0;i<PxGeometryType::eGEOMETRY_COUNT;i++)
|
||||
{
|
||||
#if PX_DEBUG
|
||||
for(PxU32 j=0; j<i; j++)
|
||||
PX_ASSERT(!threadContext->mDiscreteContactPairs[i][j]);
|
||||
#endif
|
||||
for(PxU32 j=i; j<PxGeometryType::eGEOMETRY_COUNT; j++)
|
||||
{
|
||||
const PxU32 nb = threadContext->mDiscreteContactPairs[i][j];
|
||||
const PxU32 nbModified = threadContext->mModifiedContactPairs[i][j];
|
||||
mSimStats.mNbDiscreteContactPairs[i][j] += nb;
|
||||
mSimStats.mNbModifiedContactPairs[i][j] += nbModified;
|
||||
mSimStats.mNbDiscreteContactPairsTotal += nb;
|
||||
}
|
||||
}
|
||||
|
||||
mSimStats.mNbDiscreteContactPairsWithCacheHits += threadContext->mNbDiscreteContactPairsWithCacheHits;
|
||||
mSimStats.mNbDiscreteContactPairsWithContacts += threadContext->mNbDiscreteContactPairsWithContacts;
|
||||
|
||||
mSimStats.mTotalCompressedContactSize += threadContext->mCompressedCacheSize;
|
||||
//KS - this data is not available yet
|
||||
//mSimStats.mTotalConstraintSize += threadContext->mConstraintSize;
|
||||
threadContext->clearStats();
|
||||
#else
|
||||
PX_CATCH_UNDEFINED_ENABLE_SIM_STATS
|
||||
#endif
|
||||
mContactManagerTouchEvent.combineInPlace<PxBitMap::OR>(threadContext->getLocalChangeTouch());
|
||||
//mContactManagerPatchChangeEvent.combineInPlace<PxBitMap::OR>(threadContext->getLocalPatchChangeMap());
|
||||
mMaxPatches = PxMax(mMaxPatches, threadContext->mMaxPatches);
|
||||
|
||||
threadContext->mMaxPatches = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PxsContext::updateContactManager(PxReal dt, bool hasContactDistanceChanged, PxBaseTask* continuation, PxBaseTask* firstPassContinuation,
|
||||
Cm::FanoutTask* updateBoundAndShapeTask)
|
||||
{
|
||||
PX_ASSERT(mNpImplementationContext);
|
||||
return mNpImplementationContext->updateContactManager(dt, hasContactDistanceChanged, continuation,
|
||||
firstPassContinuation, updateBoundAndShapeTask);
|
||||
}
|
||||
|
||||
void PxsContext::secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation)
|
||||
{
|
||||
PX_ASSERT(mNpImplementationContext);
|
||||
mNpImplementationContext->secondPassUpdateContactManager(dt, continuation);
|
||||
}
|
||||
|
||||
void PxsContext::fetchUpdateContactManager()
|
||||
{
|
||||
PX_ASSERT(mNpImplementationContext);
|
||||
mNpImplementationContext->fetchUpdateContactManager();
|
||||
mergeCMDiscreteUpdateResults(NULL);
|
||||
}
|
||||
|
||||
void PxsContext::resetThreadContexts()
|
||||
{
|
||||
//Note: the iterator extracts all the items and returns them to the cache on destruction(for thread safety).
|
||||
PxcThreadCoherentCacheIterator<PxcNpThreadContext, PxcNpContext> threadContextIt(mNpThreadContextPool);
|
||||
PxcNpThreadContext* threadContext = threadContextIt.getNext();
|
||||
|
||||
while(threadContext != NULL)
|
||||
{
|
||||
threadContext->reset(mContactManagerTouchEvent.size());
|
||||
threadContext = threadContextIt.getNext();
|
||||
}
|
||||
}
|
||||
|
||||
bool PxsContext::getManagerTouchEventCount(PxU32* newTouch, PxU32* lostTouch, PxU32* ccdTouch) const
|
||||
{
|
||||
if(newTouch)
|
||||
*newTouch = mCMTouchEventCount[PXS_NEW_TOUCH_COUNT];
|
||||
|
||||
if(lostTouch)
|
||||
*lostTouch = mCMTouchEventCount[PXS_LOST_TOUCH_COUNT];
|
||||
|
||||
if(ccdTouch)
|
||||
*ccdTouch = mCMTouchEventCount[PXS_CCD_RETOUCH_COUNT];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PxsContext::fillManagerTouchEvents(PxvContactManagerTouchEvent* newTouch, PxU32& newTouchCount,
|
||||
PxvContactManagerTouchEvent* lostTouch, PxU32& lostTouchCount,
|
||||
PxvContactManagerTouchEvent* ccdTouch, PxU32& ccdTouchCount)
|
||||
{
|
||||
PX_PROFILE_ZONE("PxsContext::fillManagerTouchEvents", mContextID);
|
||||
|
||||
const PxvContactManagerTouchEvent* newTouchStart = newTouch;
|
||||
const PxvContactManagerTouchEvent* lostTouchStart = lostTouch;
|
||||
const PxvContactManagerTouchEvent* ccdTouchStart = ccdTouch;
|
||||
|
||||
const PxvContactManagerTouchEvent* newTouchEnd = newTouch + newTouchCount;
|
||||
const PxvContactManagerTouchEvent* lostTouchEnd = lostTouch + lostTouchCount;
|
||||
const PxvContactManagerTouchEvent* ccdTouchEnd = ccdTouch + ccdTouchCount;
|
||||
|
||||
PX_UNUSED(newTouchEnd);
|
||||
PX_UNUSED(lostTouchEnd);
|
||||
PX_UNUSED(ccdTouchEnd);
|
||||
|
||||
const PxU32* bits = mContactManagerTouchEvent.getWords();
|
||||
if(bits)
|
||||
{
|
||||
// PT: ### bitmap iterator pattern
|
||||
const PxU32 lastSetBit = mContactManagerTouchEvent.findLast();
|
||||
for(PxU32 w = 0; w <= lastSetBit >> 5; ++w)
|
||||
{
|
||||
for(PxU32 b = bits[w]; b; b &= b-1)
|
||||
{
|
||||
const PxU32 index = PxU32(w<<5|PxLowestSetBit(b));
|
||||
|
||||
PxsContactManager* cm = mContactManagerPool.findByIndexFast(index);
|
||||
|
||||
if(cm->getTouchStatus())
|
||||
{
|
||||
if(!cm->getHasCCDRetouch())
|
||||
{
|
||||
PX_ASSERT(newTouch < newTouchEnd);
|
||||
newTouch->setCMTouchEventUserData(cm->getShapeInteraction());
|
||||
newTouch++;
|
||||
}
|
||||
else
|
||||
{
|
||||
PX_ASSERT(ccdTouch);
|
||||
PX_ASSERT(ccdTouch < ccdTouchEnd);
|
||||
ccdTouch->setCMTouchEventUserData(cm->getShapeInteraction());
|
||||
cm->clearCCDRetouch();
|
||||
ccdTouch++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PX_ASSERT(lostTouch < lostTouchEnd);
|
||||
lostTouch->setCMTouchEventUserData(cm->getShapeInteraction());
|
||||
lostTouch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newTouchCount = PxU32(newTouch - newTouchStart);
|
||||
lostTouchCount = PxU32(lostTouch - lostTouchStart);
|
||||
ccdTouchCount = PxU32(ccdTouch - ccdTouchStart);
|
||||
}
|
||||
|
||||
void PxsContext::beginUpdate()
|
||||
{
|
||||
#if PX_ENABLE_SIM_STATS
|
||||
mSimStats.clearAll();
|
||||
#else
|
||||
PX_CATCH_UNDEFINED_ENABLE_SIM_STATS
|
||||
#endif
|
||||
}
|
||||
|
||||
58
engine/third_party/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp
vendored
Normal file
58
engine/third_party/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxsMemoryManager.h"
|
||||
#include "foundation/PxAllocator.h"
|
||||
#include "foundation/PxArray.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
namespace
|
||||
{
|
||||
class PxsDefaultMemoryAllocator : public PxVirtualAllocatorCallback
|
||||
{
|
||||
public:
|
||||
virtual void* allocate(size_t size, int, const char*, int) PX_OVERRIDE PX_FINAL { return PX_ALLOC(size, "unused"); }
|
||||
virtual void deallocate(void* ptr) PX_OVERRIDE PX_FINAL { PX_FREE(ptr); }
|
||||
};
|
||||
|
||||
class PxsDefaultMemoryManager : public PxsMemoryManager
|
||||
{
|
||||
public:
|
||||
// PxsMemoryManager
|
||||
virtual PxVirtualAllocatorCallback* getHostMemoryAllocator() PX_OVERRIDE PX_FINAL { return &mDefaultMemoryAllocator; }
|
||||
virtual PxVirtualAllocatorCallback* getDeviceMemoryAllocator() PX_OVERRIDE PX_FINAL { return NULL; }
|
||||
//~PxsMemoryManager
|
||||
PxsDefaultMemoryAllocator mDefaultMemoryAllocator;
|
||||
};
|
||||
}
|
||||
|
||||
PxsMemoryManager* physx::createDefaultMemoryManager()
|
||||
{
|
||||
return PX_NEW(PxsDefaultMemoryManager);
|
||||
}
|
||||
2175
engine/third_party/physx/source/lowlevel/software/src/PxsIslandSim.cpp
vendored
Normal file
2175
engine/third_party/physx/source/lowlevel/software/src/PxsIslandSim.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1033
engine/third_party/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp
vendored
Normal file
1033
engine/third_party/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
431
engine/third_party/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp
vendored
Normal file
431
engine/third_party/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp
vendored
Normal file
@@ -0,0 +1,431 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "common/PxProfileZone.h"
|
||||
#include "PxsSimpleIslandManager.h"
|
||||
#include "foundation/PxSort.h"
|
||||
#include "PxsContactManager.h"
|
||||
#include "CmTask.h"
|
||||
#include "DyVArticulation.h"
|
||||
|
||||
using namespace physx;
|
||||
using namespace IG;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ThirdPassTask::ThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager, IslandSim& islandSim) : Cm::Task(contextID), mIslandManager(islandManager), mIslandSim(islandSim)
|
||||
{
|
||||
}
|
||||
|
||||
void ThirdPassTask::runInternal()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.thirdPassIslandGen", mContextID);
|
||||
|
||||
mIslandSim.removeDestroyedEdges();
|
||||
mIslandSim.processLostEdges(mIslandManager.mDestroyedNodes, true, true, mIslandManager.mMaxDirtyNodesPerFrame);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PostThirdPassTask::PostThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager) : Cm::Task(contextID), mIslandManager(islandManager)
|
||||
{
|
||||
}
|
||||
|
||||
void PostThirdPassTask::runInternal()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.postThirdPassIslandGen", mContextID);
|
||||
|
||||
for (PxU32 a = 0; a < mIslandManager.mDestroyedNodes.size(); ++a)
|
||||
mIslandManager.mNodeHandles.freeHandle(mIslandManager.mDestroyedNodes[a].index());
|
||||
|
||||
mIslandManager.mDestroyedNodes.clear();
|
||||
|
||||
for (PxU32 a = 0; a < mIslandManager.mDestroyedEdges.size(); ++a)
|
||||
mIslandManager.mEdgeHandles.freeHandle(mIslandManager.mDestroyedEdges[a]);
|
||||
|
||||
mIslandManager.mDestroyedEdges.clear();
|
||||
|
||||
PX_ASSERT(mIslandManager.validateDeactivations());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleIslandManager::SimpleIslandManager(bool useEnhancedDeterminism, bool gpu, PxU64 contextID) :
|
||||
mDestroyedNodes ("mDestroyedNodes"),
|
||||
mDestroyedEdges ("mDestroyedEdges"),
|
||||
mAccurateIslandManager (mCpuData, gpu ? &mGpuData : NULL, contextID),
|
||||
mSpeculativeIslandManager (mCpuData, NULL, contextID),
|
||||
mSpeculativeThirdPassTask (contextID, *this, mSpeculativeIslandManager),
|
||||
mAccurateThirdPassTask (contextID, *this, mAccurateIslandManager),
|
||||
mPostThirdPassTask (contextID, *this),
|
||||
mContextID (contextID),
|
||||
mGPU (gpu)
|
||||
{
|
||||
if(gpu)
|
||||
mGpuData.mFirstPartitionEdges.resize(1024);
|
||||
mMaxDirtyNodesPerFrame = useEnhancedDeterminism ? 0xFFFFFFFF : 1000u;
|
||||
}
|
||||
|
||||
SimpleIslandManager::~SimpleIslandManager()
|
||||
{
|
||||
}
|
||||
|
||||
PxNodeIndex SimpleIslandManager::addNode(bool isActive, bool isKinematic, Node::NodeType type, void* object)
|
||||
{
|
||||
const PxU32 handle = mNodeHandles.getHandle();
|
||||
const PxNodeIndex nodeIndex(handle);
|
||||
mAccurateIslandManager .addNode(isActive, isKinematic, type, nodeIndex, object);
|
||||
mSpeculativeIslandManager .addNode(isActive, isKinematic, type, nodeIndex, object);
|
||||
return nodeIndex;
|
||||
}
|
||||
|
||||
void SimpleIslandManager::removeNode(const PxNodeIndex index)
|
||||
{
|
||||
PX_ASSERT(mNodeHandles.isValidHandle(index.index()));
|
||||
mDestroyedNodes.pushBack(index);
|
||||
}
|
||||
|
||||
EdgeIndex SimpleIslandManager::addEdge(void* edge, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction)
|
||||
{
|
||||
const EdgeIndex handle = mEdgeHandles.getHandle();
|
||||
|
||||
const PxU32 nodeIds = 2 * handle;
|
||||
if (mCpuData.mEdgeNodeIndices.size() == nodeIds)
|
||||
{
|
||||
PX_PROFILE_ZONE("ReserveEdges", mContextID);
|
||||
const PxU32 newSize = nodeIds + 2048;
|
||||
mCpuData.mEdgeNodeIndices.resize(newSize);
|
||||
// PT: newSize is for mEdgeNodeIndices which holds two indices per edge. We only need half that size for regular edge-indexed buffers.
|
||||
mAuxCpuData.mConstraintOrCm.resize(newSize/2);
|
||||
mInteractions.resize(newSize/2);
|
||||
}
|
||||
|
||||
mCpuData.mEdgeNodeIndices[nodeIds] = nodeHandle1;
|
||||
mCpuData.mEdgeNodeIndices[nodeIds + 1] = nodeHandle2;
|
||||
mAuxCpuData.mConstraintOrCm[handle] = edge;
|
||||
mInteractions[handle] = interaction;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
EdgeIndex SimpleIslandManager::resizeEdgeArrays(EdgeIndex handle, bool flag)
|
||||
{
|
||||
if(mConnectedMap.size() == handle)
|
||||
mConnectedMap.resize(2 * (handle + 1));
|
||||
|
||||
if(mGPU && mGpuData.mFirstPartitionEdges.capacity() == handle)
|
||||
mGpuData.mFirstPartitionEdges.resize(2 * (handle + 1));
|
||||
|
||||
if(flag)
|
||||
mConnectedMap.reset(handle); // PT: for contact manager
|
||||
else
|
||||
mConnectedMap.set(handle); // PT: for constraint
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PT: the two functions below are to replicate SimpleIslandManager::addContactManager() multi-threaded
|
||||
void SimpleIslandManager::preallocateContactManagers(PxU32 nb, EdgeIndex* handles)
|
||||
{
|
||||
// PT: part from SimpleIslandManager::addContactManager / addEdge
|
||||
EdgeIndex maxHandle = 0;
|
||||
{
|
||||
{
|
||||
PX_PROFILE_ZONE("getHandles", mContextID);
|
||||
for(PxU32 i=0;i<nb;i++)
|
||||
{
|
||||
const EdgeIndex handle = mEdgeHandles.getHandle(); // PT: TODO: better version
|
||||
handles[i] = handle;
|
||||
if(handle>maxHandle)
|
||||
maxHandle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
const PxU32 nodeIds = 2 * maxHandle;
|
||||
if (mCpuData.mEdgeNodeIndices.size() <= nodeIds)
|
||||
{
|
||||
PX_PROFILE_ZONE("ReserveEdges", mContextID);
|
||||
const PxU32 newSize = nodeIds + 2048;
|
||||
mCpuData.mEdgeNodeIndices.resize(newSize);
|
||||
mAuxCpuData.mConstraintOrCm.resize(newSize/2);
|
||||
mInteractions.resize(newSize/2);
|
||||
}
|
||||
}
|
||||
|
||||
// PT: part from SimpleIslandManager::addContactManager / mSpeculativeIslandManager.addConnection()
|
||||
mSpeculativeIslandManager.preallocateConnections(maxHandle);
|
||||
|
||||
// PT: part from SimpleIslandManager::addContactManager / resizeEdgeArrays
|
||||
// PT: TODO: refactor with regular code
|
||||
if(mConnectedMap.size() <= maxHandle)
|
||||
mConnectedMap.resize(2 * (maxHandle + 1));
|
||||
|
||||
if(mGPU && mGpuData.mFirstPartitionEdges.capacity() <= maxHandle)
|
||||
mGpuData.mFirstPartitionEdges.resize(2 * (maxHandle + 1));
|
||||
}
|
||||
|
||||
bool SimpleIslandManager::addPreallocatedContactManager(EdgeIndex handle, PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, Edge::EdgeType edgeType)
|
||||
{
|
||||
// PT: part of SimpleIslandManager::addEdge that can be multi-threaded
|
||||
{
|
||||
const PxU32 nodeIds = 2 * handle;
|
||||
mCpuData.mEdgeNodeIndices[nodeIds] = nodeHandle1;
|
||||
mCpuData.mEdgeNodeIndices[nodeIds + 1] = nodeHandle2;
|
||||
mAuxCpuData.mConstraintOrCm[handle] = manager;
|
||||
mInteractions[handle] = interaction;
|
||||
}
|
||||
|
||||
// PT: part of mSpeculativeIslandManager.addConnection() that can be multi-threaded
|
||||
bool status = mSpeculativeIslandManager.addConnectionPreallocated(nodeHandle1, nodeHandle2, edgeType, handle);
|
||||
if (manager)
|
||||
manager->getWorkUnit().mEdgeIndex = handle;
|
||||
|
||||
// PT: part of SimpleIslandManager::addContactManager / resizeEdgeArrays() for contact manager
|
||||
{
|
||||
// PT: this is effectively just: mConnectedMap.reset(handle); // PT: for contact manager
|
||||
// So just this, with atomics: map[index >> 5] &= ~(1 << (index & 31));
|
||||
PxU32* map = mConnectedMap.getWords() + (handle >> 5);
|
||||
PxAtomicAnd(reinterpret_cast<volatile PxI32*>(map), ~(1 << (handle & 31)));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, Edge::EdgeType edgeType)
|
||||
{
|
||||
const EdgeIndex handle = addEdge(manager, nodeHandle1, nodeHandle2, interaction);
|
||||
|
||||
mSpeculativeIslandManager.addConnection(nodeHandle1, nodeHandle2, edgeType, handle);
|
||||
|
||||
if (manager)
|
||||
manager->getWorkUnit().mEdgeIndex = handle;
|
||||
|
||||
return resizeEdgeArrays(handle, true);
|
||||
}
|
||||
|
||||
EdgeIndex SimpleIslandManager::addConstraint(Dy::Constraint* constraint, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction)
|
||||
{
|
||||
const EdgeIndex handle = addEdge(constraint, nodeHandle1, nodeHandle2, interaction);
|
||||
|
||||
mAccurateIslandManager.addConnection(nodeHandle1, nodeHandle2, Edge::eCONSTRAINT, handle);
|
||||
mSpeculativeIslandManager.addConnection(nodeHandle1, nodeHandle2, Edge::eCONSTRAINT, handle);
|
||||
|
||||
return resizeEdgeArrays(handle, false);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::activateNode(PxNodeIndex index)
|
||||
{
|
||||
mAccurateIslandManager.activateNode(index);
|
||||
mSpeculativeIslandManager.activateNode(index);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::deactivateNode(PxNodeIndex index)
|
||||
{
|
||||
mAccurateIslandManager.deactivateNode(index);
|
||||
mSpeculativeIslandManager.deactivateNode(index);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::putNodeToSleep(PxNodeIndex index)
|
||||
{
|
||||
mAccurateIslandManager.putNodeToSleep(index);
|
||||
mSpeculativeIslandManager.putNodeToSleep(index);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::removeConnection(EdgeIndex edgeIndex)
|
||||
{
|
||||
if(edgeIndex == IG_INVALID_EDGE)
|
||||
return;
|
||||
mDestroyedEdges.pushBack(edgeIndex);
|
||||
mSpeculativeIslandManager.removeConnection(edgeIndex);
|
||||
if(mConnectedMap.test(edgeIndex))
|
||||
{
|
||||
mAccurateIslandManager.removeConnection(edgeIndex);
|
||||
mConnectedMap.reset(edgeIndex);
|
||||
}
|
||||
|
||||
mAuxCpuData.mConstraintOrCm[edgeIndex] = NULL;
|
||||
mInteractions[edgeIndex] = NULL;
|
||||
}
|
||||
|
||||
void SimpleIslandManager::firstPassIslandGen()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.firstPassIslandGen", mContextID);
|
||||
|
||||
mSpeculativeIslandManager.clearDeactivations();
|
||||
|
||||
mSpeculativeIslandManager.wakeIslands();
|
||||
mSpeculativeIslandManager.processNewEdges();
|
||||
|
||||
mSpeculativeIslandManager.removeDestroyedEdges();
|
||||
mSpeculativeIslandManager.processLostEdges(mDestroyedNodes, false, false, mMaxDirtyNodesPerFrame);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::additionalSpeculativeActivation()
|
||||
{
|
||||
mSpeculativeIslandManager.wakeIslands2();
|
||||
}
|
||||
|
||||
void SimpleIslandManager::secondPassIslandGen()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.secondPassIslandGen", mContextID);
|
||||
|
||||
secondPassIslandGenPart1();
|
||||
secondPassIslandGenPart2();
|
||||
}
|
||||
|
||||
// PT: first part of secondPassIslandGen().
|
||||
// We can put in this function any code that does not modify data we read in PxgIncrementalPartition::processLostFoundPatches().
|
||||
// The two will overlap / run in parallel.
|
||||
void SimpleIslandManager::secondPassIslandGenPart1()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.secondPassIslandGenPart1", mContextID);
|
||||
|
||||
mAccurateIslandManager.wakeIslands();
|
||||
mAccurateIslandManager.processNewEdges();
|
||||
}
|
||||
|
||||
// PT: second part of secondPassIslandGen(). Will run serially after PxgIncrementalPartition::processLostFoundPatches().
|
||||
void SimpleIslandManager::secondPassIslandGenPart2()
|
||||
{
|
||||
PX_PROFILE_ZONE("Basic.secondPassIslandGenPart2", mContextID);
|
||||
|
||||
// PT: TODO: analyze remaining code below, maybe we can move more of it to Part1
|
||||
mAccurateIslandManager.removeDestroyedEdges();
|
||||
mAccurateIslandManager.processLostEdges(mDestroyedNodes, false, false, mMaxDirtyNodesPerFrame);
|
||||
|
||||
for(PxU32 a = 0; a < mDestroyedNodes.size(); ++a)
|
||||
mNodeHandles.freeHandle(mDestroyedNodes[a].index());
|
||||
|
||||
mDestroyedNodes.clear();
|
||||
//mDestroyedEdges.clear();
|
||||
}
|
||||
|
||||
void SimpleIslandManager::thirdPassIslandGen(PxBaseTask* continuation)
|
||||
{
|
||||
mAccurateIslandManager.clearDeactivations();
|
||||
|
||||
mPostThirdPassTask.setContinuation(continuation);
|
||||
|
||||
mSpeculativeThirdPassTask.setContinuation(&mPostThirdPassTask);
|
||||
mAccurateThirdPassTask.setContinuation(&mPostThirdPassTask);
|
||||
|
||||
mSpeculativeThirdPassTask.removeReference();
|
||||
mAccurateThirdPassTask.removeReference();
|
||||
|
||||
mPostThirdPassTask.removeReference();
|
||||
|
||||
//PX_PROFILE_ZONE("Basic.thirdPassIslandGen", mContextID);
|
||||
//mSpeculativeIslandManager.removeDestroyedEdges();
|
||||
//mSpeculativeIslandManager.processLostEdges(mDestroyedNodes, true, true);
|
||||
|
||||
//mAccurateIslandManager.removeDestroyedEdges();
|
||||
//mAccurateIslandManager.processLostEdges(mDestroyedNodes, true, true);
|
||||
}
|
||||
|
||||
bool SimpleIslandManager::validateDeactivations() const
|
||||
{
|
||||
//This method sanity checks the deactivations produced by third-pass island gen. Specifically, it ensures that any bodies that
|
||||
//the speculative IG wants to deactivate are also candidates for deactivation in the accurate island gen. In practice, both should be the case. If this fails, something went wrong...
|
||||
|
||||
const PxNodeIndex* const nodeIndices = mSpeculativeIslandManager.getNodesToDeactivate(Node::eRIGID_BODY_TYPE);
|
||||
const PxU32 nbNodesToDeactivate = mSpeculativeIslandManager.getNbNodesToDeactivate(Node::eRIGID_BODY_TYPE);
|
||||
|
||||
for(PxU32 i = 0; i < nbNodesToDeactivate; ++i)
|
||||
{
|
||||
//Node is active in accurate sim => mismatch between accurate and inaccurate sim!
|
||||
const Node& node = mAccurateIslandManager.getNode(nodeIndices[i]);
|
||||
const Node& speculativeNode = mSpeculativeIslandManager.getNode(nodeIndices[i]);
|
||||
//KS - we need to verify that the bodies in the "deactivating" list are still candidates for deactivation. There are cases where they may not no longer be candidates, e.g. if the application
|
||||
//put bodies to sleep and activated them
|
||||
if(node.isActive() && !speculativeNode.isActive())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleIslandManager::checkInternalConsistency()
|
||||
{
|
||||
return mAccurateIslandManager.checkInternalConsistency() && mSpeculativeIslandManager.checkInternalConsistency();
|
||||
}
|
||||
|
||||
void SimpleIslandManager::setEdgeConnected(EdgeIndex edgeIndex, Edge::EdgeType edgeType)
|
||||
{
|
||||
if(!mConnectedMap.test(edgeIndex))
|
||||
{
|
||||
mAccurateIslandManager.addConnection(mCpuData.mEdgeNodeIndices[edgeIndex * 2], mCpuData.mEdgeNodeIndices[edgeIndex * 2 + 1], edgeType, edgeIndex);
|
||||
mConnectedMap.set(edgeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleIslandManager::setEdgeDisconnected(EdgeIndex edgeIndex)
|
||||
{
|
||||
if(mConnectedMap.test(edgeIndex))
|
||||
{
|
||||
//PX_ASSERT(!mAccurateIslandManager.getEdge(edgeIndex).isInDirtyList());
|
||||
mAccurateIslandManager.removeConnection(edgeIndex);
|
||||
mConnectedMap.reset(edgeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleIslandManager::deactivateEdge(const EdgeIndex edgeIndex)
|
||||
{
|
||||
if (mGPU && mGpuData.mFirstPartitionEdges[edgeIndex])
|
||||
{
|
||||
//this is the partition edges created/updated by the gpu solver
|
||||
mGpuData.mDestroyedPartitionEdges.pushBack(mGpuData.mFirstPartitionEdges[edgeIndex]);
|
||||
mGpuData.mFirstPartitionEdges[edgeIndex] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleIslandManager::setEdgeRigidCM(const EdgeIndex edgeIndex, PxsContactManager* cm)
|
||||
{
|
||||
mAuxCpuData.mConstraintOrCm[edgeIndex] = cm;
|
||||
cm->getWorkUnit().mEdgeIndex = edgeIndex;
|
||||
}
|
||||
|
||||
void SimpleIslandManager::clearEdgeRigidCM(const EdgeIndex edgeIndex)
|
||||
{
|
||||
mAuxCpuData.mConstraintOrCm[edgeIndex] = NULL;
|
||||
deactivateEdge(edgeIndex);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::setKinematic(PxNodeIndex nodeIndex)
|
||||
{
|
||||
mAccurateIslandManager.setKinematic(nodeIndex);
|
||||
mSpeculativeIslandManager.setKinematic(nodeIndex);
|
||||
}
|
||||
|
||||
void SimpleIslandManager::setDynamic(PxNodeIndex nodeIndex)
|
||||
{
|
||||
mAccurateIslandManager.setDynamic(nodeIndex);
|
||||
mSpeculativeIslandManager.setDynamic(nodeIndex);
|
||||
}
|
||||
Reference in New Issue
Block a user