aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp')
-rw-r--r--PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp369
1 files changed, 369 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp b/PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp
new file mode 100644
index 00000000..b01eefb0
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/src/PxsSimpleIslandManager.cpp
@@ -0,0 +1,369 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 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 "foundation/PxProfiler.h"
+#include "PxsSimpleIslandManager.h"
+#include "PsSort.h"
+#include "PxsContactManager.h"
+#include "CmTask.h"
+
+#define IG_SANITY_CHECKS 0
+
+namespace physx
+{
+namespace IG
+{
+
+ SimpleIslandManager::SimpleIslandManager(bool useEnhancedDeterminism, PxU64 contextID) :
+ mDestroyedNodes(PX_DEBUG_EXP("mDestroyedNodes")),
+ mInteractions(PX_DEBUG_EXP("mInteractions")),
+ mDestroyedEdges(PX_DEBUG_EXP("mDestroyedEdges")),
+ mFirstPartitionEdges(PX_DEBUG_EXP("mFirstPartitionEdges")),
+ mDestroyedPartitionEdges(PX_DEBUG_EXP("IslandSim::mDestroyedPartitionEdges")),
+ mEdgeNodeIndices(PX_DEBUG_EXP("mEdgeNodeIndices")),
+ mConstraintOrCm(PX_DEBUG_EXP("mConstraintOrCm")),
+ mIslandManager(&mFirstPartitionEdges, mEdgeNodeIndices, &mDestroyedPartitionEdges, contextID),
+ mSpeculativeIslandManager(NULL, mEdgeNodeIndices, NULL, contextID),
+ mSpeculativeThirdPassTask(*this, mSpeculativeIslandManager),
+ mAccurateThirdPassTask(*this, mIslandManager),
+ mPostThirdPassTask(*this),
+ mContextID(contextID)
+{
+ mFirstPartitionEdges.resize(1024);
+ mMaxDirtyNodesPerFrame = useEnhancedDeterminism ? 0xFFFFFFFF : 1000u;
+}
+
+SimpleIslandManager::~SimpleIslandManager()
+{
+}
+
+NodeIndex SimpleIslandManager::addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive)
+{
+ PxU32 handle = mNodeHandles.getHandle();
+ NodeIndex nodeIndex(handle);
+ mIslandManager.addRigidBody(body, isKinematic, isActive, nodeIndex);
+ mSpeculativeIslandManager.addRigidBody(body, isKinematic, isActive, nodeIndex);
+ return nodeIndex;
+}
+
+void SimpleIslandManager::removeNode(const NodeIndex index)
+{
+ PX_ASSERT(mNodeHandles.isValidHandle(index.index()));
+ mDestroyedNodes.pushBack(index);
+}
+
+NodeIndex SimpleIslandManager::addArticulation(Sc::ArticulationSim* articulation, Dy::Articulation* llArtic, bool isActive)
+{
+ PxU32 handle = mNodeHandles.getHandle();
+ NodeIndex nodeIndex(handle);
+ mIslandManager.addArticulation(articulation, llArtic, isActive, nodeIndex);
+ mSpeculativeIslandManager.addArticulation(articulation, llArtic, isActive, nodeIndex);
+ return nodeIndex;
+}
+
+EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction)
+{
+ EdgeIndex handle = mEdgeHandles.getHandle();
+
+ PxU32 nodeIds = 2 * handle;
+ if (mEdgeNodeIndices.size() == nodeIds)
+ {
+ mEdgeNodeIndices.resize(2 * (nodeIds + 2));
+ mConstraintOrCm.resize(2 * (handle + 1));
+ mInteractions.resize(2 * (handle + 1));
+ }
+
+ mEdgeNodeIndices[nodeIds] = nodeHandle1;
+ mEdgeNodeIndices[nodeIds+1] = nodeHandle2;
+ mConstraintOrCm[handle].mCm = manager;
+ mInteractions[handle] = interaction;
+
+ mSpeculativeIslandManager.addContactManager(manager, nodeHandle1, nodeHandle2, handle);
+
+ if (manager)
+ manager->getWorkUnit().mEdgeIndex = handle;
+
+ if(mConnectedMap.size() == handle)
+ {
+ mConnectedMap.resize(2 * (handle + 1));
+ }
+ if (mFirstPartitionEdges.capacity() == handle)
+ {
+ mFirstPartitionEdges.resize(2 * (handle + 1));
+ }
+ mConnectedMap.reset(handle);
+ return handle;
+}
+
+EdgeIndex SimpleIslandManager::addConstraint(Dy::Constraint* constraint, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction)
+{
+ EdgeIndex handle = mEdgeHandles.getHandle();
+
+ PxU32 nodeIds = 2 * handle;
+ if (mEdgeNodeIndices.size() == nodeIds)
+ {
+ mEdgeNodeIndices.resize(2 * (mEdgeNodeIndices.size() + 2));
+ mConstraintOrCm.resize(2 * (handle + 1));
+ mInteractions.resize(2 * (handle + 1));
+ }
+
+ mEdgeNodeIndices[nodeIds] = nodeHandle1;
+ mEdgeNodeIndices[nodeIds + 1] = nodeHandle2;
+
+ mConstraintOrCm[handle].mConstraint = constraint;
+
+ mInteractions[handle] = interaction;
+
+ mIslandManager.addConstraint(constraint, nodeHandle1, nodeHandle2, handle);
+ mSpeculativeIslandManager.addConstraint(constraint, nodeHandle1, nodeHandle2, handle);
+ if(mConnectedMap.size() == handle)
+ {
+ mConnectedMap.resize(2*(mConnectedMap.size()+1));
+ }
+
+ if (mFirstPartitionEdges.capacity() == handle)
+ {
+ mFirstPartitionEdges.resize(2 * (mFirstPartitionEdges.capacity() + 1));
+ }
+ mConnectedMap.set(handle);
+ return handle;
+}
+
+void SimpleIslandManager::activateNode(NodeIndex index)
+{
+ mIslandManager.activateNode(index);
+ mSpeculativeIslandManager.activateNode(index);
+}
+
+void SimpleIslandManager::deactivateNode(NodeIndex index)
+{
+ mIslandManager.deactivateNode(index);
+ mSpeculativeIslandManager.deactivateNode(index);
+}
+
+void SimpleIslandManager::putNodeToSleep(NodeIndex index)
+{
+ mIslandManager.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))
+ {
+ mIslandManager.removeConnection(edgeIndex);
+ mConnectedMap.reset(edgeIndex);
+ }
+
+ mConstraintOrCm[edgeIndex].mCm = NULL;
+ mInteractions[edgeIndex] = NULL;
+}
+
+void SimpleIslandManager::firstPassIslandGen()
+{
+ PX_PROFILE_ZONE("Basic.firstPassIslandGen", getContextId());
+ 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", getContextId());
+
+ mIslandManager.wakeIslands();
+ mIslandManager.processNewEdges();
+
+ mIslandManager.removeDestroyedEdges();
+ mIslandManager.processLostEdges(mDestroyedNodes, false, false, mMaxDirtyNodesPerFrame);
+
+ for(PxU32 a = 0; a < mDestroyedNodes.size(); ++a)
+ {
+ mNodeHandles.freeHandle(mDestroyedNodes[a].index());
+ }
+ mDestroyedNodes.clear();
+ mDestroyedEdges.clear();
+}
+
+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 NodeIndex* 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 = mIslandManager.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;
+}
+
+void ThirdPassTask::runInternal()
+{
+ PX_PROFILE_ZONE("Basic.thirdPassIslandGen", mIslandSim.getContextId());
+ mIslandSim.removeDestroyedEdges();
+ mIslandSim.processLostEdges(mIslandManager.mDestroyedNodes, true, true, mIslandManager.mMaxDirtyNodesPerFrame);
+}
+
+void PostThirdPassTask::runInternal()
+{
+ 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());
+}
+
+void SimpleIslandManager::thirdPassIslandGen(PxBaseTask* continuation)
+{
+
+ mIslandManager.clearDeactivations();
+
+ mPostThirdPassTask.setContinuation(continuation);
+
+ mSpeculativeThirdPassTask.setContinuation(&mPostThirdPassTask);
+ mAccurateThirdPassTask.setContinuation(&mPostThirdPassTask);
+
+ mSpeculativeThirdPassTask.removeReference();
+ mAccurateThirdPassTask.removeReference();
+
+ mPostThirdPassTask.removeReference();
+
+ //PX_PROFILE_ZONE("Basic.thirdPassIslandGen", getContextId());
+ //mSpeculativeIslandManager.removeDestroyedEdges();
+ //mSpeculativeIslandManager.processLostEdges(mDestroyedNodes, true, true);
+
+ //mIslandManager.removeDestroyedEdges();
+ //mIslandManager.processLostEdges(mDestroyedNodes, true, true);
+
+
+}
+
+bool SimpleIslandManager::checkInternalConsistency()
+{
+ return mIslandManager.checkInternalConsistency() && mSpeculativeIslandManager.checkInternalConsistency();
+}
+
+void SimpleIslandManager::clearDestroyedEdges()
+{
+ mDestroyedPartitionEdges.forceSize_Unsafe(0);
+}
+
+void SimpleIslandManager::setEdgeConnected(EdgeIndex edgeIndex)
+{
+ if(!mConnectedMap.test(edgeIndex))
+ {
+ mIslandManager.addContactManager(mConstraintOrCm[edgeIndex].mCm, mEdgeNodeIndices[edgeIndex*2], mEdgeNodeIndices[edgeIndex*2+1], edgeIndex);
+ mConnectedMap.set(edgeIndex);
+ }
+}
+
+bool SimpleIslandManager::getIsEdgeConnected(EdgeIndex edgeIndex)
+{
+ return !!mConnectedMap.test(edgeIndex);
+}
+
+void SimpleIslandManager::deactivateEdge(const EdgeIndex edgeIndex)
+{
+ if (mFirstPartitionEdges[edgeIndex])
+ {
+ mDestroyedPartitionEdges.pushBack(mFirstPartitionEdges[edgeIndex]);
+ mFirstPartitionEdges[edgeIndex] = NULL;
+ }
+}
+
+void SimpleIslandManager::setEdgeDisconnected(EdgeIndex edgeIndex)
+{
+ if(mConnectedMap.test(edgeIndex))
+ {
+ //PX_ASSERT(!mIslandManager.getEdge(edgeIndex).isInDirtyList());
+ mIslandManager.removeConnection(edgeIndex);
+ mConnectedMap.reset(edgeIndex);
+ }
+}
+
+void SimpleIslandManager::setEdgeRigidCM(const EdgeIndex edgeIndex, PxsContactManager* cm)
+{
+ mConstraintOrCm[edgeIndex].mCm = cm;
+ cm->getWorkUnit().mEdgeIndex = edgeIndex;
+}
+
+void SimpleIslandManager::clearEdgeRigidCM(const EdgeIndex edgeIndex)
+{
+ mConstraintOrCm[edgeIndex].mCm = NULL;
+ if (mFirstPartitionEdges[edgeIndex])
+ {
+ //this is the partition edges created/updated by the gpu solver
+ mDestroyedPartitionEdges.pushBack(mFirstPartitionEdges[edgeIndex]);
+ mFirstPartitionEdges[edgeIndex] = NULL;
+ }
+}
+
+void SimpleIslandManager::setKinematic(IG::NodeIndex nodeIndex)
+{
+ mIslandManager.setKinematic(nodeIndex);
+ mSpeculativeIslandManager.setKinematic(nodeIndex);
+}
+
+void SimpleIslandManager::setDynamic(IG::NodeIndex nodeIndex)
+{
+ mIslandManager.setDynamic(nodeIndex);
+ mSpeculativeIslandManager.setDynamic(nodeIndex);
+}
+
+}
+}
+