// 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. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef SC_ACTOR_SIM_H #define SC_ACTOR_SIM_H #include "foundation/PxUserAllocated.h" #include "CmPtrTable.h" #include "CmUtils.h" #include "PxActor.h" #include "ScInteractionFlags.h" #include "ScActorCore.h" #include "PxsSimpleIslandManager.h" #include "PxFiltering.h" namespace physx { class PxActor; namespace Sc { #define SC_NOT_IN_SCENE_INDEX 0xffffffff // the body is not in the scene yet #define SC_NOT_IN_ACTIVE_LIST_INDEX 0xfffffffe // the body is in the scene but not in the active list struct PxFilterObjectFlagEx : PxFilterObjectFlag { enum Enum { eRIGID_STATIC = eNEXT_FREE, eRIGID_DYNAMIC = eNEXT_FREE<<1, eNON_RIGID = eNEXT_FREE<<2, eDEFORMABLE_SURFACE = eNEXT_FREE<<3, eDEFORMABLE_VOLUME = eNEXT_FREE<<4, ePARTICLESYSTEM = eNEXT_FREE<<5, eLAST = ePARTICLESYSTEM }; }; static const PxReal ScInternalWakeCounterResetValue = 20.0f*0.02f; class Interaction; class ElementSim; class Scene; class ShapeManager : public PxUserAllocated { public: ShapeManager() {} ~ShapeManager() {} PX_FORCE_INLINE PxU32 getNbElements() const { return mShapes.getCount(); } PX_FORCE_INLINE ElementSim** getElements() { return reinterpret_cast(mShapes.getPtrs()); } PX_FORCE_INLINE ElementSim*const* getElements() const { return reinterpret_cast(mShapes.getPtrs()); } // void onElementAttach(ElementSim& element); void onElementDetach(ElementSim& element); Cm::PtrTable mShapes; }; class ActorSim : public ShapeManager { friend class Scene; // the scene is allowed to set the scene array index friend class Interaction; PX_NOCOPY(ActorSim) public: enum InternalFlags { //BF_DISABLE_GRAVITY = 1 << 0, // Don't apply the scene's gravity BF_HAS_STATIC_TOUCH = 1 << 1, // Set when a body is part of an island with static contacts. Needed to be able to recalculate adaptive force if this changes BF_KINEMATIC_MOVED = 1 << 2, // Set when the kinematic was moved BF_ON_DEATHROW = 1 << 3, // Set when the body is destroyed BF_IS_IN_SLEEP_LIST = 1 << 4, // Set when the body is added to the list of bodies which were put to sleep BF_IS_IN_WAKEUP_LIST = 1 << 5, // Set when the body is added to the list of bodies which were woken up BF_SLEEP_NOTIFY = 1 << 6, // A sleep notification should be sent for this body (and not a wakeup event, even if the body is part of the woken list as well) BF_WAKEUP_NOTIFY = 1 << 7, // A wake up notification should be sent for this body (and not a sleep event, even if the body is part of the sleep list as well) BF_HAS_CONSTRAINTS = 1 << 8, // Set if the body has one or more constraints BF_KINEMATIC_SETTLING = 1 << 9, // Set when the body was moved kinematically last frame BF_KINEMATIC_SETTLING_2 = 1 << 10, BF_KINEMATIC_MOVE_FLAGS = BF_KINEMATIC_MOVED | BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2, //Used to clear kinematic masks in 1 call BF_KINEMATIC_SURFACE_VELOCITY = 1 << 11, //Set when the application calls setKinematicVelocity. Actor remains awake until application calls clearKinematicVelocity. BF_IS_COMPOUND_RIGID = 1 << 12, // Set when the body is a compound actor, we dont want to set the sq bounds // PT: WARNING: flags stored on 16-bits now. }; ActorSim(Scene&, ActorCore&); virtual ~ActorSim(); // Get the scene the actor resides in PX_FORCE_INLINE Scene& getScene() const { return mScene; } // Get the number of interactions connected to the actor PX_FORCE_INLINE PxU32 getActorInteractionCount() const { return mInteractions.size(); } // Get an iterator to the interactions connected to the actor PX_FORCE_INLINE Interaction** getActorInteractions() const { return mInteractions.begin(); } // Get the type ID of the actor PX_FORCE_INLINE PxActorType::Enum getActorType() const { return mCore.getActorCoreType(); } // Returns true if the actor is a dynamic rigid body (including articulation links) PX_FORCE_INLINE PxU16 isDynamicRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eRIGID_DYNAMIC; } PX_FORCE_INLINE PxU16 isDeformableSurface() const { return mFilterFlags & PxFilterObjectFlagEx::eDEFORMABLE_SURFACE; } PX_FORCE_INLINE PxU16 isDeformableVolume() const { return mFilterFlags & PxFilterObjectFlagEx::eDEFORMABLE_VOLUME; } PX_FORCE_INLINE PxU16 isParticleSystem() const { return mFilterFlags & PxFilterObjectFlagEx::ePARTICLESYSTEM; } PX_FORCE_INLINE PxU16 isNonRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eNON_RIGID; } PX_FORCE_INLINE PxU16 isStaticRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eRIGID_STATIC; } virtual void postActorFlagChange(PxU32, PxU32) {} void setActorsInteractionsDirty(InteractionDirtyFlag::Enum flag, const ActorSim* other, PxU8 interactionFlag); PX_FORCE_INLINE ActorCore& getActorCore() const { return mCore; } PX_FORCE_INLINE bool isActive() const { return (mActiveListIndex < SC_NOT_IN_ACTIVE_LIST_INDEX); } PX_FORCE_INLINE PxU32 getActiveListIndex() const { return mActiveListIndex; } // if the body is active, the index is smaller than SC_NOT_IN_ACTIVE_LIST_INDEX PX_FORCE_INLINE void setActiveListIndex(PxU32 index) { mActiveListIndex = index; } PX_FORCE_INLINE PxU32 getActiveCompoundListIndex() const { return mActiveCompoundListIndex; } // if the body is active and is compound, the index is smaller than SC_NOT_IN_ACTIVE_LIST_INDEX PX_FORCE_INLINE void setActiveCompoundListIndex(PxU32 index) { mActiveCompoundListIndex = index; } PX_FORCE_INLINE PxNodeIndex getNodeIndex() const { return mNodeIndex; } PX_FORCE_INLINE PxU32 getActorID() const { return mId; } PX_FORCE_INLINE PxU16 getInternalFlag() const { return mInternalFlags; } PX_FORCE_INLINE PxU16 readInternalFlag(InternalFlags flag) const { return PxU16(mInternalFlags & flag); } PX_FORCE_INLINE void raiseInternalFlag(InternalFlags flag) { mInternalFlags |= flag; } PX_FORCE_INLINE void clearInternalFlag(InternalFlags flag) { mInternalFlags &= ~flag; } PX_FORCE_INLINE PxFilterObjectAttributes getFilterAttributes() const { return PxFilterObjectAttributes(mFilterFlags); } virtual PxActor* getPxActor() const = 0; //This can all be removed and functionality can be subsumed by the island system, removing the need for this //virtual call and any associated work virtual void registerCountedInteraction() {} virtual void unregisterCountedInteraction() {} virtual PxU32 getNumCountedInteractions() const { return 0; } virtual void internalWakeUp(PxReal wakeCounterValue = ScInternalWakeCounterResetValue) { PX_UNUSED(wakeCounterValue); } private: //These are called from interaction creation/destruction void registerInteractionInActor(Interaction* interaction); void unregisterInteractionFromActor(Interaction* interaction); void reallocInteractions(Sc::Interaction**& mem, PxU32& capacity, PxU32 size, PxU32 requiredMinCapacity); protected: // dsequeira: interaction arrays are a major cause of small allocations, so we don't want to delegate them to the heap allocator // it's not clear this inline array is really needed, we should take it out and see whether the cache perf is worse static const PxU32 INLINE_INTERACTION_CAPACITY = 4; Interaction* mInlineInteractionMem[INLINE_INTERACTION_CAPACITY]; Cm::OwnedArray mInteractions; Scene& mScene; ActorCore& mCore; // Sleeping PxU32 mActiveListIndex; // Used by Scene to track active bodies PxU32 mActiveCompoundListIndex; // Used by Scene to track active compound bodies // Island manager PxNodeIndex mNodeIndex; PxU32 mId; // PT: ID provided by Sc::Scene::mActorIDTracker PxU16 mInternalFlags; PxU16 mFilterFlags; // PT: PxFilterObjectAttributes. Capturing the type information in local flags here is redundant // but avoids reading the Core memory from the Sim object, and is also faster to test multiple types at once. }; } // namespace Sc } #endif