feat(physics): wire physx sdk into build
This commit is contained in:
845
engine/third_party/physx/source/gpusimulationcontroller/src/PxgBodySimManager.cpp
vendored
Normal file
845
engine/third_party/physx/source/gpusimulationcontroller/src/PxgBodySimManager.cpp
vendored
Normal file
@@ -0,0 +1,845 @@
|
||||
// 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.
|
||||
|
||||
#include "PxgBodySimManager.h"
|
||||
#include "PxvDynamics.h"
|
||||
#include "PxsRigidBody.h"
|
||||
#include "PxgBodySim.h"
|
||||
#include "foundation/PxFPU.h"
|
||||
#include "foundation/PxAtomic.h"
|
||||
#include "DyFeatherstoneArticulation.h"
|
||||
#include "DyDeformableSurface.h"
|
||||
#include "DyDeformableVolume.h"
|
||||
#include "DyParticleSystem.h"
|
||||
|
||||
#define BODY_SIM_VALIDATE 0
|
||||
|
||||
using namespace physx;
|
||||
|
||||
void PxgBodySimManager::addBody(PxsRigidBody* rigidBody, const PxU32 nodeIndex)
|
||||
{
|
||||
if (mUpdatedMap.boundedTest(nodeIndex))
|
||||
return;
|
||||
|
||||
if (mBodies.capacity() <= nodeIndex)
|
||||
{
|
||||
mBodies.resize(2 * nodeIndex + 1);
|
||||
}
|
||||
|
||||
mBodies[nodeIndex] = reinterpret_cast<void*>(rigidBody);
|
||||
|
||||
mUpdatedMap.growAndSet(nodeIndex);
|
||||
mNewOrUpdatedBodySims.pushBack(nodeIndex);
|
||||
mTotalNumBodies = PxMax(mTotalNumBodies, nodeIndex + 1);
|
||||
|
||||
mStaticConstraints.reserve(mTotalNumBodies);
|
||||
mStaticConstraints.resize(mTotalNumBodies);
|
||||
|
||||
PxgStaticConstraints& constraints = mStaticConstraints[nodeIndex];
|
||||
constraints.mStaticContacts.forceSize_Unsafe(0);
|
||||
constraints.mStaticJoints.forceSize_Unsafe(0);
|
||||
|
||||
// raise first DMA to GPU flag so we can handle body updates correctly with direct GPU API
|
||||
rigidBody->mInternalFlags |= PxsRigidBody::eFIRST_BODY_COPY_GPU;
|
||||
|
||||
#if BODY_SIM_VALIDATE
|
||||
else
|
||||
{
|
||||
bool found = false;
|
||||
for (PxU32 i = 0; i < mNewBodySims.size(); ++i)
|
||||
{
|
||||
if (mNewBodySims[i] == nodeIndex)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PX_ASSERT(found);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PxgBodySimManager::~PxgBodySimManager()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////articulation
|
||||
void PxgBodySimManager::addArticulation(Dy::FeatherstoneArticulation* articulation, const PxU32 nodeIndex, bool OmniPVDRecordDirectGPUAPI)
|
||||
{
|
||||
if (mUpdatedMap.boundedTest(nodeIndex))
|
||||
return;
|
||||
|
||||
if (mBodies.capacity() <= nodeIndex)
|
||||
{
|
||||
mBodies.resize(2 * nodeIndex + 1);
|
||||
}
|
||||
|
||||
mBodies[nodeIndex] = reinterpret_cast<void*>(articulation);
|
||||
|
||||
mUpdatedMap.growAndSet(nodeIndex);
|
||||
PxgArticulationIndices index;
|
||||
index.nodeIndex = nodeIndex;
|
||||
index.remapIndex = mArticulationIdPool.getNewID();
|
||||
|
||||
Dy::ArticulationCore* core = articulation->getCore();
|
||||
core->gpuRemapIndex = index.remapIndex;
|
||||
|
||||
mNewArticulationSims.pushBack(index);
|
||||
//Mark as in dirty list so that it doesn't appear in update list!
|
||||
articulation->mGPUDirtyFlags |= Dy::ArticulationDirtyFlag::eIN_DIRTY_LIST;
|
||||
|
||||
mNodeToRemapMap.insert(nodeIndex, index.remapIndex);
|
||||
#if PX_SUPPORT_OMNI_PVD
|
||||
if (OmniPVDRecordDirectGPUAPI)
|
||||
{
|
||||
mRemapToNodeMap.insert(index.remapIndex, nodeIndex);
|
||||
}
|
||||
#else
|
||||
PX_UNUSED(OmniPVDRecordDirectGPUAPI);
|
||||
#endif
|
||||
//articulation->setGpuRemapId(index.remapIndex);
|
||||
|
||||
mTotalNumBodies = PxMax(mTotalNumBodies, nodeIndex + 1);
|
||||
mTotalNumArticulations = PxMax(mTotalNumArticulations, index.remapIndex + 1);
|
||||
|
||||
mStaticConstraints.resize(mTotalNumBodies); //Shared between RBs and articulations...
|
||||
mArticulationSelfConstraints.resize(mTotalNumArticulations);
|
||||
|
||||
PxgStaticConstraints& constraints = mStaticConstraints[nodeIndex];
|
||||
constraints.mStaticContacts.forceSize_Unsafe(0);
|
||||
constraints.mStaticContacts.reserve(articulation->getBodyCount()); //We expect a contact per-body, so bump up the initial reservation
|
||||
constraints.mStaticJoints.forceSize_Unsafe(0);
|
||||
|
||||
PxgArticulationSelfConstraints& selfConstraints = mArticulationSelfConstraints[index.remapIndex];
|
||||
selfConstraints.mSelfContacts.forceSize_Unsafe(0);
|
||||
selfConstraints.mSelfJoints.forceSize_Unsafe(0);
|
||||
}
|
||||
|
||||
void PxgBodySimManager::updateArticulation(Dy::FeatherstoneArticulation* articulation, const PxU32 nodeIndex)
|
||||
{
|
||||
if (!(articulation->mGPUDirtyFlags & Dy::ArticulationDirtyFlag::eIN_DIRTY_LIST))
|
||||
{
|
||||
const PxHashMap<PxU32, PxU32>::Entry* entry = mNodeToRemapMap.find(nodeIndex);
|
||||
//If entry is not there, it means that this articulation is pending insertion (added to scene, but not yet simulated). In this
|
||||
//case, it will not need to appear in the update list
|
||||
if (entry)
|
||||
{
|
||||
articulation->mGPUDirtyFlags |= Dy::ArticulationDirtyFlag::eIN_DIRTY_LIST;
|
||||
PxU32 index = entry->second;
|
||||
|
||||
PxgArticulationUpdate update;
|
||||
update.articulationIndex = index;
|
||||
update.articulation = articulation;
|
||||
//KS - we don't write out startIndex - this happens later in the heavy-lifting code that actually writes out data from the articulation.
|
||||
//We defer this until during the frame because it is quite common that the user might update multiple properties and we would prefer to batc
|
||||
|
||||
mUpdatedArticulations.pushBack(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addStaticArticulationContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(nodeIndex.isArticulation());
|
||||
PxgStaticConstraints& staticConstraints = mStaticConstraints[nodeIndex.index()];
|
||||
|
||||
if (staticConstraints.mStaticContacts.size() < PxgStaticConstraints::MaxConstraints)
|
||||
{
|
||||
PxgStaticConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID = nodeIndex.articulationLinkId();
|
||||
PxU32 i = 0;
|
||||
PxU32 count = staticConstraints.mStaticContacts.size();
|
||||
for (; i < count; ++i)
|
||||
{
|
||||
if (con.linkID <= staticConstraints.mStaticContacts[i].linkID)
|
||||
break;
|
||||
}
|
||||
staticConstraints.mStaticContacts.resizeUninitialized(count + 1);
|
||||
|
||||
for (PxU32 j = count; j > i; --j)
|
||||
{
|
||||
staticConstraints.mStaticContacts[j] = staticConstraints.mStaticContacts[j - 1];
|
||||
}
|
||||
|
||||
staticConstraints.mStaticContacts[i] = con;
|
||||
mMaxStaticArticContacts = PxMax(staticConstraints.mStaticContacts.size(), mMaxStaticArticContacts);
|
||||
mTotalStaticArticContacts++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static bool remove(PxU32 uniqueIndex, PxArray<T>& container, PxU32& counter)
|
||||
{
|
||||
// PT: one of these loops was checking the indices in decreasing order for no clear reason (introduced in CL 30572881)
|
||||
PxU32 size = container.size();
|
||||
for(PxU32 i=0; i<size; i++)
|
||||
{
|
||||
if(container[i].uniqueId == uniqueIndex)
|
||||
{
|
||||
//Need to maintain order for batching to work!
|
||||
container.remove(i); // PT: beware, this is an actual shift
|
||||
counter--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeStaticArticulationContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(nodeIndex.isArticulation());
|
||||
return remove(uniqueIndex, mStaticConstraints[nodeIndex.index()].mStaticContacts, mTotalStaticArticContacts);
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addStaticArticulationJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(nodeIndex.isArticulation());
|
||||
PxgStaticConstraints& staticConstraints = mStaticConstraints[nodeIndex.index()];
|
||||
|
||||
if (staticConstraints.mStaticJoints.size() < PxgStaticConstraints::MaxConstraints)
|
||||
{
|
||||
PxgStaticConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID = nodeIndex.articulationLinkId();
|
||||
//We need to find where to insert this contact into the articulation. The assumption is that we will not have a very
|
||||
//large number of static constraints, so we can just do a linear search. If this turns out to be a problem, we can try
|
||||
//something like binary search...
|
||||
PxU32 i = 0;
|
||||
PxU32 count = staticConstraints.mStaticJoints.size();
|
||||
for (; i < count; ++i)
|
||||
{
|
||||
if (con.linkID <= staticConstraints.mStaticJoints[i].linkID)
|
||||
break;
|
||||
}
|
||||
staticConstraints.mStaticJoints.resizeUninitialized(count + 1);
|
||||
|
||||
for (PxU32 j = count; j > i; --j)
|
||||
{
|
||||
staticConstraints.mStaticJoints[j] = staticConstraints.mStaticJoints[j - 1];
|
||||
}
|
||||
|
||||
staticConstraints.mStaticJoints[i] = con;
|
||||
|
||||
mMaxStaticArticJoints = PxMax(mMaxStaticArticJoints, count + 1);
|
||||
mTotalStaticArticJoints++;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeStaticArticulationJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(nodeIndex.isArticulation());
|
||||
return remove(uniqueIndex, mStaticConstraints[nodeIndex.index()].mStaticJoints, mTotalStaticArticJoints);
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addStaticRBContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PxgStaticConstraints& staticConstraints = mStaticConstraints[nodeIndex.index()];
|
||||
{
|
||||
PX_ASSERT(!nodeIndex.isArticulation());
|
||||
PxgStaticConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID = 0;
|
||||
staticConstraints.mStaticContacts.pushBack(con);
|
||||
mMaxStaticRBContacts = PxMax(staticConstraints.mStaticContacts.size(), mMaxStaticRBContacts);
|
||||
mTotalStaticRBContacts++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeStaticRBContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(!nodeIndex.isArticulation());
|
||||
return remove(uniqueIndex, mStaticConstraints[nodeIndex.index()].mStaticContacts, mTotalStaticRBContacts);
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addStaticRBJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(!nodeIndex.isArticulation());
|
||||
PxgStaticConstraints& staticConstraints = mStaticConstraints[nodeIndex.index()];
|
||||
|
||||
{
|
||||
PxgStaticConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID = 0;
|
||||
|
||||
staticConstraints.mStaticJoints.pushBack(con);
|
||||
|
||||
mMaxStaticRBJoints = PxMax(mMaxStaticRBJoints, staticConstraints.mStaticJoints.size());
|
||||
mTotalStaticRBJoints++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeStaticRBJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex)
|
||||
{
|
||||
PX_ASSERT(!nodeIndex.isArticulation());
|
||||
return remove(uniqueIndex, mStaticConstraints[nodeIndex.index()].mStaticJoints, mTotalStaticRBJoints);
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addSelfArticulationContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex0, const PxNodeIndex nodeIndex1)
|
||||
{
|
||||
PxU32 remapIndex = mNodeToRemapMap[nodeIndex0.index()];
|
||||
PxgArticulationSelfConstraints& selfConstraints = mArticulationSelfConstraints[remapIndex];
|
||||
if (selfConstraints.mSelfContacts.size() < PxgArticulationSelfConstraints::MaxConstraints)
|
||||
{
|
||||
PxgSelfConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID0 = nodeIndex0.articulationLinkId();
|
||||
con.linkID1 = nodeIndex1.articulationLinkId();
|
||||
|
||||
PxU32 count = selfConstraints.mSelfContacts.size();
|
||||
|
||||
selfConstraints.mSelfContacts.resizeUninitialized(count + 1);
|
||||
|
||||
PxU32 i = count;
|
||||
|
||||
selfConstraints.mSelfContacts[i] = con;
|
||||
mMaxSelfArticContacts = PxMax(selfConstraints.mSelfContacts.size(), mMaxSelfArticContacts);
|
||||
mTotalSelfArticContacts++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeSelfArticulationContactManager(PxU32 uniqueIndex, const PxNodeIndex nodeIndex0, const PxNodeIndex nodeIndex1)
|
||||
{
|
||||
PX_UNUSED(nodeIndex1);
|
||||
const PxHashMap<PxU32, PxU32>::Entry* entry = mNodeToRemapMap.find(nodeIndex0.index());
|
||||
|
||||
if(!entry)
|
||||
return false;
|
||||
|
||||
const PxU32 index = entry->second;
|
||||
return remove(uniqueIndex, mArticulationSelfConstraints[index].mSelfContacts, mTotalSelfArticContacts);
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::addSelfArticulationJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex0, const PxNodeIndex nodeIndex1)
|
||||
{
|
||||
PxU32 remapIndex = mNodeToRemapMap[nodeIndex0.index()];
|
||||
PxgArticulationSelfConstraints& selfConstraints = mArticulationSelfConstraints[remapIndex];
|
||||
if (selfConstraints.mSelfJoints.size() < PxgArticulationSelfConstraints::MaxConstraints)
|
||||
{
|
||||
PxgSelfConstraint con;
|
||||
con.uniqueId = uniqueIndex;
|
||||
con.linkID0 = nodeIndex0.articulationLinkId();
|
||||
con.linkID1 = nodeIndex1.articulationLinkId();
|
||||
//We need to find where to insert this contact into the articulation. The assumption is that we will not have a very
|
||||
//large number of static constraints, so we can just do a linear search. If this turns out to be a problem, we can try
|
||||
//something like binary search...
|
||||
PxU32 i = 0;
|
||||
PxU32 count = selfConstraints.mSelfJoints.size();
|
||||
for (; i < count; ++i)
|
||||
{
|
||||
if (con.linkID0 <= selfConstraints.mSelfJoints[i].linkID0)
|
||||
break;
|
||||
}
|
||||
selfConstraints.mSelfJoints.resizeUninitialized(count + 1);
|
||||
|
||||
for (PxU32 j = count; j > i; --j)
|
||||
{
|
||||
selfConstraints.mSelfJoints[j] = selfConstraints.mSelfJoints[j - 1];
|
||||
}
|
||||
|
||||
selfConstraints.mSelfJoints[i] = con;
|
||||
|
||||
mMaxSelfArticJoints = PxMax(mMaxSelfArticJoints, count + 1);
|
||||
mTotalSelfArticJoints++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::removeSelfArticulationJoint(PxU32 uniqueIndex, const PxNodeIndex nodeIndex0, const PxNodeIndex nodeIndex1)
|
||||
{
|
||||
PX_UNUSED(nodeIndex1);
|
||||
const PxHashMap<PxU32, PxU32>::Entry* entry = mNodeToRemapMap.find(nodeIndex0.index());
|
||||
|
||||
if(!entry)
|
||||
return false;
|
||||
|
||||
const PxU32 index = entry->second;
|
||||
return remove(uniqueIndex, mArticulationSelfConstraints[index].mSelfJoints, mTotalSelfArticJoints);
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseArticulation(Dy::FeatherstoneArticulation* articulation, const PxU32 nodeIndex)
|
||||
{
|
||||
mDeferredFreeNodeIDs.pushBack(nodeIndex);
|
||||
|
||||
if (articulation->mGPUDirtyFlags & Dy::ArticulationDirtyFlag::eIN_DIRTY_LIST)
|
||||
{
|
||||
for (PxU32 i = 0; i < mUpdatedArticulations.size(); ++i)
|
||||
{
|
||||
if (mUpdatedArticulations[i].articulation == articulation)
|
||||
{
|
||||
mUpdatedArticulations.replaceWithLast(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (PxU32 i = 0; i < mNewArticulationSims.size(); ++i)
|
||||
{
|
||||
if (mNewArticulationSims[i].nodeIndex == nodeIndex)
|
||||
{
|
||||
mNewArticulationSims.replaceWithLast(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseDeferredArticulationIds()
|
||||
{
|
||||
PxHashMap<PxU32, PxU32>::Entry entry;
|
||||
PxU32 size = mDeferredFreeNodeIDs.size();
|
||||
for(PxU32 i=0;i<size;i++)
|
||||
{
|
||||
bool found = mNodeToRemapMap.erase(mDeferredFreeNodeIDs[i], entry);
|
||||
PX_UNUSED(found);
|
||||
PX_ASSERT(found);
|
||||
#if PX_SUPPORT_OMNI_PVD
|
||||
mRemapToNodeMap.erase(entry.second);
|
||||
#endif
|
||||
mArticulationIdPool.deferredFreeID(entry.second);
|
||||
}
|
||||
mDeferredFreeNodeIDs.clear();
|
||||
mArticulationIdPool.processDeferredIds();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////softbody
|
||||
|
||||
void PxgBodySimManager::addSoftBody(Dy::DeformableVolume* deformableVolume, const PxU32 nodeIndex)
|
||||
{
|
||||
if (mUpdatedMap.boundedTest(nodeIndex))
|
||||
return;
|
||||
|
||||
if (mBodies.capacity() <= nodeIndex)
|
||||
{
|
||||
mBodies.resize(2 * nodeIndex + 1);
|
||||
}
|
||||
|
||||
mBodies[nodeIndex] = reinterpret_cast<void*>(deformableVolume);
|
||||
|
||||
mUpdatedMap.growAndSet(nodeIndex);
|
||||
PxgSoftBodyIndices index;
|
||||
index.nodeIndex = nodeIndex;
|
||||
index.remapIndex = mSoftBodyIdPool.getNewID();
|
||||
mNewSoftBodySims.pushBack(index);
|
||||
|
||||
deformableVolume->setGpuRemapId(index.remapIndex);
|
||||
|
||||
if (mActiveSoftbodyIndex.size() < (index.remapIndex + 1))
|
||||
{
|
||||
mActiveSoftbodyIndex.resize(PxMax(index.remapIndex + 1, mActiveSoftbodyIndex.size() * 2));
|
||||
mActiveSelfCollisionSoftbodyIndex.resize(PxMax(index.remapIndex + 1, mActiveSelfCollisionSoftbodyIndex.size() * 2));
|
||||
}
|
||||
mActiveSoftbodyIndex[index.remapIndex] = mActiveSoftbodiesStaging.size();
|
||||
|
||||
if (deformableVolume->getCore().bodyFlags & PxDeformableBodyFlag::eDISABLE_SELF_COLLISION)
|
||||
mActiveSelfCollisionSoftbodyIndex[index.remapIndex] = 0xFFFFFFFF;
|
||||
else
|
||||
{
|
||||
mActiveSelfCollisionSoftbodyIndex[index.remapIndex] = mActiveSelfCollisionSoftBodiesStaging.size();
|
||||
mActiveSelfCollisionSoftBodiesStaging.pushBack(index.remapIndex);
|
||||
}
|
||||
|
||||
mTotalNumBodies = PxMax(mTotalNumBodies, nodeIndex + 1);
|
||||
mTotalNumSoftBodies = PxMax(mTotalNumSoftBodies, index.remapIndex + 1);
|
||||
|
||||
mActiveSoftbodiesStaging.pushBack(index.remapIndex);
|
||||
mActiveSoftbodiesDirty = true;
|
||||
if (index.remapIndex == mDeformableVolumes.size())
|
||||
mDeformableVolumes.pushBack(deformableVolume);
|
||||
else
|
||||
mDeformableVolumes[index.remapIndex] = deformableVolume;
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseSoftBody(Dy::DeformableVolume* deformableVolume)
|
||||
{
|
||||
PxU32 remapIndex = deformableVolume->getGpuRemapId();
|
||||
PxU32 index = mActiveSoftbodyIndex[remapIndex];
|
||||
|
||||
if (index != 0xFFFFFFFF)
|
||||
{
|
||||
PX_ASSERT(mActiveSoftbodiesStaging[index] == remapIndex);
|
||||
mActiveSoftbodiesDirty = true;
|
||||
mActiveSoftbodyIndex[remapIndex] = 0xFFFFFFFF;
|
||||
|
||||
|
||||
mActiveSoftbodiesStaging.replaceWithLast(index);
|
||||
if (index < mActiveSoftbodiesStaging.size())
|
||||
mActiveSoftbodyIndex[mActiveSoftbodiesStaging[index]] = index;
|
||||
|
||||
PxU32 selfCollisionIndex = mActiveSelfCollisionSoftbodyIndex[remapIndex];
|
||||
|
||||
if (selfCollisionIndex != 0xFFFFFFFF)
|
||||
{
|
||||
PX_ASSERT(mActiveSelfCollisionSoftBodiesStaging[selfCollisionIndex] == remapIndex);
|
||||
mActiveSelfCollisionSoftbodyIndex[remapIndex] = 0xFFFFFFFF;
|
||||
|
||||
|
||||
mActiveSelfCollisionSoftBodiesStaging.replaceWithLast(selfCollisionIndex);
|
||||
if (selfCollisionIndex < mActiveSelfCollisionSoftBodiesStaging.size())
|
||||
mActiveSelfCollisionSoftbodyIndex[mActiveSelfCollisionSoftBodiesStaging[selfCollisionIndex]] = selfCollisionIndex;
|
||||
}
|
||||
}
|
||||
|
||||
for (PxU32 i = 0; i < mNewSoftBodySims.size(); ++i)
|
||||
{
|
||||
if (mNewSoftBodySims[i].remapIndex == remapIndex)
|
||||
{
|
||||
mNewSoftBodySims.replaceWithLast(i);
|
||||
}
|
||||
}
|
||||
|
||||
mDeformableVolumes[remapIndex] = NULL;
|
||||
|
||||
mSoftBodyIdPool.deferredFreeID(deformableVolume->getGpuRemapId());
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseDeferredSoftBodyIds()
|
||||
{
|
||||
mSoftBodyIdPool.processDeferredIds();
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::activateSoftbody(Dy::DeformableVolume* deformableVolume)
|
||||
{
|
||||
PxU32 remapIndex = deformableVolume->getGpuRemapId();
|
||||
PxU32 index = mActiveSoftbodyIndex[remapIndex];
|
||||
if (0xFFFFFFFF == index)
|
||||
{
|
||||
mActiveSoftbodyIndex[remapIndex] = mActiveSoftbodiesStaging.size();
|
||||
mActiveSoftbodiesStaging.pushBack(remapIndex);
|
||||
mActiveSoftbodiesDirty = true;
|
||||
|
||||
if (deformableVolume->getCore().bodyFlags & PxDeformableBodyFlag::eDISABLE_SELF_COLLISION)
|
||||
mActiveSelfCollisionSoftbodyIndex[remapIndex] = 0xFFFFFFFF;
|
||||
else
|
||||
{
|
||||
mActiveSelfCollisionSoftbodyIndex[remapIndex] = mActiveSelfCollisionSoftBodiesStaging.size();
|
||||
mActiveSelfCollisionSoftBodiesStaging.pushBack(remapIndex);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::deactivateSoftbody(Dy::DeformableVolume* deformableVolume)
|
||||
{
|
||||
PxU32 remapIndex = deformableVolume->getGpuRemapId();
|
||||
PxU32 index = mActiveSoftbodyIndex[remapIndex];
|
||||
if (0xFFFFFFFF != index)
|
||||
{
|
||||
mActiveSoftbodyIndex[remapIndex] = 0xFFFFFFFF;
|
||||
mActiveSoftbodiesStaging.replaceWithLast(index);
|
||||
mActiveSoftbodiesDirty = true;
|
||||
if (index < mActiveSoftbodiesStaging.size())
|
||||
mActiveSoftbodyIndex[mActiveSoftbodiesStaging[index]] = index;
|
||||
|
||||
deactivateSoftbodySelfCollision(deformableVolume);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::activateSoftbodySelfCollision(Dy::DeformableVolume* deformableVolume)
|
||||
{
|
||||
PxU32 remapIndex = deformableVolume->getGpuRemapId();
|
||||
PxU32 index = mActiveSelfCollisionSoftbodyIndex[remapIndex];
|
||||
if (0xFFFFFFFF == index)
|
||||
{
|
||||
mActiveSelfCollisionSoftbodyIndex[remapIndex] = mActiveSelfCollisionSoftBodiesStaging.size();
|
||||
mActiveSelfCollisionSoftBodiesStaging.pushBack(remapIndex);
|
||||
mActiveSoftbodiesDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::deactivateSoftbodySelfCollision(Dy::DeformableVolume* deformableVolume)
|
||||
{
|
||||
PxU32 remapIndex = deformableVolume->getGpuRemapId();
|
||||
PxU32 index = mActiveSelfCollisionSoftbodyIndex[remapIndex];
|
||||
if (0xFFFFFFFF != index)
|
||||
{
|
||||
mActiveSoftbodiesDirty = true;
|
||||
PX_ASSERT(mActiveSelfCollisionSoftBodiesStaging[index] == remapIndex);
|
||||
mActiveSelfCollisionSoftbodyIndex[remapIndex] = 0xFFFFFFFF;
|
||||
|
||||
mActiveSelfCollisionSoftBodiesStaging.replaceWithLast(index);
|
||||
if (index < mActiveSelfCollisionSoftBodiesStaging.size())
|
||||
mActiveSelfCollisionSoftbodyIndex[mActiveSelfCollisionSoftBodiesStaging[index]] = index;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////femCloth
|
||||
|
||||
void PxgBodySimManager::addFEMCloth(Dy::DeformableSurface* deformableSurface, const PxU32 nodeIndex)
|
||||
{
|
||||
if (mUpdatedMap.boundedTest(nodeIndex))
|
||||
return;
|
||||
|
||||
if (mBodies.capacity() <= nodeIndex)
|
||||
{
|
||||
mBodies.resize(2 * nodeIndex + 1);
|
||||
}
|
||||
|
||||
mBodies[nodeIndex] = reinterpret_cast<void*>(deformableSurface);
|
||||
|
||||
mUpdatedMap.growAndSet(nodeIndex);
|
||||
|
||||
PxgFEMClothIndices index;
|
||||
index.nodeIndex = nodeIndex;
|
||||
index.remapIndex = mFEMClothIdPool.getNewID();
|
||||
mNewFEMClothSims.pushBack(index);
|
||||
|
||||
deformableSurface->setGpuRemapId(index.remapIndex);
|
||||
|
||||
if (mActiveFEMClothIndex.size() < (index.remapIndex+1))
|
||||
{
|
||||
mActiveFEMClothIndex.resize(PxMax(index.remapIndex + 1, mActiveFEMClothIndex.size() * 2));
|
||||
}
|
||||
mActiveFEMClothIndex[index.remapIndex] = mActiveFEMClothStaging.size();
|
||||
|
||||
mTotalNumBodies = PxMax(mTotalNumBodies, nodeIndex + 1);
|
||||
mTotalNumFEMCloths = PxMax(mTotalNumFEMCloths, index.remapIndex + 1);
|
||||
|
||||
mActiveFEMClothStaging.pushBack(index.remapIndex);
|
||||
mActiveFEMClothsDirty = true;
|
||||
|
||||
if (index.remapIndex == mDeformableSurfaces.size())
|
||||
mDeformableSurfaces.pushBack(deformableSurface);
|
||||
else
|
||||
mDeformableSurfaces[index.remapIndex] = deformableSurface;
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseFEMCloth(Dy::DeformableSurface* deformableSurface)
|
||||
{
|
||||
PxU32 remapIndex = deformableSurface->getGpuRemapId();
|
||||
PxU32 index = mActiveFEMClothIndex[remapIndex];
|
||||
|
||||
if (index != 0xFFFFFFFF)
|
||||
{
|
||||
PX_ASSERT(mActiveFEMClothStaging[index] == remapIndex);
|
||||
mActiveFEMClothsDirty = true;
|
||||
mActiveFEMClothIndex[remapIndex] = 0xFFFFFFFF;
|
||||
|
||||
mActiveFEMClothStaging.replaceWithLast(index);
|
||||
if (index < mActiveFEMClothStaging.size())
|
||||
mActiveFEMClothIndex[mActiveFEMClothStaging[index]] = index;
|
||||
}
|
||||
|
||||
for (PxU32 i = 0; i < mNewFEMClothSims.size(); ++i)
|
||||
{
|
||||
if (mNewFEMClothSims[i].remapIndex == remapIndex)
|
||||
{
|
||||
mNewFEMClothSims.replaceWithLast(i);
|
||||
}
|
||||
}
|
||||
|
||||
mDeformableSurfaces[remapIndex] = NULL;
|
||||
|
||||
mFEMClothIdPool.deferredFreeID(remapIndex);
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseDeferredFEMClothIds()
|
||||
{
|
||||
mFEMClothIdPool.processDeferredIds();
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::activateCloth(Dy::DeformableSurface* deformableSurface)
|
||||
{
|
||||
PxU32 remapIndex = deformableSurface->getGpuRemapId();
|
||||
PxU32 index = mActiveFEMClothIndex[remapIndex];
|
||||
if (0xFFFFFFFF == index)
|
||||
{
|
||||
mActiveFEMClothIndex[remapIndex] = mActiveFEMClothStaging.size();
|
||||
mActiveFEMClothStaging.pushBack(remapIndex);
|
||||
mActiveFEMClothsDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PxgBodySimManager::deactivateCloth(Dy::DeformableSurface* deformableSurface)
|
||||
{
|
||||
PxU32 remapIndex = deformableSurface->getGpuRemapId();
|
||||
PxU32 index = mActiveFEMClothIndex[remapIndex];
|
||||
if (0xFFFFFFFF != index)
|
||||
{
|
||||
mActiveFEMClothIndex[remapIndex] = 0xFFFFFFFF;
|
||||
mActiveFEMClothStaging.replaceWithLast(index);
|
||||
mActiveFEMClothsDirty = true;
|
||||
if (index < mActiveFEMClothStaging.size())
|
||||
mActiveFEMClothIndex[mActiveFEMClothStaging[index]] = index;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////particlesystem
|
||||
|
||||
void PxgBodySimManager::addPBDParticleSystem(Dy::ParticleSystem* particleSystem, const PxU32 nodeIndex)
|
||||
{
|
||||
if (mUpdatedMap.boundedTest(nodeIndex))
|
||||
return;
|
||||
|
||||
if (mBodies.capacity() <= nodeIndex)
|
||||
{
|
||||
mBodies.resize(2 * nodeIndex + 1);
|
||||
}
|
||||
|
||||
mBodies[nodeIndex] = reinterpret_cast<void*>(particleSystem);
|
||||
|
||||
mUpdatedMap.growAndSet(nodeIndex);
|
||||
PxgParticleSystemIndices index;
|
||||
index.nodeIndex = nodeIndex;
|
||||
index.remapIndex = mPBDParticleSystemIdPool.getNewID();
|
||||
mNewPBDParticleSystemSims.pushBack(index);
|
||||
|
||||
particleSystem->setGpuRemapId(index.remapIndex);
|
||||
|
||||
mTotalNumBodies = PxMax(mTotalNumBodies, nodeIndex + 1);
|
||||
mTotalNumPBDParticleSystems = PxMax(mTotalNumPBDParticleSystems, index.remapIndex + 1);
|
||||
|
||||
mActivePBDParticleSystems.pushBack(index.remapIndex);
|
||||
mActivePBDParticleSystemsDirty = true;
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releasePBDParticleSystem(Dy::ParticleSystem* particleSystem)
|
||||
{
|
||||
PxU32 remapIndex = particleSystem->getGpuRemapId();
|
||||
for (PxU32 i = 0; i < mActivePBDParticleSystems.size(); ++i)
|
||||
{
|
||||
if (mActivePBDParticleSystems[i] == remapIndex)
|
||||
{
|
||||
mActivePBDParticleSystems.replaceWithLast(i);
|
||||
mActivePBDParticleSystemsDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (PxU32 i = 0; i < mNewPBDParticleSystemSims.size(); ++i)
|
||||
{
|
||||
if (mNewPBDParticleSystemSims[i].remapIndex == remapIndex)
|
||||
{
|
||||
mNewPBDParticleSystemSims.replaceWithLast(i);
|
||||
}
|
||||
}
|
||||
|
||||
mPBDParticleSystemIdPool.deferredFreeID(remapIndex);
|
||||
}
|
||||
|
||||
void PxgBodySimManager::releaseDeferredPBDParticleSystemIds()
|
||||
{
|
||||
mPBDParticleSystemIdPool.processDeferredIds();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////softbody
|
||||
|
||||
void PxgBodySimManager::updateBody(const PxNodeIndex& nodeIndex)
|
||||
{
|
||||
const PxU32 index = nodeIndex.index();
|
||||
if (!mUpdatedMap.boundedTest(index))
|
||||
{
|
||||
mUpdatedMap.growAndSet(index);
|
||||
mNewOrUpdatedBodySims.pushBack(index);
|
||||
}
|
||||
}
|
||||
|
||||
void PxgBodySimManager::updateBodies(PxsRigidBody** rigidBodies, PxU32* nodeIndices, PxU32 nbBodies,
|
||||
PxsExternalAccelerationProvider* externalAccelerations)
|
||||
{
|
||||
mExternalAccelerations = externalAccelerations;
|
||||
PxU32 newVal = static_cast<PxU32>(PxAtomicAdd(reinterpret_cast<PxI32*>(&mNbUpdatedBodies), static_cast<PxI32>(nbBodies)));
|
||||
|
||||
PxgBodySimVelocityUpdate* newUpdatedBodies = mNewUpdatedBodies.begin();
|
||||
const PxU32 startIndex = newVal - nbBodies;
|
||||
for(PxU32 i=0; i<nbBodies; ++i)
|
||||
{
|
||||
PxsRigidBody* rigid = rigidBodies[i];
|
||||
PxsBodyCore& bcLL = rigid->getCore();
|
||||
|
||||
newUpdatedBodies[i + startIndex].linearVelocityXYZ_bodySimIndexW = make_float4(bcLL.linearVelocity.x, bcLL.linearVelocity.y, bcLL.linearVelocity.z, PX_FR(nodeIndices[i]));
|
||||
newUpdatedBodies[i + startIndex].angularVelocityXYZ_maxPenBiasW = make_float4(bcLL.angularVelocity.x, bcLL.angularVelocity.y, bcLL.angularVelocity.z, bcLL.maxPenBias);
|
||||
|
||||
if (externalAccelerations)
|
||||
{
|
||||
if (externalAccelerations->hasAccelerations())
|
||||
{
|
||||
const PxsRigidBodyExternalAcceleration& acc = externalAccelerations->get(nodeIndices[i]);
|
||||
newUpdatedBodies[i + startIndex].externalLinearAccelerationXYZ = make_float4(acc.linearAcceleration.x, acc.linearAcceleration.y, acc.linearAcceleration.z, 0.0f);
|
||||
newUpdatedBodies[i + startIndex].externalAngularAccelerationXYZ = make_float4(acc.angularAcceleration.x, acc.angularAcceleration.y, acc.angularAcceleration.z, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
newUpdatedBodies[i + startIndex].externalLinearAccelerationXYZ = make_float4(0.0f);
|
||||
newUpdatedBodies[i + startIndex].externalAngularAccelerationXYZ = make_float4(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PxgBodySimManager::reserve(const PxU32 nbBodies)
|
||||
{
|
||||
const PxU32 requiredSize = mNewUpdatedBodies.size() + nbBodies;
|
||||
mNbUpdatedBodies = mNewUpdatedBodies.size();
|
||||
if (mNewUpdatedBodies.capacity() < requiredSize)
|
||||
{
|
||||
mNewUpdatedBodies.reserve(requiredSize * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void PxgBodySimManager::destroy()
|
||||
{
|
||||
this->~PxgBodySimManager();
|
||||
PX_FREE_THIS;
|
||||
}
|
||||
|
||||
void PxgBodySimManager::reset()
|
||||
{
|
||||
mNewOrUpdatedBodySims.forceSize_Unsafe(0);
|
||||
mNewArticulationSims.forceSize_Unsafe(0);
|
||||
|
||||
mNewSoftBodySims.forceSize_Unsafe(0);
|
||||
mNewFEMClothSims.forceSize_Unsafe(0);
|
||||
mNewPBDParticleSystemSims.forceSize_Unsafe(0);
|
||||
|
||||
mNewUpdatedBodies.forceSize_Unsafe(0);
|
||||
mUpdatedArticulations.forceSize_Unsafe(0);
|
||||
mNbUpdatedBodies = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user