Revision control

++ // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
++ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
++ // SPDX-FileCopyrightText: Copyright (c) 2008-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
++ // SPDX-License-Identifier: Apache-2.0
++
++ #ifndef DY_CONTEXT_H
++ #define DY_CONTEXT_H
++
++ #include "PxSceneDesc.h"
++ #include "DyThresholdTable.h"
++ #include "PxcNpThreadContext.h"
++ #include "PxsSimulationController.h"
++ #include "PxsHeapStats.h"
++ #include "DyConstraintWriteBack.h"
++ #include "foundation/PxAllocator.h"
++ #include "foundation/PxUserAllocated.h"
++ #include "CmPinnableArray.h"
++ #include "CmPinnableBitMap.h"
++ #include "PxsRigidBody.h"
++
++ namespace physx
++ {
++ class PxcNpMemBlockPool;
++
++ namespace Cm
++ {
++ class FlushPool;
++ }
++
++ namespace IG
++ {
++ class SimpleIslandManager;
++ }
++
++ struct PxvSimStats;
++ class PxsContactManager;
++ struct PxsContactManagerOutputCounts;
++ class PxvNphaseImplementationContext;
++
++ namespace Dy
++ {
++
++ /**
++ Defining class, so it can be forward declared without pulling in DyThreasholdTable.h.
++ */
++ class ThresholdStream : public PxArray<ThresholdStreamElement>{};
++
++ /**
++ Threshold stream that may be backed by device mapped host memory for the GPU pipeline,
++ hence the pageable fallback is disabled.
++ For the CPU pipeline, the stream is backed by pageable memory anyways, so no fallback
++ required either.
++ */
++ class ThresholdStreamMapped : public Cm::PinnableArray<ThresholdStreamElement>
++ {
++ public:
++ ThresholdStreamMapped(Cm::VirtualAllocatorCallback& allocator) :
++ Cm::PinnableArray<ThresholdStreamElement>(allocator, PxsHeapStats::eSOLVER, Cm::PinnableAllocatorFallback::eDISABLED)
++ {}
++ };
++
++ class Context : public PxUserAllocated
++ {
++ PX_NOCOPY(Context)
++ public:
++
++ // PT: TODO: consider making all of these public at this point
++ // PT: please avoid useless comments like "returns Blah" for a function called "getBlah".
++
++ PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mMaxBiasCoefficient; }
++ PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mMaxBiasCoefficient = coeff; }
++
++ PX_FORCE_INLINE PxReal getCorrelationDistance() const { return mCorrelationDistance; }
++ PX_FORCE_INLINE void setCorrelationDistance(PxReal f) { mCorrelationDistance = f; }
++
++ PX_FORCE_INLINE PxReal getBounceThreshold() const { return mBounceThreshold; }
++ PX_FORCE_INLINE void setBounceThreshold(PxReal f) { mBounceThreshold = f; }
++
++ PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mFrictionOffsetThreshold; }
++ PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal offset) { mFrictionOffsetThreshold = offset; }
++
++ PX_FORCE_INLINE PxReal getCCDSeparationThreshold() const { return mCCDSeparationThreshold; }
++ PX_FORCE_INLINE void setCCDSeparationThreshold(PxReal offset) { mCCDSeparationThreshold = offset; }
++
++ PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mSolverBatchSize; }
++ PX_FORCE_INLINE void setSolverBatchSize(PxU32 f) { mSolverBatchSize = f; }
++
++ PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mSolverArticBatchSize; }
++ PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 f) { mSolverArticBatchSize = f; }
++
++ PX_FORCE_INLINE PxReal getDt() const { return mDt; }
++ PX_FORCE_INLINE void setDt(const PxReal dt) { mDt = dt; }
++ // PT: TODO: we have a setDt function but it doesn't set the inverse dt, what's the story here?
++ PX_FORCE_INLINE PxReal getInvDt() const { return mInvDt; }
++
++ //Forces any cached body state to be updated!
++ PX_FORCE_INLINE void setStateDirty(bool dirty) { mBodyStateDirty = dirty; }
++ PX_FORCE_INLINE bool isStateDirty() const { return mBodyStateDirty; }
++
++ // Returns the maximum solver constraint size in this island in bytes.
++ PX_FORCE_INLINE PxU32 getMaxSolverConstraintSize() const { return mMaxSolverConstraintSize; }
++
++ PX_FORCE_INLINE PxReal getLengthScale() const { return mLengthScale; }
++ PX_FORCE_INLINE const PxVec3& getGravity() const { return mGravity; }
++ PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
++
++ PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return mThresholdStream; }
++ PX_FORCE_INLINE ThresholdStreamMapped& getForceChangedThresholdStream() { return mForceChangedThresholdStream; }
++ PX_FORCE_INLINE ThresholdTable& getThresholdTable() { return mThresholdTable; }
++
++ PX_FORCE_INLINE PxcDataStreamPool& getContactStreamPool() { return mContactStreamPool; }
++ PX_FORCE_INLINE PxcDataStreamPool& getPatchStreamPool() { return mPatchStreamPool; }
++ PX_FORCE_INLINE PxcDataStreamPool& getForceStreamPool() { return mForceStreamPool; }
++ PX_FORCE_INLINE Cm::PinnableArray<Dy::ConstraintWriteback>& getConstraintWriteBackPool() { return mConstraintWriteBackPool; }
++ PX_FORCE_INLINE PxcDataStreamPool& getFrictionPatchStreamPool() { return mFrictionPatchStreamPool; }
++
++ /**
++ \brief Returns whether sleeping is disabled in the scene
++ \return True if sleeping is disabled (PxSceneFlag::eDISABLE_SLEEPING is set)
++ */
++ PX_FORCE_INLINE bool isSleepingDisabled() const { return mIsSleepingDisabled; }
++ PX_FORCE_INLINE bool isEnhancedDeterminismEnabled() const { return mUseEnhancedDeterminism; }
++
++ /**
++ \brief Destroys this dynamics context
++ */
++ virtual void destroy() = 0;
++
++ /**
++ \brief The entry point for the constraint solver.
++ \param[in] dt The simulation time-step
++ \param[in] continuation The continuation task for the solver
++ \param[in] processLostTouchTask The task that processes lost touches
++
++ This method is called after the island generation has completed. Its main responsibilities are:
++ (1) Reserving the solver body pools
++ (2) Initializing the static and kinematic solver bodies, which are shared resources between islands.
++ (3) Construct the solver task chains for each island
++
++ Each island is solved as an independent solver task chain. In addition, large islands may be solved using multiple parallel tasks.
++ Island solving is asynchronous. Once all islands have been solved, the continuation task will be called.
++ */
++ virtual void update( Cm::FlushPool& flushPool, PxBaseTask* continuation, PxBaseTask* postPartitioningTask, PxBaseTask* processLostTouchTask,
++ PxvNphaseImplementationContext* nPhaseContext, PxU32 maxPatchesPerCM, PxU32 maxArticulationLinks,
++ PxReal dt, const PxVec3& gravity, Cm::PinnableBitMap& changedHandleMap) = 0;
++ virtual void updatePostPartitioning(PxBaseTask* /*processLostTouchTask*/,
++ PxvNphaseImplementationContext* /*nPhaseContext*/, PxU32 /*maxPatchesPerCM*/, PxU32 /*maxArticulationLinks*/,
++ PxReal /*dt*/, const PxVec3& /*gravity*/, Cm::PinnableBitMap& /*changedHandleMap*/) {}
++
++ virtual void processPatches( Cm::FlushPool& /*flushPool*/, PxBaseTask* /*continuation*/,
++ PxsContactManager** /*lostFoundPatchManagers*/, PxU32 /*nbLostFoundPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {}
++
++ /**
++ \brief This method copy gpu solver body data to cpu body core
++ */
++ virtual void updateBodyCore(PxBaseTask* /*continuation*/) {}
++
++ /**
++ \brief Called after update's task chain has completed. This collects the results of the solver together.
++ This method combines the results of several islands, e.g. constructing scene-level simulation statistics and merging together threshold streams for contact notification.
++ */
++ virtual void mergeResults() = 0;
++
++ virtual void setSimulationController(PxsSimulationController* simulationController) = 0;
++
++ virtual void getDataStreamBase(void*& /*contactStreamBase*/, void*& /*patchStreamBase*/, void*& /*forceAndIndicesStreamBase*/) {}
++
++ virtual PxSolverType::Enum getSolverType() const = 0;
++
++ virtual PxsExternalAccelerationProvider& getExternalRigidAccelerations() { return mRigidExternalAccelerations; }
++
++ // Only used for Direct GPU API pipeline at the moment.
++ virtual void setActiveBreakableConstraintCount(PxU32 activeBreakableConstraintCount) { PX_UNUSED(activeBreakableConstraintCount); }
++
++ protected:
++
++ Context(IG::SimpleIslandManager& islandManager, Cm::VirtualAllocatorCallback& allocator, Cm::VirtualAllocatorCallback& mappedAllocator,
++ PxvSimStats& simStats, PxReal maxBiasCoefficient, PxReal lengthScale, PxU64 contextID, PxSceneFlags sceneFlags) :
++ mForceChangedThresholdStream(mappedAllocator),
++ mIslandManager (islandManager),
++ mDt (1.0f),
++ mInvDt (1.0f),
++ mMaxBiasCoefficient (maxBiasCoefficient),
++ mEnableStabilization (sceneFlags & PxSceneFlag::eENABLE_STABILIZATION),
++ mUseEnhancedDeterminism (sceneFlags & PxSceneFlag::eENABLE_ENHANCED_DETERMINISM),
++ mSolveArticulationContactLast(sceneFlags & PxSceneFlag::eSOLVE_ARTICULATION_CONTACT_LAST),
++ mIsSleepingDisabled (sceneFlags & PxSceneFlag::eDISABLE_SLEEPING),
++ mBounceThreshold (-2.0f),
++ mLengthScale (lengthScale),
++ mSolverBatchSize (32),
++ mConstraintWriteBackPool (allocator),
++ mSimStats (simStats),
++ mContextID (contextID),
++ mBodyStateDirty (false)
++ {
++ }
++
++ virtual ~Context() {}
++
++ ThresholdStream mThresholdStream;
++ ThresholdStreamMapped mForceChangedThresholdStream;
++ ThresholdTable mThresholdTable;
++
++ IG::SimpleIslandManager& mIslandManager;
++ PxsSimulationController* mSimulationController;
++ /**
++ \brief Time-step.
++ */
++ PxReal mDt;
++ /**
++ \brief 1/time-step.
++ */
++ PxReal mInvDt;
++
++ PxReal mMaxBiasCoefficient;
++
++ const bool mEnableStabilization;
++ const bool mUseEnhancedDeterminism;
++ const bool mSolveArticulationContactLast;
++ const bool mIsSleepingDisabled;
++
++ PxVec3 mGravity;
++ /**
++ \brief max solver constraint size
++ */
++ PxU32 mMaxSolverConstraintSize;
++
++ /**
++ \brief Threshold controlling the relative velocity at which the solver transitions between restitution and bias for solving normal contact constraint.
++ */
++ PxReal mBounceThreshold;
++ /**
++ \brief Threshold controlling whether friction anchors are constructed or not. If the separation is above mFrictionOffsetThreshold, the contact will not be considered to become a friction anchor
++ */
++ PxReal mFrictionOffsetThreshold;
++
++ /**
++ \brief Threshold controlling whether distant contacts are processed using bias, restitution or a combination of the two. This only has effect on pairs involving bodies that have enabled speculative CCD simulation mode.
++ */
++ PxReal mCCDSeparationThreshold;
++
++ /**
++ \brief Threshold for controlling friction correlation
++ */
++ PxReal mCorrelationDistance;
++
++ /**
++ \brief The length scale from PxTolerancesScale::length.
++ */
++ PxReal mLengthScale;
++
++ /**
++ \brief The minimum size of an island to generate a solver task chain.
++ */
++ PxU32 mSolverBatchSize;
++
++ /**
++ \brief The minimum number of articulations required to generate a solver task chain.
++ */
++ PxU32 mSolverArticBatchSize;
++
++ /**
++ \brief Structure to encapsulate contact stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
++ */
++ PxcDataStreamPool mContactStreamPool;
++
++ /**
++ \brief Struct to encapsulate the contact patch stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
++ */
++
++ PxcDataStreamPool mPatchStreamPool;
++
++ /**
++ \brief Structure to encapsulate force stream allocations. Used by GPU solver to reference pre-allocated pinned host memory for force reports.
++ */
++ PxcDataStreamPool mForceStreamPool;
++
++ /**
++ \brief Struct to encapsulate the friction patch stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
++ */
++ PxcDataStreamPool mFrictionPatchStreamPool;
++
++ /**
++ \brief Structure to encapsulate constraint write back allocations. Used by GPU/CPU solver to reference pre-allocated pinned host memory for breakable joint reports.
++ */
++ Cm::PinnableArray<Dy::ConstraintWriteback> mConstraintWriteBackPool;
++
++ PxvSimStats& mSimStats;
++
++ const PxU64 mContextID;
++
++ PxsExternalAccelerationProvider mRigidExternalAccelerations;
++
++ bool mBodyStateDirty;
++ };
++
++ Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, Cm::FlushPool& taskPool, PxvSimStats& simStats,
++ Cm::VirtualAllocatorCallback& allocator, PxsMaterialManager* materialManager,
++ IG::SimpleIslandManager& islandManager, PxU64 contextID, PxReal maxBiasCoefficient,
++ PxReal lengthScale, PxSceneFlags sceneFlags);
++
++ Context* createTGSDynamicsContext( PxcNpMemBlockPool* memBlockPool, Cm::FlushPool& taskPool, PxvSimStats& simStats,
++ Cm::VirtualAllocatorCallback& allocator, PxsMaterialManager* materialManager,
++ IG::SimpleIslandManager& islandManager, PxU64 contextID,
++ PxReal lengthScale, PxSceneFlags sceneFlags);
++ }
++
++ }
++
++ #endif
++