Revision control
- //
// 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-2021 NVIDIA Corporation. All rights reserved.
+ // Copyright (c) 2008-2026 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXS_SIMPLE_ISLAND_GEN_H
#define PXS_SIMPLE_ISLAND_GEN_H
+ #include "foundation/PxUserAllocated.h"
#include "PxsIslandSim.h"
#include "CmTask.h"
+ /*
+ PT: runs first part of the island gen's second pass in parallel with the Pxg-level constraint partitioning.
+
+ mIslandGen task spawns Pxg constraint partitioning task(s).
+ mIslandGen runs processNarrowPhaseTouchEvents() in parallel with Pxg.
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ Previous design:
+
+ mPostIslandGen runs as a continuation task after mIslandGen and Pxg.
+
+ mPostIslandGen mainly runs mSetEdgesConnectedTask, which:
+ - calls mSimpleIslandManager->setEdgeConnected()
+ - calls mSimpleIslandManager-secondPassIslandGen()
+ - calls wakeObjectsUp()
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ New design:
+
+ postIslandGen is not a task anymore (mPostIslandGen does not exist).
+ postIslandGen is directly called at the end of mIslandGen.
+ So it now runs in parallel with Pxg.
+ mIslandGen and Pxg continue to mSolver task.
+
+ postIslandGen mainly runs mSetEdgesConnectedTask, which:
+ - calls mSimpleIslandManager->setEdgeConnected()
+ - calls mSimpleIslandManager->secondPassIslandGenPart1()
+
+ mSolver now first runs the parts that don't overlap with Pxg:
+ - calls mSimpleIslandManager-secondPassIslandGenPart2()
+ - calls wakeObjectsUp()
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ Before:
+ mIslandGen->processNarrowPhaseTouchEvents |mPostIslandGen |mSolver
+ =>PxgConstraintPartition |=>setEdgesConnected->secondPassIslandGen->wakeObjectsUp|
+
+ After:
+ mIslandGen->processNarrowPhaseTouchEvents->postIslandGen |secondPassIslandGenPart2->wakeObjectsUp->mSolver
+ =>PxgConstraintPartition =>setEdgesConnected->secondPassIslandGenPart1 |
+ */
+ #define USE_SPLIT_SECOND_PASS_ISLAND_GEN 1
+
namespace physx
{
+ class PxsContactManager;
+ // PT: TODO: fw declaring an Sc class here is not good
namespace Sc
{
class Interaction;
}
+
+ namespace Dy
+ {
+ struct Constraint;
+ }
+
namespace IG
{
-
class SimpleIslandManager;
class ThirdPassTask : public Cm::Task
{
SimpleIslandManager& mIslandManager;
IslandSim& mIslandSim;
public:
ThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager, IslandSim& islandSim);
- virtual void runInternal();
+ virtual void runInternal() PX_OVERRIDE;
- virtual const char* getName() const
+ virtual const char* getName() const PX_OVERRIDE
{
return "ThirdPassIslandGenTask";
}
private:
PX_NOCOPY(ThirdPassTask)
};
class PostThirdPassTask : public Cm::Task
{
SimpleIslandManager& mIslandManager;
public:
PostThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager);
- virtual void runInternal();
+ virtual void runInternal() PX_OVERRIDE;
- virtual const char* getName() const
+ virtual const char* getName() const PX_OVERRIDE
{
return "PostThirdPassTask";
}
private:
PX_NOCOPY(PostThirdPassTask)
};
- class SimpleIslandManager
+ class AuxCpuData
{
+ public:
+ PX_FORCE_INLINE PxsContactManager* getContactManager(IG::EdgeIndex edgeId) const { return reinterpret_cast<PxsContactManager*>(mConstraintOrCm[edgeId]); }
+ PX_FORCE_INLINE Dy::Constraint* getConstraint(IG::EdgeIndex edgeId) const { return reinterpret_cast<Dy::Constraint*>(mConstraintOrCm[edgeId]); }
- HandleManager<PxU32> mNodeHandles; //! Handle manager for nodes
- HandleManager<EdgeIndex> mEdgeHandles; //! Handle manager for edges
+ Cm::BlockArray<void*> mConstraintOrCm; //! Pointers to either the constraint or Cm for this pair
+ };
+
+ class SimpleIslandManager : public PxUserAllocated
+ {
+ HandleManager<PxU32> mNodeHandles; //! Handle manager for nodes
+ HandleManager<EdgeIndex> mEdgeHandles; //! Handle manager for edges
//An array of destroyed nodes
- Ps::Array<NodeIndex> mDestroyedNodes;
+ PxArray<PxNodeIndex> mDestroyedNodes;
Cm::BlockArray<Sc::Interaction*> mInteractions;
-
//Edges destroyed this frame
- Ps::Array<EdgeIndex> mDestroyedEdges;
- Ps::Array<PartitionEdge*> mFirstPartitionEdges;
- Ps::Array<PartitionEdge*> mDestroyedPartitionEdges;
- //KS - stores node indices for a given edge. Node index 0 is at 2* edgeId and NodeIndex1 is at 2*edgeId + 1
- //can also be used for edgeInstance indexing so there's no need to figure out outboundNode ID either!
- Cm::BlockArray<NodeIndex> mEdgeNodeIndices;
- Cm::BlockArray<void*> mConstraintOrCm; //! Pointers to either the constraint or Cm for this pair
+ PxArray<EdgeIndex> mDestroyedEdges;
+ GPUExternalData mGpuData;
- Cm::BitMap mConnectedMap;
+ CPUExternalData mCpuData;
+ AuxCpuData mAuxCpuData;
- IslandSim mIslandManager;
+ PxBitMap mConnectedMap;
+
+ // PT: TODO: figure out why we still need both
+ IslandSim mAccurateIslandManager;
IslandSim mSpeculativeIslandManager;
ThirdPassTask mSpeculativeThirdPassTask;
ThirdPassTask mAccurateThirdPassTask;
PostThirdPassTask mPostThirdPassTask;
PxU32 mMaxDirtyNodesPerFrame;
- PxU64 mContextID;
+ const PxU64 mContextID;
+ const bool mGPU;
public:
- SimpleIslandManager(bool useEnhancedDeterminism, PxU64 contextID);
-
+ SimpleIslandManager(bool useEnhancedDeterminism, bool gpu, PxU64 contextID);
~SimpleIslandManager();
- NodeIndex addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive);
+ PxNodeIndex addNode(bool isActive, bool isKinematic, Node::NodeType type, void* object);
+ void removeNode(const PxNodeIndex index);
- void removeNode(const NodeIndex index);
+ // PT: these two functions added for multithreaded implementation of Sc::Scene::islandInsertion
+ void preallocateContactManagers(PxU32 nb, EdgeIndex* handles);
+ bool addPreallocatedContactManager(EdgeIndex handle, PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, Edge::EdgeType edgeType);
- NodeIndex addArticulation(Sc::ArticulationSim* articulation, Dy::ArticulationV* llArtic, bool isActive);
+ EdgeIndex addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, Edge::EdgeType edgeType);
+ EdgeIndex addConstraint(Dy::Constraint* constraint, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction);
- EdgeIndex addContactManager(PxsContactManager* manager, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction);
+ PX_FORCE_INLINE PxIntBool isEdgeConnected(EdgeIndex edgeIndex) const { return mConnectedMap.test(edgeIndex); }
- EdgeIndex addConstraint(Dy::Constraint* constraint, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction);
-
- bool isConnected(EdgeIndex edgeIndex) const { return !!mConnectedMap.test(edgeIndex); }
-
- PX_FORCE_INLINE NodeIndex getEdgeIndex(EdgeInstanceIndex edgeIndex) const { return mEdgeNodeIndices[edgeIndex]; }
-
- void activateNode(NodeIndex index);
- void deactivateNode(NodeIndex index);
- void putNodeToSleep(NodeIndex index);
+ void activateNode(PxNodeIndex index);
+ void deactivateNode(PxNodeIndex index);
+ void putNodeToSleep(PxNodeIndex index);
void removeConnection(EdgeIndex edgeIndex);
void firstPassIslandGen();
void additionalSpeculativeActivation();
void secondPassIslandGen();
+ void secondPassIslandGenPart1();
+ void secondPassIslandGenPart2();
void thirdPassIslandGen(PxBaseTask* continuation);
- void clearDestroyedEdges();
+ PX_INLINE void clearDestroyedPartitionEdges()
+ {
+ mGpuData.mDestroyedPartitionEdges.forceSize_Unsafe(0);
+ }
- void setEdgeConnected(EdgeIndex edgeIndex);
+ void setEdgeConnected(EdgeIndex edgeIndex, Edge::EdgeType edgeType);
void setEdgeDisconnected(EdgeIndex edgeIndex);
- bool getIsEdgeConnected(EdgeIndex edgeIndex);
-
void setEdgeRigidCM(const EdgeIndex edgeIndex, PxsContactManager* cm);
void clearEdgeRigidCM(const EdgeIndex edgeIndex);
- void setKinematic(IG::NodeIndex nodeIndex);
+ void setKinematic(PxNodeIndex nodeIndex);
- void setDynamic(IG::NodeIndex nodeIndex);
+ void setDynamic(PxNodeIndex nodeIndex);
- const IslandSim& getSpeculativeIslandSim() const { return mSpeculativeIslandManager; }
- const IslandSim& getAccurateIslandSim() const { return mIslandManager; }
+ PX_FORCE_INLINE IslandSim& getSpeculativeIslandSim() { return mSpeculativeIslandManager; }
+ PX_FORCE_INLINE const IslandSim& getSpeculativeIslandSim() const { return mSpeculativeIslandManager; }
- IslandSim& getAccurateIslandSim() { return mIslandManager; }
+ PX_FORCE_INLINE IslandSim& getAccurateIslandSim() { return mAccurateIslandManager; }
+ PX_FORCE_INLINE const IslandSim& getAccurateIslandSim() const { return mAccurateIslandManager; }
- PX_FORCE_INLINE PxU32 getNbEdgeHandles() const { return mEdgeHandles.getTotalHandles(); }
+ PX_FORCE_INLINE const AuxCpuData& getAuxCpuData() const { return mAuxCpuData; }
- PX_FORCE_INLINE PxU32 getNbNodeHandles() const { return mNodeHandles.getTotalHandles(); }
+ PX_FORCE_INLINE PxU32 getNbEdgeHandles() const { return mEdgeHandles.getTotalHandles(); }
+
+ PX_FORCE_INLINE PxU32 getNbNodeHandles() const { return mNodeHandles.getTotalHandles(); }
void deactivateEdge(const EdgeIndex edge);
- PX_FORCE_INLINE PxsContactManager* getContactManager(IG::EdgeIndex edgeId) const { return reinterpret_cast<PxsContactManager*>(mConstraintOrCm[edgeId]); }
- PX_FORCE_INLINE PxsContactManager* getContactManagerUnsafe(IG::EdgeIndex edgeId) const { return reinterpret_cast<PxsContactManager*>(mConstraintOrCm[edgeId]); }
- PX_FORCE_INLINE Dy::Constraint* getConstraint(IG::EdgeIndex edgeId) const { return reinterpret_cast<Dy::Constraint*>(mConstraintOrCm[edgeId]); }
- PX_FORCE_INLINE Dy::Constraint* getConstraintUnsafe(IG::EdgeIndex edgeId) const { return reinterpret_cast<Dy::Constraint*>(mConstraintOrCm[edgeId]); }
+ PX_FORCE_INLINE PxsContactManager* getContactManager(IG::EdgeIndex edgeId) const { return reinterpret_cast<PxsContactManager*>(mAuxCpuData.mConstraintOrCm[edgeId]); }
+ PX_FORCE_INLINE Dy::Constraint* getConstraint(IG::EdgeIndex edgeId) const { return reinterpret_cast<Dy::Constraint*>(mAuxCpuData.mConstraintOrCm[edgeId]); }
- PX_FORCE_INLINE Sc::Interaction* getInteraction(IG::EdgeIndex edgeId) const { return mInteractions[edgeId]; }
+ PX_FORCE_INLINE Sc::Interaction* getInteractionFromEdgeIndex(IG::EdgeIndex edgeId) const { return mInteractions[edgeId]; }
- PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
+ PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
bool checkInternalConsistency();
-
private:
friend class ThirdPassTask;
friend class PostThirdPassTask;
- bool validateDeactivations() const;
+ bool validateDeactivations() const;
+ EdgeIndex addEdge(void* edge, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction);
+ EdgeIndex resizeEdgeArrays(EdgeIndex handle, bool flag);
PX_NOCOPY(SimpleIslandManager)
};
-
-
}
}
#endif