Files
XCEngine/engine/third_party/physx/source/simulationcontroller/src/ScActorSim.h

224 lines
10 KiB
C++

// 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<ElementSim**>(mShapes.getPtrs());
}
PX_FORCE_INLINE ElementSim*const* getElements() const
{
return reinterpret_cast<ElementSim*const*>(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<Sc::Interaction*, Sc::ActorSim, PxU32, &Sc::ActorSim::reallocInteractions>
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