feat(physics): wire physx sdk into build
This commit is contained in:
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user