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 SC_SCENE_H
++ #define SC_SCENE_H
++
++ #include "PxPhysXConfig.h"
++ #include "PxScene.h"
++ #include "PxSimulationEventCallback.h"
++ #include "foundation/PxPool.h"
++ #include "foundation/PxHashSet.h"
++ #include "foundation/PxHashMap.h"
++ #include "CmTask.h"
++ #include "CmFlushPool.h"
++ #include "CmPreallocatingPool.h"
++ #include "foundation/PxBitMap.h"
++ #include "ScIterators.h"
++ #include "PxsMaterialManager.h"
++ #include "PxvManager.h"
++ #include "ScStaticCore.h"
++ #include "ScBodyCore.h"
++ #include "PxAggregate.h"
++ #include "PxsContext.h"
++ #include "GuPrunerTypedef.h"
++ #include "DyContext.h"
++ #include "ScFiltering.h"
++ #include "ScBroadphase.h"
++ #include "ScInteraction.h"
++ #include "ScArticulationJointSim.h"
++ #include "ScConstraintInteraction.h"
++ #include "ScConstraintSim.h"
++ #include "BpVolumeData.h"
++
++ #define PX_MAX_DOMINANCE_GROUP 32
++
++ namespace
++ {
++ class OverlapFilterTask;
++ class OnOverlapCreatedTask;
++ class IslandInsertionTask;
++ }
++
++ namespace physx
++ {
++ class NpShape;
++
++ struct PxTriggerPair;
++
++ class PxsSimulationController;
++ class PxsSimulationControllerCallback;
++ class PxsMemoryManager;
++
++ #if PX_SUPPORT_GPU_PHYSX
++ class PxsKernelWranglerManager;
++ class PxsHeapMemoryAllocatorManager;
++ #endif
++
++ namespace IG
++ {
++ class SimpleIslandManager;
++ typedef PxU32 EdgeIndex;
++ }
++
++ struct DelayedGPUTypes
++ {
++ struct Data
++ {
++ IG::EdgeIndex mEdgeIndex;
++ IG::Edge::EdgeType mType;
++ };
++ PxArray<Data> mDelayed;
++ PxMutex mLock;
++ };
++
++ class PxsCCDContext;
++
++ namespace Cm
++ {
++ class IDPool;
++ }
++
++ namespace Bp
++ {
++ class AABBManagerBase;
++ class BroadPhase;
++ class BoundsArray;
++ }
++
++ namespace Dy
++ {
++ class Context;
++ #if PX_SUPPORT_GPU_PHYSX
++ class DeformableSurface;
++ class DeformableVolume;
++ class ParticleSystem;
++ #endif
++ }
++
++ namespace Sc
++ {
++ class ActorSim;
++ class ElementSim;
++
++ class ShapeCore;
++ class RigidCore;
++ class ConstraintCore;
++ class ArticulationCore;
++ class ArticulationJointCore;
++ class ArticulationSpatialTendonCore;
++ class ArticulationFixedTendonCore;
++ class ArticulationMimicJointCore;
++ class LLDeformableSurfacePool;
++ class LLDeformableVolumePool;
++ class LLParticleSystemPool;
++
++ class BodyCore;
++ class DeformableSurfaceCore;
++ class DeformableVolumeCore;
++ class ParticleSystemCore;
++
++ class NPhaseCore;
++ class ElementSimInteraction;
++ class BodySim;
++ class ShapeSim;
++ class RigidSim;
++ class StaticSim;
++ class ConstraintSim;
++ struct TriggerPairExtraData;
++ class ObjectIDTracker;
++ class ActorPairReport;
++ class ContactStreamManager;
++ class SqBoundsManager;
++ class ShapeInteraction;
++ class ElementInteractionMarker;
++ class ArticulationSim;
++ class DeformableSurfaceSim;
++ class DeformableVolumeSim;
++ class ParticleSystemSim;
++ class SimStats;
++ struct SimStateData;
++
++ struct BatchInsertionState
++ {
++ BodySim* bodySim;
++ StaticSim*staticSim;
++ ShapeSim* shapeSim;
++ ptrdiff_t staticActorOffset;
++ ptrdiff_t staticShapeTableOffset;
++ ptrdiff_t dynamicActorOffset;
++ ptrdiff_t dynamicShapeTableOffset;
++ ptrdiff_t shapeOffset;
++ };
++
++ struct BatchRemoveState
++ {
++ PxInlineArray<ShapeSim*, 64> bufferedShapes;
++ PxInlineArray<const ShapeCore*, 64> removedShapes;
++ };
++
++ struct SceneInternalFlag
++ {
++ enum Enum
++ {
++ eSCENE_SIP_STATES_DIRTY_DOMINANCE = (1<<1),
++ eSCENE_SIP_STATES_DIRTY_VISUALIZATION = (1<<2),
++ eSCENE_DEFAULT = 0
++ };
++ };
++
++ struct SimulationStage
++ {
++ enum Enum
++ {
++ eCOMPLETE,
++ eCOLLIDE,
++ eFETCHCOLLIDE,
++ eADVANCE,
++ eFETCHRESULT
++ };
++ };
++
++ struct SqBoundsSync;
++ struct SqRefFinder;
++
++ struct DeformableRigidInteraction
++ {
++ IG::EdgeIndex mIndex;
++ PxU32 mCount;
++
++ DeformableRigidInteraction() : mCount(0) {}
++ };
++
++ class Scene : public PxUserAllocated
++ {
++ struct SimpleBodyPair
++ {
++ ActorSim* body1;
++ ActorSim* body2;
++ PxU32 body1ID;
++ PxU32 body2ID;
++ };
++
++ PX_NOCOPY(Scene)
++
++ public:
++ Scene(const PxSceneDesc& desc, PxU64 contextID);
++ ~Scene() {} //use release() plz.
++
++ void preAllocate(PxU32 nbStatics, PxU32 nbBodies, PxU32 nbStaticShapes, PxU32 nbDynamicShapes);
++ void release();
++
++ PX_FORCE_INLINE PxsSimulationController* getSimulationController() { return mSimulationController; }
++ PX_FORCE_INLINE const PxsSimulationController* getSimulationController() const { return mSimulationController; }
++
++ PX_FORCE_INLINE Bp::AABBManagerBase* getAABBManager() { return mAABBManager; }
++ PX_FORCE_INLINE const Bp::AABBManagerBase* getAABBManager() const { return mAABBManager; }
++ PX_FORCE_INLINE PxArray<BodySim*>& getCcdBodies() { return mCcdBodies; }
++
++ PX_FORCE_INLINE IG::SimpleIslandManager* getSimpleIslandManager() { return mSimpleIslandManager; }
++ PX_FORCE_INLINE const IG::SimpleIslandManager* getSimpleIslandManager() const { return mSimpleIslandManager; }
++
++ PX_FORCE_INLINE SimulationStage::Enum getSimulationStage() const { return mSimulationStage; }
++ PX_FORCE_INLINE void setSimulationStage(SimulationStage::Enum stage) { mSimulationStage = stage; }
++
++ PX_FORCE_INLINE PxPool<SimStateData>* getSimStateDataPool() { return mSimStateDataPool; }
++ PX_FORCE_INLINE PxBitMap& getDirtyShapeSimMap() { return mDirtyShapeSimMap; }
++
++ PX_FORCE_INLINE void setGravity(const PxVec3& g) { mGravity = g; }
++ PX_FORCE_INLINE const PxVec3& getGravity() const { return mGravity; }
++
++ PX_FORCE_INLINE void setElapsedTime(PxReal t) { mDt = t; mOneOverDt = t > 0.0f ? 1.0f/t : 0.0f; }
++ PX_FORCE_INLINE PxReal getOneOverDt() const { return mOneOverDt; }
++ // PX_FORCE_INLINE PxReal getDt() const { return mDt; }
++
++ PX_FORCE_INLINE void setLimits(const PxSceneLimits& limits) { mLimits = limits; }
++ PX_FORCE_INLINE const PxSceneLimits& getLimits() const { return mLimits; }
++
++ PX_FORCE_INLINE void setBatchRemove(BatchRemoveState* bs) { mBatchRemoveState = bs; }
++ PX_FORCE_INLINE BatchRemoveState* getBatchRemove() const { return mBatchRemoveState; }
++
++ PX_FORCE_INLINE void setMaxArticulationLinks(const PxU32 maxLinks) { mMaxNbArticulationLinks = maxLinks; }
++ PX_FORCE_INLINE PxU32 getMaxArticulationLinks() const { return mMaxNbArticulationLinks; }
++
++ // mDynamicsContext wrappers
++ PX_FORCE_INLINE Dy::Context* getDynamicsContext() { return mDynamicsContext; }
++ PX_FORCE_INLINE const Dy::Context* getDynamicsContext() const { return mDynamicsContext; }
++
++ PX_FORCE_INLINE void setBounceThresholdVelocity(PxReal t) { mDynamicsContext->setBounceThreshold(-t); }
++ PX_FORCE_INLINE PxReal getBounceThresholdVelocity() const { return -mDynamicsContext->getBounceThreshold(); }
++
++ PX_FORCE_INLINE PxSolverType::Enum getSolverType() const { return mDynamicsContext->getSolverType(); }
++
++ PX_FORCE_INLINE void setSolverBatchSize(PxU32 solverBatchSize) { mDynamicsContext->setSolverBatchSize(solverBatchSize); }
++ PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mDynamicsContext->getSolverBatchSize(); }
++
++ PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 solverBatchSize) { mDynamicsContext->setSolverArticBatchSize(solverBatchSize); }
++ PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mDynamicsContext->getSolverArticBatchSize(); }
++
++ PX_FORCE_INLINE void setCCDMaxSeparation(PxReal separation) { mDynamicsContext->setCCDSeparationThreshold(separation); }
++ PX_FORCE_INLINE PxReal getCCDMaxSeparation() const { return mDynamicsContext->getCCDSeparationThreshold(); }
++
++ PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mDynamicsContext->setMaxBiasCoefficient(coeff); }
++ PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mDynamicsContext->getMaxBiasCoefficient(); }
++
++ PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal t) { mDynamicsContext->setFrictionOffsetThreshold(t); }
++ PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mDynamicsContext->getFrictionOffsetThreshold(); }
++
++ PX_FORCE_INLINE void setFrictionCorrelationDistance(PxReal t) { mDynamicsContext->setCorrelationDistance(t); }
++ PX_FORCE_INLINE PxReal getFrictionCorrelationDistance() const { return mDynamicsContext->getCorrelationDistance(); }
++
++ PX_FORCE_INLINE PxReal getLengthScale() const { return mDynamicsContext->getLengthScale(); }
++
++ PX_FORCE_INLINE void setDynamicsDirty() { mDynamicsContext->setStateDirty(true); }
++ //~mDynamicsContext wrappers
++
++ // mLLContext wrappers
++ PX_FORCE_INLINE PxsContext* getLowLevelContext() { return mLLContext; }
++ PX_FORCE_INLINE const PxsContext* getLowLevelContext() const { return mLLContext; }
++
++ PX_FORCE_INLINE Cm::FlushPool* getFlushPool() { return &mLLContext->getTaskPool(); }
++
++ void setBodyAccelerationTask(PxLightCpuTask* task) { mBodyAccelerationTask = task; }
++
++ PX_FORCE_INLINE void setPCM(bool enabled) { mLLContext->setPCM(enabled); }
++ PX_FORCE_INLINE void setContactCache(bool enabled) { mLLContext->setContactCache(enabled); }
++
++ PX_FORCE_INLINE void setContactModifyCallback(PxContactModifyCallback* callback) { mLLContext->setContactModifyCallback(callback); }
++ PX_FORCE_INLINE PxContactModifyCallback* getContactModifyCallback() const { return mLLContext->getContactModifyCallback(); }
++
++ PX_FORCE_INLINE void setDeformableSurfaceGpuPostSolveCallback(PxPostSolveCallback* callback) { mSimulationController->setDeformableSurfaceGpuPostSolveCallback(callback); }
++ PX_FORCE_INLINE void setDeformableVolumeGpuPostSolveCallback(PxPostSolveCallback* callback) { mSimulationController->setDeformableVolumeGpuPostSolveCallback(callback); }
++
++ PX_FORCE_INLINE void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value)
++ {
++ mVisualizationParameterChanged = true;
++ mLLContext->setVisualizationParameter(param, value);
++ }
++
++ PX_FORCE_INLINE PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const { return mLLContext->getVisualizationParameter(param); }
++ PX_FORCE_INLINE void setVisualizationCullingBox(const PxBounds3& box) { mLLContext->setVisualizationCullingBox(box); }
++ PX_FORCE_INLINE const PxBounds3& getVisualizationCullingBox() const { return mLLContext->getVisualizationCullingBox(); }
++ PX_FORCE_INLINE PxReal getVisualizationScale() const { return mLLContext->getRenderScale(); }
++ PX_FORCE_INLINE PxRenderBuffer& getRenderBuffer() { return mLLContext->getRenderBuffer(); }
++
++ PX_FORCE_INLINE void setNbContactDataBlocks(PxU32 blockCount) { mLLContext->getNpMemBlockPool().setBlockCount(blockCount); }
++ PX_FORCE_INLINE PxU32 getNbContactDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getUsedBlockCount(); }
++ PX_FORCE_INLINE PxU32 getMaxNbContactDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getMaxUsedBlockCount(); }
++ PX_FORCE_INLINE PxU32 getMaxNbConstraintDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getPeakConstraintBlockCount(); }
++ PX_FORCE_INLINE void setScratchBlock(void* addr, PxU32 size) { mLLContext->setScratchBlock(addr, size); }
++ //~mLLContext wrappers
++
++ PX_FORCE_INLINE void setFlags(PxSceneFlags flags)
++ {
++ mPublicFlags = flags;
++ }
++ PX_FORCE_INLINE PxSceneFlags getFlags() const { return mPublicFlags; }
++ PX_FORCE_INLINE bool readInternalFlag(SceneInternalFlag::Enum flag) const { return (mInternalFlags & flag) != 0; }
++
++ void addStatic(StaticCore&, NpShape*const *shapes, PxU32 nbShapes, size_t shapePtrOffset, PxBounds3* uninflatedBounds);
++ void removeStatic(StaticCore&, PxInlineArray<const ShapeCore*,64>& removedShapes, bool wakeOnLostTouch);
++
++ void addBody(BodyCore&, NpShape*const *shapes, PxU32 nbShapes, size_t shapePtrOffset, PxBounds3* uninflatedBounds, bool compound);
++ void removeBody(BodyCore&, PxInlineArray<const ShapeCore*,64>& removedShapes, bool wakeOnLostTouch);
++
++ // Batch insertion API.
++ // the bounds generated here are the uninflated bounds for the shapes, *if* they are trigger or sim shapes.
++ // It's up to the caller to ensure the bounds array is big enough.
++ // Some care is required in handling these since sim and SQ tweak the bounds in slightly different ways.
++
++ void startBatchInsertion(BatchInsertionState&);
++ void addStatic(PxActor* actor, BatchInsertionState&, PxBounds3* outBounds);
++ void addBody(PxActor* actor, BatchInsertionState&, PxBounds3* outBounds, bool compound);
++ void finishBatchInsertion(BatchInsertionState&);
++
++ void addConstraint(ConstraintCore&, RigidCore*, RigidCore*);
++ void removeConstraint(ConstraintCore&);
++
++ void addConstraintToMap(ConstraintCore& constraint, RigidCore*, RigidCore*);
++ void removeConstraintFromMap(const ConstraintInteraction&);
++
++ void addArticulation(ArticulationCore&, BodyCore& root);
++ void removeArticulation(ArticulationCore&);
++
++ void addArticulationJoint(ArticulationJointCore&, BodyCore& parent, BodyCore& child);
++ void removeArticulationJoint(ArticulationJointCore&);
++
++ void addArticulationTendon(ArticulationSpatialTendonCore&);
++ static void removeArticulationTendon(ArticulationSpatialTendonCore&);
++
++ void addArticulationTendon(ArticulationFixedTendonCore&);
++ static void removeArticulationTendon(ArticulationFixedTendonCore&);
++
++ void addArticulationMimicJoint(ArticulationMimicJointCore&);
++ static void removeArticulationMimicJoint(ArticulationMimicJointCore&);
++
++ void addArticulationSimControl(ArticulationCore& core);
++ void removeArticulationSimControl(ArticulationCore& core);
++
++ #if PX_SUPPORT_GPU_PHYSX
++ void gpu_updateBodySim(BodySim& sim);
++ #else
++ PX_FORCE_INLINE void gpu_updateBodySim(BodySim&) {}
++ #endif
++
++ PX_FORCE_INLINE PxU32 getNbArticulations() const { return mArticulations.size(); }
++ PX_FORCE_INLINE ArticulationCore* const* getArticulations() { return mArticulations.getEntries(); }
++
++ PX_FORCE_INLINE PxU32 getNbConstraints() const { return mConstraints.size(); }
++ PX_FORCE_INLINE ConstraintCore*const* getConstraints() const { return mConstraints.getEntries(); }
++ PX_FORCE_INLINE ConstraintCore*const* getConstraints() { return mConstraints.getEntries(); }
++
++ void initContactsIterator(ContactIterator&, PxsContactManagerOutputIterator&);
++
++ void setSimulationEventCallback(PxSimulationEventCallback* callback);
++ PxSimulationEventCallback* getSimulationEventCallback() const;
++
++ void setCCDContactModifyCallback(PxCCDContactModifyCallback* callback);
++ PxCCDContactModifyCallback* getCCDContactModifyCallback() const;
++
++ void setCCDMaxPasses(PxU32 ccdMaxPasses);
++ PxU32 getCCDMaxPasses() const;
++
++ void setCCDThreshold(PxReal t);
++ PxReal getCCDThreshold() const;
++
++ // Broad-phase management
++ void finishBroadPhase(PxBaseTask* continuation);
++ void finishBroadPhaseStage2(PxU32 ccdPass);
++ void preallocateContactManagers(PxBaseTask* continuation);
++
++ void islandInsertion(PxBaseTask* continuation);
++ void registerContactManagers(PxBaseTask* continuation);
++ void registerInteractions(PxBaseTask* continuation);
++ void registerSceneInteractions(PxBaseTask* continuation);
++
++ void secondPassNarrowPhase(PxBaseTask* continuation);
++
++ void setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance);
++ PxDominanceGroupPair getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const;
++
++ // Run
++ void simulate(PxReal timeStep, PxBaseTask* continuation);
++ void advance(PxReal timeStep, PxBaseTask* continuation);
++ void collide(PxReal timeStep, PxBaseTask* continuation);
++ void endSimulation();
++ void flush(bool sendPendingReports);
++ void fireBrokenConstraintCallbacks();
++ void fireTriggerCallbacks();
++ void fireQueuedContactCallbacks();
++ void fireOnAdvanceCallback();
++
++ const PxArray<PxContactPairHeader>&
++ getQueuedContactPairHeaders();
++
++ void postCallbacksPreSync();
++ void postCallbacksPreSyncKinematics();
++ void postReportsCleanup();
++ void fireCallbacksPostSync();
++ void syncSceneQueryBounds(SqBoundsSync& sync, SqRefFinder& finder);
++
++ PxU32 getDefaultContactReportStreamBufferSize() const;
++
++ void visualizeStartStep();
++ void visualizeContacts();
++
++ // PX_ENABLE_SIM_STATS
++ void getStats(PxSimulationStatistics& stats) const;
++ PX_FORCE_INLINE SimStats& getStatsInternal() { return *mStats; }
++ // PX_ENABLE_SIM_STATS
++
++ void buildActiveActors();
++ void buildActiveAndFrozenActors();
++ PxActor** getActiveActors(PxU32& nbActorsOut);
++ void setActiveActors(PxActor** actors, PxU32 nbActors);
++
++ PxActor** getFrozenActors(PxU32& nbActorsOut);
++
++ void finalizeContactStreamAndCreateHeader(PxContactPairHeader& header,
++ const ActorPairReport& aPair,
++ ContactStreamManager& cs, PxU32 removedShapeTestMask);
++
++ PxTaskManager* getTaskManagerPtr() const { return mTaskManager; }
++ PxCudaContextManager* getCudaContextManager() const { return mCudaContextManager; }
++
++ void shiftOrigin(const PxVec3& shift);
++
++ PX_FORCE_INLINE bool isCollisionPhaseActive() const { return mIsCollisionPhaseActive; }
++ PX_FORCE_INLINE void setCollisionPhaseToActive() { PX_ASSERT(!mIsCollisionPhaseActive); mIsCollisionPhaseActive = true; }
++ PX_FORCE_INLINE void setCollisionPhaseToInactive() { PX_ASSERT(mIsCollisionPhaseActive); mIsCollisionPhaseActive = false; }
++
++ void addShape_(RigidSim&, ShapeCore&);
++ void removeShape_(ShapeSim&, bool wakeOnLostTouch);
++
++ void registerShapeInNphase(RigidCore* rigidCore, const ShapeCore& shapeCore, const PxU32 transformCacheID);
++ void unregisterShapeFromNphase(const ShapeCore& shapeCore, const PxU32 transformCacheID);
++
++ void notifyNphaseOnUpdateShapeMaterial(const ShapeCore& shapeCore);
++
++ // Get an array of the active actors.
++ PX_FORCE_INLINE BodyCore*const* getActiveBodiesArray() const { return mActiveBodies.begin(); }
++ PX_FORCE_INLINE PxU32 getNumActiveBodies() const { return mActiveBodies.size(); }
++
++ PX_FORCE_INLINE BodyCore*const* getActiveCompoundBodiesArray() const { return mActiveCompoundBodies.begin(); }
++ PX_FORCE_INLINE PxU32 getNumActiveCompoundBodies() const { return mActiveCompoundBodies.size(); }
++
++ PX_FORCE_INLINE PxU32 getNbInteractions(InteractionType::Enum type) const { return mInteractions[type].size(); }
++ PX_FORCE_INLINE PxU32 getNbActiveInteractions(InteractionType::Enum type) const { return mActiveInteractionCount[type]; }
++ // Get all interactions of a certain type
++ PX_FORCE_INLINE ElementSimInteraction** getInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); }
++ PX_FORCE_INLINE ElementSimInteraction** getActiveInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); }
++
++ void registerInteraction(ElementSimInteraction* interaction, bool active);
++ void unregisterInteraction(ElementSimInteraction* interaction);
++
++ void notifyInteractionActivated(Interaction* interaction);
++ void notifyInteractionDeactivated(Interaction* interaction);
++
++ // for pool management of interaction arrays, a major cause of dynamic allocation
++ void** allocatePointerBlock(PxU32 size);
++ void deallocatePointerBlock(void**, PxU32 size);
++ private:
++ // Get the number of active one-way dominator actors
++ PX_FORCE_INLINE PxU32 getActiveKinematicBodiesCount() const { return mActiveKinematicBodyCount; }
++
++ // Get an iterator to the active one-way dominator actors
++ PX_FORCE_INLINE BodyCore*const* getActiveKinematicBodies() const { return mActiveBodies.begin(); }
++
++ // Get the number of active non-kinematic actors
++ PX_FORCE_INLINE PxU32 getActiveDynamicBodiesCount() const { return mActiveBodies.size() - mActiveKinematicBodyCount; }
++
++ // Get the active non-kinematic actors
++ PX_FORCE_INLINE BodyCore*const* getActiveDynamicBodies() const { return mActiveBodies.begin() + mActiveKinematicBodyCount; }
++
++ void swapInteractionArrayIndices(PxU32 id1, PxU32 id2, InteractionType::Enum type);
++ public:
++ void addDirtyArticulationSim(ArticulationSim* artiSim);
++ void removeDirtyArticulationSim(ArticulationSim* artiSim);
++
++ void addToActiveList(ActorSim& actor);
++ void removeFromActiveList(ActorSim& actor);
++ void removeFromActiveCompoundBodyList(BodySim& actor);
++ void swapInActiveBodyList(BodySim& body); // call when an active body gets switched from dynamic to kinematic or vice versa
++
++ void addActiveBreakableConstraint(ConstraintSim*, ConstraintInteraction*);
++ void removeActiveBreakableConstraint(ConstraintSim*);
++ //the Actor should register its top level shapes with these.
++ void removeBody(BodySim&);
++
++ //lists of actors woken up or put to sleep last simulate
++ void onBodyWakeUp(BodySim* body);
++ void onBodySleep(BodySim* body);
++
++ PX_FORCE_INLINE bool isValid() const { return (mLLContext != NULL); }
++
++ void addToLostTouchList(ActorSim& body1, ActorSim& body2);
++
++ Bp::AggregateHandle createAggregate(void* userData, PxU32 maxNumShapes, PxAggregateFilterHint filterHint, PxU32 envID);
++
++ void deleteAggregate(PxU32 id);
++
++ PX_FORCE_INLINE PxPool2<ConstraintInteraction, 4096>& getConstraintInteractionPool() { return mConstraintInteractionPool; }
++ public:
++ PX_FORCE_INLINE const PxsMaterialManager& getMaterialManager() const { return mMaterialManager; }
++ PX_FORCE_INLINE PxsMaterialManager& getMaterialManager() { return mMaterialManager; }
++
++ PX_FORCE_INLINE const BroadphaseManager& getBroadphaseManager() const { return mBroadphaseManager; }
++ PX_FORCE_INLINE BroadphaseManager& getBroadphaseManager() { return mBroadphaseManager; }
++ PX_FORCE_INLINE bool fireOutOfBoundsCallbacks()
++ {
++ return mBroadphaseManager.fireOutOfBoundsCallbacks(mAABBManager, *mElementIDPool, mContextId);
++ }
++ // Collision filtering
++ void setFilterShaderData(const void* data, PxU32 dataSize);
++ PX_FORCE_INLINE const void* getFilterShaderDataFast() const { return mFilterShaderData; }
++ PX_FORCE_INLINE PxU32 getFilterShaderDataSizeFast() const { return mFilterShaderDataSize; }
++ PX_FORCE_INLINE PxSimulationFilterShader getFilterShaderFast() const { return mFilterShader; }
++ PX_FORCE_INLINE PxSimulationFilterCallback* getFilterCallbackFast() const { return mFilterCallback; }
++ PX_FORCE_INLINE PxPairFilteringMode::Enum getKineKineFilteringMode() const { return mKineKineFilteringMode; }
++ PX_FORCE_INLINE PxPairFilteringMode::Enum getStaticKineFilteringMode() const { return mStaticKineFilteringMode; }
++
++ PX_FORCE_INLINE PxU32 getTimeStamp() const { return mTimeStamp; }
++ PX_FORCE_INLINE PxU32 getReportShapePairTimeStamp() const { return mReportShapePairTimeStamp; }
++
++ PX_FORCE_INLINE NPhaseCore* getNPhaseCore() const { return mNPhaseCore; }
++
++ void checkConstraintBreakage();
++
++ PX_FORCE_INLINE PxArray<TriggerPairExtraData>&
++ getTriggerBufferExtraData() { return *mTriggerBufferExtraData; }
++ PX_FORCE_INLINE PxArray<PxTriggerPair>& getTriggerBufferAPI() { return mTriggerBufferAPI; }
++ void reserveTriggerReportBufferSpace(const PxU32 pairCount, PxTriggerPair*& triggerPairBuffer, TriggerPairExtraData*& triggerPairExtraBuffer);
++
++ PX_FORCE_INLINE ObjectIDTracker& getActorIDTracker() { return *mActorIDTracker; }
++
++ PX_FORCE_INLINE void markReleasedBodyIDForLostTouch(PxU32 id) { mLostTouchPairsDeletedBodyIDs.growAndSet(id); }
++ void resizeReleasedBodyIDMaps(PxU32 maxActors, PxU32 numActors);
++
++ PX_FORCE_INLINE StaticSim& getStaticAnchor() { return *mStaticAnchor; }
++
++ PX_FORCE_INLINE Bp::BoundsArray& getBoundsArray() const { return *mBoundsArray; }
++ PX_FORCE_INLINE void updateContactDistance(PxU32 idx, PxReal distance) { (*mContactDistance)[idx] = distance; mHasContactDistanceChanged = true; }
++ PX_FORCE_INLINE SqBoundsManager& getSqBoundsManager() const { return *mSqBoundsManager; }
++
++ PX_FORCE_INLINE BodyCore* const* getSleepBodiesArray(PxU32& count) { count = mSleepBodies.size(); return mSleepBodies.getEntries(); }
++
++ PX_FORCE_INLINE PxTaskManager& getTaskManager() const { PX_ASSERT(mTaskManager); return *mTaskManager; }
++
++ PX_FORCE_INLINE void setPostSolverVelocityNeeded() { mContactReportsNeedPostSolverVelocity = true; }
++
++ PX_FORCE_INLINE ObjectIDTracker& getConstraintIDTracker() { return *mConstraintIDTracker; }
++ PX_FORCE_INLINE ObjectIDTracker& getElementIDPool() { return *mElementIDPool; }
++ PX_FORCE_INLINE PxBitMap& getVelocityModifyMap() { return mVelocityModifyMap; }
++
++ void* allocateConstraintBlock(PxU32 size);
++ void deallocateConstraintBlock(void* addr, PxU32 size);
++
++ void stepSetupCollide(PxBaseTask* continuation);//This is very important to guarantee thread safety in the collide
++ PX_FORCE_INLINE void addToPosePreviewList(BodySim& b) { PX_ASSERT(!mPosePreviewBodies.contains(&b)); mPosePreviewBodies.insert(&b); }
++ PX_FORCE_INLINE void removeFromPosePreviewList(BodySim& b) { PX_ASSERT(mPosePreviewBodies.contains(&b)); mPosePreviewBodies.erase(&b); }
++ #if PX_DEBUG
++ PX_FORCE_INLINE bool isInPosePreviewList(BodySim& b) const { return mPosePreviewBodies.contains(&b); }
++ #endif
++
++ PX_FORCE_INLINE void setSpeculativeCCDRigidBody(PxU32 index) { mSpeculativeCCDRigidBodyBitMap.growAndSet(index); }
++ PX_FORCE_INLINE void resetSpeculativeCCDRigidBody(PxU32 index) { mSpeculativeCCDRigidBodyBitMap.boundedReset(index); }
++
++ PX_FORCE_INLINE void setSpeculativeCCDArticulationLink(PxU32 index) { mSpeculativeCDDArticulationBitMap.growAndSet(index); }
++ PX_FORCE_INLINE void resetSpeculativeCCDArticulationLink(PxU32 index) { mSpeculativeCDDArticulationBitMap.boundedReset(index); }
++
++ PX_FORCE_INLINE PxU64 getContextId() const { return mContextId; }
++ PX_FORCE_INLINE bool isUsingGpuDynamicsOrBp() const { return mUseGpuBp || mUseGpuDynamics; }
++ PX_FORCE_INLINE bool isUsingGpuDynamicsAndBp() const { return mUseGpuBp && mUseGpuDynamics; }
++ PX_FORCE_INLINE bool isUsingGpuDynamics() const { return mUseGpuDynamics; }
++ PX_FORCE_INLINE bool isUsingGpuBp() const { return mUseGpuBp; }
++
++ PX_FORCE_INLINE void setDirectGPUAPIInitialized() { mIsDirectGPUAPIInitialized = true; }
++ PX_FORCE_INLINE bool isDirectGPUAPIInitialized() const { return mIsDirectGPUAPIInitialized; }
++
++ // statistics counters increase/decrease
++ PX_FORCE_INLINE void increaseNumKinematicsCounter() { mNbRigidKinematic++; }
++ PX_FORCE_INLINE void decreaseNumKinematicsCounter() { mNbRigidKinematic--; }
++ PX_FORCE_INLINE void increaseNumDynamicsCounter() { mNbRigidDynamics++; }
++ PX_FORCE_INLINE void decreaseNumDynamicsCounter() { mNbRigidDynamics--; }
++
++ ConstraintCore* findConstraintCore(const ActorSim* sim0, const ActorSim* sim1);
++
++ //internal private methods:
++ private:
++ void activateEdgesInternal(IG::Edge::EdgeType type);
++ void releaseConstraints(bool endOfScene);
++ PX_INLINE void clearBrokenConstraintBuffer() { mBrokenConstraints.clear(); }
++
++ /////////////////////////////////////////////////////////////
++
++ void collideStep(PxBaseTask* continuation);
++ void advanceStep(PxBaseTask* continuation);
++
++ // subroutines of collideStep/solveStep:
++ void kinematicsSetup(PxBaseTask* continuation);
++ void stepSetupSolve(PxBaseTask* continuation);
++
++ void processNarrowPhaseTouchEvents(PxBaseTask* continuation);
++ void setEdgesConnected(PxBaseTask* continuation);
++ void processNarrowPhaseLostTouchEvents(PxBaseTask* continuation);
++ void processNarrowPhaseLostTouchEventsIslands(PxBaseTask* continuation);
++ void processLostTouchPairs();
++ void integrateKinematicPose();
++ void updateKinematicCached(PxBaseTask* continuation);
++
++ void beforeSolver(PxBaseTask* continuation);
++ void checkForceThresholdContactEvents(PxU32 ccdPass);
++ private:
++ void putObjectsToSleep();
++ void wakeObjectsUp();
++
++ void collectPostSolverVelocitiesBeforeCCD();
++
++ void clearSleepWakeBodies();
++ PX_INLINE void cleanUpSleepBodies();
++ PX_INLINE void cleanUpWokenBodies();
++ PX_INLINE void cleanUpSleepOrWokenBodies(PxCoalescedHashSet<BodyCore*>& bodyList, PxU32 removeFlag, bool& validMarker);
++
++ private:
++
++ // Material manager
++ PX_ALIGN(16, PxsMaterialManager mMaterialManager);
++
++ BroadphaseManager mBroadphaseManager;
++ PxU64 mContextId;
++
++ PxArray<BodyCore*> mActiveBodies; // Sorted: kinematic before dynamic
++ PxU32 mActiveKinematicBodyCount; // Number of active kinematics. This is also the index in mActiveBodies where the active dynamic bodies start.
++ PxU32 mActiveDynamicBodyCount; // Number of active dynamics. This is also the index in mActiveBodies where the active soft bodies start.
++ PxArray<BodyCore*> mActiveCompoundBodies;
++
++ BodyCore** mActiveKinematicsCopy;
++ PxU32 mActiveKinematicsCopyCapacity;
++
++ // PT: this array used for:
++ // - debug visualization
++ // - processing trigger interactions
++ // - updating dirty interactions
++ PxArray<ElementSimInteraction*> mInteractions[InteractionType::eTRACKED_IN_SCENE_COUNT];
++ PxU32 mActiveInteractionCount[InteractionType::eTRACKED_IN_SCENE_COUNT]; // Interactions with id < activeInteractionCount are active
++
++ template <typename T, PxU32 size>
++ struct Block
++ {
++ PxU8 mem[sizeof(T)*size];
++ Block() {} // get around VS warning C4345, otherwise useless
++ };
++
++ typedef Block<void*, 8> PointerBlock8;
++ typedef Block<void*, 16> PointerBlock16;
++ typedef Block<void*, 32> PointerBlock32;
++
++ PxPool<PointerBlock8> mPointerBlock8Pool;
++ PxPool<PointerBlock16> mPointerBlock16Pool;
++ PxPool<PointerBlock32> mPointerBlock32Pool;
++
++ PxsContext* mLLContext;
++
++ Bp::AABBManagerBase* mAABBManager;
++ PxsCCDContext* mCCDContext;
++ PxI32 mNumFastMovingShapes;
++ PxU32 mCCDPass;
++
++ IG::SimpleIslandManager* mSimpleIslandManager;
++
++ Dy::Context* mDynamicsContext;
++
++ PxsMemoryManager* mMemoryManager;
++
++ #if PX_SUPPORT_GPU_PHYSX
++ PxsKernelWranglerManager* mGpuWranglerManagers;
++ PxsHeapMemoryAllocatorManager* mHeapMemoryAllocationManager;
++ #endif
++
++ PxsSimulationController* mSimulationController;
++
++ PxsSimulationControllerCallback* mSimulationControllerCallback;
++
++ PxSceneLimits mLimits;
++
++ PxVec3 mGravity; //!< Gravity vector
++
++ PxArray<PxContactPairHeader>
++ mQueuedContactPairHeaders;
++ //time:
++ //constants set with setTiming():
++ PxReal mDt; //delta time for current step.
++ PxReal mOneOverDt; //inverse of dt.
++ //stepping / counters:
++ PxU32 mTimeStamp; //Counts number of steps.
++ PxU32 mReportShapePairTimeStamp; //Timestamp for refreshing the shape pair report structure. Updated before delayed shape/actor deletion and before CCD passes.
++ //containers:
++ // Those ones contain shape ptrs from Actor, i.e. compound level, not subparts
++
++ PxCoalescedHashSet<ConstraintCore*> mConstraints;
++
++ Bp::BoundsArray* mBoundsArray;
++ Cm::PinnableArray<PxReal>* mContactDistance;
++ bool mHasContactDistanceChanged;
++ SqBoundsManager* mSqBoundsManager;
++
++ PxArray<BodySim*> mCcdBodies;
++ PxArray<PxTriggerPair> mTriggerBufferAPI;
++ PxArray<TriggerPairExtraData>* mTriggerBufferExtraData;
++
++ PxCoalescedHashSet<ArticulationCore*> mArticulations;
++ PxCoalescedHashSet<ArticulationSim*> mDirtyArticulationSims;
++
++ PxArray<ConstraintCore*> mBrokenConstraints;
++ PxCoalescedHashSet<ConstraintSim*> mActiveBreakableConstraints;
++
++ // pools for joint buffers
++ // The pools below currently cover all the internal cases
++ typedef Block<PxU8, 128> MemBlock128;
++ typedef Block<PxU8, 256> MemBlock256;
++ typedef Block<PxU8, 384> MemBlock384;
++ typedef Block<PxU8, 512> MemBlock512;
++
++ PxPool2<MemBlock128, 8192> mMemBlock128Pool;
++ PxPool2<MemBlock256, 8192> mMemBlock256Pool;
++ PxPool2<MemBlock384, 8192> mMemBlock384Pool;
++ PxPool2<MemBlock512, 8192> mMemBlock512Pool;
++
++ // broad phase data:
++ NPhaseCore* mNPhaseCore;
++
++ // Collision filtering
++ void* mFilterShaderData;
++ PxU32 mFilterShaderDataSize;
++ PxU32 mFilterShaderDataCapacity;
++ PxSimulationFilterShader mFilterShader;
++ PxSimulationFilterCallback* mFilterCallback;
++
++ const PxPairFilteringMode::Enum mKineKineFilteringMode;
++ const PxPairFilteringMode::Enum mStaticKineFilteringMode;
++
++ PxCoalescedHashSet<BodyCore*> mSleepBodies;
++ PxCoalescedHashSet<BodyCore*> mWokeBodies;
++
++ bool mWokeBodyListValid;
++ bool mSleepBodyListValid;
++ const bool mEnableStabilization;
++
++ PxArray<PxActor*> mActiveActors;
++ PxArray<PxActor*> mFrozenActors;
++
++ PxArray<const PxRigidBody*> mClientPosePreviewBodies; // buffer for bodies that requested early report of the integrated pose (eENABLE_POSE_INTEGRATION_PREVIEW).
++ // This buffer gets exposed to users. Is officially accessible from PxSimulationEventCallback::onAdvance()
++ // until the next simulate()/advance().
++ PxArray<PxTransform> mClientPosePreviewBuffer; // buffer of newly integrated poses for the bodies that requested a preview. This buffer gets exposed
++ // to users.
++
++ PxSimulationEventCallback* mSimulationEventCallback;
++
++ SimStats* mStats;
++ PxU32 mInternalFlags; // PT: combination of ::SceneInternalFlag, looks like only 2 bits are needed
++ PxSceneFlags mPublicFlags; // Copy of PxSceneDesc::flags, of type PxSceneFlag
++
++ // PT: TODO: unify names, "tracker" or "pool"?
++ ObjectIDTracker* mConstraintIDTracker; // PT: provides Sc::ContraintSim::mLowLevelConstraint::index
++ ObjectIDTracker* mActorIDTracker; // PT: provides Sc::ActorSim::mId
++ ObjectIDTracker* mElementIDPool; // PT: provides Sc::ElementSim::mElementID
++
++ StaticCore mAnchorCore;
++ StaticSim* mStaticAnchor;
++
++ Cm::PreallocatingPool<ShapeSim>* mShapeSimPool;
++ Cm::PreallocatingPool<StaticSim>* mStaticSimPool;
++ Cm::PreallocatingPool<BodySim>* mBodySimPool;
++ PxPool2<ConstraintSim, 4096> mConstraintSimPool;
++ PxPool2<ArticulationJointSim, 4096> mArticulationJointSimPool;
++
++ PxHashMap<PxPair<const ActorSim*, const ActorSim*>, ConstraintCore*> mConstraintMap;
++
++ PxPool2<ConstraintInteraction, 4096> mConstraintInteractionPool;
++
++ PxPool<SimStateData>* mSimStateDataPool;
++
++ BatchRemoveState* mBatchRemoveState;
++
++ PxArray<SimpleBodyPair> mLostTouchPairs;
++ PxBitMap mLostTouchPairsDeletedBodyIDs; // Need to know which bodies have been deleted when processing the lost touch pair list.
++ // Can't use the existing rigid object ID tracker class since this map needs to be cleared at
++ // another point in time.
++ PxBitMap mVelocityModifyMap;
++
++ PxArray<PxvContactManagerTouchEvent> mTouchFoundEvents;
++ PxArray<PxvContactManagerTouchEvent> mTouchLostEvents;
++
++ PxBitMap mDirtyShapeSimMap;
++
++ PxU32 mDominanceBitMatrix[PX_MAX_DOMINANCE_GROUP];
++
++ bool mVisualizationParameterChanged;
++
++ PxU32 mMaxNbArticulationLinks;
++
++ // statics:
++ PxU32 mNbRigidStatics;
++ PxU32 mNbRigidDynamics;
++ PxU32 mNbRigidKinematic;
++ PxU32 mNbGeometries[PxGeometryType::eGEOMETRY_COUNT];
++
++ //IG::Node::eTYPE_COUNT
++ PxU32 mNumDeactivatingNodes[IG::Node::eTYPE_COUNT];
++
++ // task decomposition
++ void setupBroadPhaseFirstAndSecondPassTasks(PxBaseTask* continuation);
++ void broadPhase(PxBaseTask* continuation);
++ void broadPhaseFirstPass(PxBaseTask* continuation);
++ void broadPhaseSecondPass(PxBaseTask* continuation);
++ void updateBroadPhase(PxBaseTask* continuation);
++ void preIntegrate(PxBaseTask* continuation);
++ void postBroadPhase(PxBaseTask* continuation);
++ void postBroadPhaseContinuation(PxBaseTask* continuation);
++ void preRigidBodyNarrowPhase(PxBaseTask* continuation);
++ void postBroadPhaseStage2(PxBaseTask* continuation);
++ void postBroadPhaseStage3(PxBaseTask* continuation);
++ void updateBoundsAndShapes(PxBaseTask* continuation);
++ void rigidBodyNarrowPhase(PxBaseTask* continuation);
++ void unblockNarrowPhase(PxBaseTask* continuation);
++ void islandGen(PxBaseTask* continuation);
++ void postIslandGen(PxBaseTask* continuation);
++ void solver(PxBaseTask* continuation);
++ void updateBodies(PxBaseTask* continuation);
++ void updateShapes(PxBaseTask* continuation);
++ void updateSimulationController(PxBaseTask* continuation);
++ void updateDynamics(PxBaseTask* continuation);
++ void updateDynamicsPostPartitioning(PxBaseTask* continuation);
++ void processLostContacts(PxBaseTask*);
++ void processLostContacts2(PxBaseTask*);
++ void processLostContacts3(PxBaseTask*);
++ void destroyManagers(PxBaseTask*);
++ void lostTouchReports(PxBaseTask*);
++ void unregisterInteractions(PxBaseTask*);
++ void postThirdPassIslandGen(PxBaseTask*);
++ void postSolver(PxBaseTask* continuation);
++ void afterIntegration(PxBaseTask* continuation); // performs sleep check, for instance
++ void postCCDPass(PxBaseTask* continuation);
++ void ccdBroadPhaseAABB(PxBaseTask* continuation);
++ void ccdBroadPhase(PxBaseTask* continuation);
++ void updateCCDMultiPass(PxBaseTask* continuation);
++ void updateCCDSinglePass(PxBaseTask* continuation);
++ void updateCCDSinglePassStage2(PxBaseTask* continuation);
++ void updateCCDSinglePassStage3(PxBaseTask* continuation);
++ void finalizationPhase(PxBaseTask* continuation);
++
++ void postNarrowPhase(PxBaseTask* continuation);
++
++ void addShapes(NpShape*const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& sim, PxBounds3* outBounds);
++ void removeShapes(RigidSim& , PxInlineArray<ShapeSim*, 64>& , PxInlineArray<const ShapeCore*, 64>&, bool wakeOnLostTouch);
++
++ private:
++ void addShapes(NpShape*const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& sim, ShapeSim*& prefetchedShapeSim, PxBounds3* outBounds);
++ void updateContactDistances(PxBaseTask* continuation);
++ void updateDirtyShapes(PxBaseTask* continuation);
++
++ Cm::DelegateTask<Scene, &Scene::secondPassNarrowPhase> mSecondPassNarrowPhase;
++ Cm::DelegateTask<Scene, &Scene::postNarrowPhase> mPostNarrowPhase;
++ Cm::DelegateTask<Scene, &Scene::finalizationPhase> mFinalizationPhase;
++ Cm::DelegateTask<Scene, &Scene::updateCCDMultiPass> mUpdateCCDMultiPass;
++
++ //multi-pass ccd stuff
++ PxArray<Cm::DelegateTask<Scene, &Scene::updateCCDSinglePass> > mUpdateCCDSinglePass;
++ PxArray<Cm::DelegateTask<Scene, &Scene::updateCCDSinglePassStage2> > mUpdateCCDSinglePass2;
++ PxArray<Cm::DelegateTask<Scene, &Scene::updateCCDSinglePassStage3> > mUpdateCCDSinglePass3;
++ PxArray<Cm::DelegateTask<Scene, &Scene::ccdBroadPhaseAABB> > mCCDBroadPhaseAABB;
++ PxArray<Cm::DelegateTask<Scene, &Scene::ccdBroadPhase> > mCCDBroadPhase;
++ PxArray<Cm::DelegateTask<Scene, &Scene::postCCDPass> > mPostCCDPass;
++
++ Cm::DelegateTask<Scene, &Scene::afterIntegration> mAfterIntegration;
++ Cm::DelegateTask<Scene, &Scene::postSolver> mPostSolver;
++ Cm::DelegateTask<Scene, &Scene::solver> mSolver;
++ Cm::DelegateTask<Scene, &Scene::updateBodies> mUpdateBodies;
++ Cm::DelegateTask<Scene, &Scene::updateShapes> mUpdateShapes;
++ Cm::DelegateTask<Scene, &Scene::updateSimulationController> mUpdateSimulationController;
++ Cm::DelegateTask<Scene, &Scene::updateDynamics> mUpdateDynamics;
++ Cm::DelegateTask<Scene, &Scene::updateDynamicsPostPartitioning> mUpdateDynamicsPostPartitioning;
++ Cm::DelegateTask<Scene, &Scene::processLostContacts> mProcessLostContactsTask;
++ Cm::DelegateTask<Scene, &Scene::processLostContacts2> mProcessLostContactsTask2;
++ Cm::DelegateTask<Scene, &Scene::processLostContacts3> mProcessLostContactsTask3;
++ Cm::DelegateTask<Scene, &Scene::destroyManagers> mDestroyManagersTask;
++ Cm::DelegateTask<Scene, &Scene::lostTouchReports> mLostTouchReportsTask;
++ Cm::DelegateTask<Scene, &Scene::unregisterInteractions> mUnregisterInteractionsTask;
++ Cm::DelegateTask<Scene,
++ &Scene::processNarrowPhaseLostTouchEventsIslands> mProcessNarrowPhaseLostTouchTasks;
++ Cm::DelegateTask<Scene,
++ &Scene::processNarrowPhaseLostTouchEvents> mProcessNPLostTouchEvents;
++ Cm::DelegateTask<Scene, &Scene::postThirdPassIslandGen> mPostThirdPassIslandGenTask;
++ #if !USE_SPLIT_SECOND_PASS_ISLAND_GEN
++ Cm::DelegateTask<Scene, &Scene::postIslandGen> mPostIslandGen;
++ #endif
++ Cm::DelegateTask<Scene, &Scene::islandGen> mIslandGen;
++ Cm::DelegateTask<Scene, &Scene::preRigidBodyNarrowPhase> mPreRigidBodyNarrowPhase;
++ Cm::DelegateTask<Scene, &Scene::setEdgesConnected> mSetEdgesConnectedTask;
++ Cm::DelegateFanoutTask<Scene, &Scene::updateBoundsAndShapes> mUpdateBoundAndShapeTask;
++ Cm::DelegateTask<Scene, &Scene::rigidBodyNarrowPhase> mRigidBodyNarrowPhase;
++ Cm::DelegateTask<Scene, &Scene::unblockNarrowPhase> mRigidBodyNPhaseUnlock;
++ Cm::DelegateTask<Scene, &Scene::postBroadPhase> mPostBroadPhase;
++ Cm::DelegateTask<Scene, &Scene::postBroadPhaseContinuation> mPostBroadPhaseCont;
++ Cm::DelegateTask<Scene, &Scene::postBroadPhaseStage2> mPostBroadPhase2;
++ Cm::DelegateFanoutTask<Scene, &Scene::postBroadPhaseStage3> mPostBroadPhase3;
++ Cm::DelegateTask<Scene, &Scene::preallocateContactManagers> mPreallocateContactManagers;
++ Cm::DelegateTask<Scene, &Scene::islandInsertion> mIslandInsertion;
++ Cm::DelegateTask<Scene, &Scene::registerContactManagers> mRegisterContactManagers;
++ Cm::DelegateTask<Scene, &Scene::registerInteractions> mRegisterInteractions;
++ Cm::DelegateTask<Scene, &Scene::registerSceneInteractions> mRegisterSceneInteractions;
++ Cm::DelegateTask<Scene, &Scene::broadPhase> mBroadPhase;
++ Cm::DelegateTask<Scene, &Scene::advanceStep> mAdvanceStep;
++ Cm::DelegateTask<Scene, &Scene::collideStep> mCollideStep;
++ Cm::DelegateTask<Scene, &Scene::broadPhaseFirstPass> mBpFirstPass;
++ Cm::DelegateTask<Scene, &Scene::broadPhaseSecondPass> mBpSecondPass;
++ Cm::DelegateTask<Scene, &Scene::updateBroadPhase> mBpUpdate;
++ Cm::DelegateTask<Scene, &Scene::preIntegrate> mPreIntegrate;
++
++ Cm::FlushPool mTaskPool;
++ PxTaskManager* mTaskManager;
++ PxCudaContextManager* mCudaContextManager;
++ PxLightCpuTask* mBodyAccelerationTask;
++
++ bool mContactReportsNeedPostSolverVelocity;
++ bool mUseGpuDynamics;
++ bool mUseGpuBp;
++ bool mCCDBp;
++
++ SimulationStage::Enum mSimulationStage;
++
++ PxCoalescedHashSet<const BodySim*> mPosePreviewBodies; // list of bodies that requested early report of the integrated pose (eENABLE_POSE_INTEGRATION_PREVIEW).
++
++ PxArray<PxsContactManager*> mPreallocatedContactManagers;
++ PxArray<ShapeInteraction*> mPreallocatedShapeInteractions;
++ PxArray<ElementInteractionMarker*> mPreallocatedInteractionMarkers;
++
++ // PT: class members that should ideally just be local parameters passed from task to task
++ OverlapFilterTask* mOverlapFilterTaskHead; // PT: tmp data passed from finishBroadPhase to preallocateContactManagers
++ PxArray<FilterInfo> mFilterInfo; // PT: tmp data passed from finishBroadPhase to preallocateContactManagers
++ OnOverlapCreatedTask* mOverlapCreatedTaskHead;
++ IslandInsertionTask* mIslandInsertionTaskHead;
++ PxArray<IG::EdgeIndex> mPreallocatedHandles;
++ DelayedGPUTypes mGPUTypes; // PT: GPU types found in last part of Sc::Scene::islandInsertion(), delayed for later processing
++ //~class members that should ideally just be local parameters passed from task to task
++
++ PxBitMap mSpeculativeCCDRigidBodyBitMap;
++ PxBitMap mSpeculativeCDDArticulationBitMap;
++
++ bool mIsCollisionPhaseActive;
++ // Set to true as long as collision phase is active (used as an indicator that it is OK to read object pose,
++ // velocity etc. compared to the solver phase where these properties might get written to).
++ bool mIsDirectGPUAPIInitialized;
++
++
++ public:
++ // For OmniPVD. To notify NpScene that actor's sleeping state has changed.
++ typedef void(*SleepingStateChangedCallback)(PxRigidDynamic&, bool);
++ SleepingStateChangedCallback mOnSleepingStateChanged;
++
++ // PT: moved all the GPU-related code & data here in an attempt to clearly separate the CPU/GPU bits
++ #if PX_SUPPORT_GPU_PHYSX
++ public:
++ void gpu_addToActiveList(ActorSim& actorSim, ActorCore* appendedActorCore);
++ void gpu_removeFromActiveList(ActorSim& actorSim, PxU32 removedActiveIndex);
++ void gpu_clearSleepWakeBodies();
++ void gpu_buildActiveActors();
++ void gpu_buildActiveAndFrozenActors();
++ void gpu_setSimulationEventCallback(PxSimulationEventCallback* callback);
++ PxU32 gpu_cleanUpSleepAndWokenBodies();
++ void gpu_fireOnSleepCallback(PxActor** actors);
++ void gpu_fireOnWakeCallback(PxActor** actors);
++ void gpu_updateBounds();
++ void gpu_releasePools();
++ void gpu_release();
++
++ void addDeformableSurface(DeformableSurfaceCore&);
++ void removeDeformableSurface(DeformableSurfaceCore&);
++ void addDeformableVolume(DeformableVolumeCore&);
++ void removeDeformableVolume(DeformableVolumeCore&);
++ void addParticleSystem(ParticleSystemCore&);
++ void removeParticleSystem(ParticleSystemCore&);
++
++ PX_FORCE_INLINE PxU32 getNbDeformableSurfaces() const { return mDeformableSurfaces.size(); }
++ PX_FORCE_INLINE DeformableSurfaceCore* const* getDeformableSurfaces() { return mDeformableSurfaces.getEntries(); }
++
++ PX_FORCE_INLINE PxU32 getNbDeformableVolumes() const { return mDeformableVolumes.size(); }
++ PX_FORCE_INLINE DeformableVolumeCore* const* getDeformableVolumes() { return mDeformableVolumes.getEntries(); }
++
++ PX_FORCE_INLINE PxU32 getNbParticleSystems() const { return mParticleSystems.size(); }
++ PX_FORCE_INLINE ParticleSystemCore* const* getParticleSystems() { return mParticleSystems.getEntries(); }
++
++ // PT: redundant?
++ // Get the active deformable surface actors
++ PX_FORCE_INLINE DeformableSurfaceCore*const* getActiveDeformableSurfacesArray() const { return mActiveDeformableSurfaces.begin(); }
++ PX_FORCE_INLINE PxU32 getNumActiveDeformableSurfaces() const { return mActiveDeformableSurfaces.size(); }
++
++ // PT: redundant?
++ // Get the active deformable surface actors
++ PX_FORCE_INLINE DeformableVolumeCore*const* getActiveDeformableVolumesArray() const { return mActiveDeformableVolumes.begin(); }
++ PX_FORCE_INLINE PxU32 getNumActiveDeformableVolumes() const { return mActiveDeformableVolumes.size(); }
++
++ PX_FORCE_INLINE const PxsDeformableSurfaceMaterialManager& getDeformableSurfaceMaterialManager() const { return mDeformableSurfaceMaterialManager; }
++ PX_FORCE_INLINE PxsDeformableSurfaceMaterialManager& getDeformableSurfaceMaterialManager() { return mDeformableSurfaceMaterialManager; }
++
++ PX_FORCE_INLINE const PxsDeformableVolumeMaterialManager& getDeformableVolumeMaterialManager() const { return mDeformableVolumeMaterialManager; }
++ PX_FORCE_INLINE PxsDeformableVolumeMaterialManager& getDeformableVolumeMaterialManager() { return mDeformableVolumeMaterialManager; }
++
++ PX_FORCE_INLINE const PxsPBDMaterialManager& getPBDMaterialManager() const { return mPBDMaterialManager; }
++ PX_FORCE_INLINE PxsPBDMaterialManager& getPBDMaterialManager() { return mPBDMaterialManager; }
++
++ Dy::DeformableSurface* createLLDeformableSurface(DeformableSurfaceSim* sim);
++ void destroyLLDeformableSurface(Dy::DeformableSurface& femCloth);
++
++ Dy::DeformableVolume* createLLDeformableVolume(DeformableVolumeSim* sim);
++ void destroyLLDeformableVolume(Dy::DeformableVolume& deformableVolume);
++
++ Dy::ParticleSystem* createLLParticleSystem(ParticleSystemSim* sim);
++ void destroyLLParticleSystem(Dy::ParticleSystem& softBody);
++
++ void cleanUpSleepDeformableVolumes();
++ void cleanUpWokenDeformableVolumes();
++ void cleanUpSleepOrWokenDeformableVolumes(PxCoalescedHashSet<DeformableVolumeCore*>& bodyList, PxU32 removeFlag, bool& validMarker);
++
++ void addDeformableSurfaceSimControl(DeformableSurfaceCore& core);
++ void removeDeformableSurfaceSimControl(DeformableSurfaceCore& core);
++ void addDeformableVolumeSimControl(DeformableVolumeCore& core);
++ void removeDeformableVolumeSimControl(DeformableVolumeCore& core);
++ void addParticleSystemSimControl(ParticleSystemCore& core);
++ void removeParticleSystemSimControl(ParticleSystemCore& core);
++
++ PxU32 addRigidAttachment(BodyCore* core, DeformableVolumeSim& sim, PxU32 vertId, const PxVec3& actorSpacePose, bool doConversion);
++ void removeRigidAttachment(BodyCore* core, DeformableVolumeSim& sim, PxU32 handle);
++
++ void addTetRigidFilter(BodyCore* core, DeformableVolumeSim& sim, PxU32 tetIdx);
++ void removeTetRigidFilter(BodyCore* core, DeformableVolumeSim& sim, PxU32 tetIdx);
++
++ PxU32 addTetRigidAttachment(BodyCore* core, DeformableVolumeSim& sim, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, bool doConversion);
++
++ void addSoftBodyFilter(DeformableVolumeCore& core, PxU32 tetIdx0, DeformableVolumeSim& sim, PxU32 tetIdx1);
++ void removeSoftBodyFilter(DeformableVolumeCore& core, PxU32 tetIdx0, DeformableVolumeSim& sim, PxU32 tetIdx1);
++ void addSoftBodyFilters(DeformableVolumeCore& core, DeformableVolumeSim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize);
++ void removeSoftBodyFilters(DeformableVolumeCore& core, DeformableVolumeSim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize);
++
++ PxU32 addSoftBodyAttachment(DeformableVolumeCore& core, PxU32 tetIdx0, const PxVec4& triBarycentric0, DeformableVolumeSim& sim, PxU32 tetIdx1, const PxVec4& tetBarycentric1, bool doConversion);
++ void removeSoftBodyAttachment(DeformableVolumeCore& core, DeformableVolumeSim& sim, PxU32 handle);
++
++ void addClothFilter(DeformableSurfaceCore& core, PxU32 triIdx, Sc::DeformableVolumeSim& sim, PxU32 tetIdx);
++ void removeClothFilter(DeformableSurfaceCore& core, PxU32 triIdx, Sc::DeformableVolumeSim& sim, PxU32 tetIdx);
++
++ PxU32 addClothAttachment(DeformableSurfaceCore& core, PxU32 triIdx, const PxVec4& triBarycentric, DeformableVolumeSim& sim, PxU32 tetIdx, const PxVec4& tetBarycentric, bool doConversion);
++ void removeClothAttachment(DeformableSurfaceCore& core, DeformableVolumeSim& sim, PxU32 handle);
++
++ PxU32 addRigidAttachment(BodyCore* core, DeformableSurfaceSim& sim, PxU32 vertId, const PxVec3& actorSpacePose);
++ void removeRigidAttachment(BodyCore* core, DeformableSurfaceSim& sim, PxU32 handle);
++
++ void addClothFilter(DeformableSurfaceCore& core0, PxU32 triIdx0, Sc::DeformableSurfaceSim& sim1, PxU32 triIdx1);
++ void removeClothFilter(DeformableSurfaceCore& core, PxU32 triIdx0, DeformableSurfaceSim& sim1, PxU32 triIdx1);
++
++ PxU32 addTriClothAttachment(DeformableSurfaceCore& core0, PxU32 triIdx0, const PxVec4& barycentric0, Sc::DeformableSurfaceSim& sim1, PxU32 triIdx1, const PxVec4& barycentric1);
++ void removeTriClothAttachment(DeformableSurfaceCore& core, DeformableSurfaceSim& sim1, PxU32 handle);
++
++ void addTriRigidFilter(BodyCore* core, DeformableSurfaceSim& sim, PxU32 triIdx);
++ void removeTriRigidFilter(BodyCore* core, DeformableSurfaceSim& sim, PxU32 triIdx);
++
++ PxU32 addTriRigidAttachment(BodyCore* core, DeformableSurfaceSim& sim, PxU32 triIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose);
++ void removeTriRigidAttachment(BodyCore* core, DeformableSurfaceSim& sim, PxU32 handle);
++
++ PxActor** getActiveDeformableVolumeActors(PxU32& nbActorsOut);
++ void setActiveDeformableVolumeActors(PxActor** actors, PxU32 nbActors);
++
++ //PxActor** getActiveDeformableSurfaceActors(PxU32& nbActorsOut);
++ //void setActiveDeformableSurfaceActors(PxActor** actors, PxU32 nbActors);
++
++ #if USE_SPLIT_SECOND_PASS_ISLAND_GEN
++ PxU64 mPadding;
++ #endif
++ PX_ALIGN(16, PxsDeformableSurfaceMaterialManager mDeformableSurfaceMaterialManager);
++ PX_ALIGN(16, PxsDeformableVolumeMaterialManager mDeformableVolumeMaterialManager);
++ PX_ALIGN(16, PxsPBDMaterialManager mPBDMaterialManager);
++
++ PxArray<DeformableSurfaceCore*> mActiveDeformableSurfaces;
++ PxArray<DeformableVolumeCore*> mActiveDeformableVolumes;
++ PxArray<ParticleSystemCore*> mActiveParticleSystems;
++
++ PxCoalescedHashSet<DeformableSurfaceCore*> mDeformableSurfaces;
++ PxCoalescedHashSet<DeformableVolumeCore*> mDeformableVolumes;
++ PxCoalescedHashSet<ParticleSystemCore*> mParticleSystems;
++
++ PxCoalescedHashSet<DeformableVolumeCore*> mSleepDeformableVolumes;
++ PxCoalescedHashSet<DeformableVolumeCore*> mWokeDeformableVolumes;
++
++ PxArray<PxActor*> mActiveDeformableSurfaceActors;
++ PxArray<PxActor*> mActiveDeformableVolumeActors;
++
++ LLDeformableSurfacePool* mLLDeformableSurfacePool;
++ LLDeformableVolumePool* mLLDeformableVolumePool;
++ LLParticleSystemPool* mLLParticleSystemPool;
++
++ PxHashMap<PxPair<PxU32, PxU32>, DeformableRigidInteraction> mDeformableRigidInteractionMap;
++
++ bool mWokeDeformableVolumeListValid;
++ bool mSleepDeformableVolumeListValid;
++ #endif
++ };
++
++ bool activateInteraction(Interaction* interaction);
++ void activateInteractions(Sc::ActorSim& actorSim);
++ void deactivateInteractions(Sc::ActorSim& actorSim);
++
++ } // namespace Sc
++
++ }
++
++ #endif