364 lines
11 KiB
C
364 lines
11 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-2019 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_ISLAND_MANAGER_TYPES_H
|
||
|
#define PXS_ISLAND_MANAGER_TYPES_H
|
||
|
|
||
|
#include "CmPhysXCommon.h"
|
||
|
|
||
|
namespace physx
|
||
|
{
|
||
|
|
||
|
class PxsContactManager;
|
||
|
class PxsRigidBody;
|
||
|
namespace Dy
|
||
|
{
|
||
|
struct Constraint;
|
||
|
class Articulation;
|
||
|
}
|
||
|
|
||
|
typedef PxU32 NodeType;
|
||
|
typedef PxU32 EdgeType;
|
||
|
typedef PxU32 IslandType;
|
||
|
#define INVALID_NODE 0xffffffff
|
||
|
#define INVALID_EDGE 0xffffffff
|
||
|
#define INVALID_ISLAND 0xffffffff
|
||
|
|
||
|
namespace Dy
|
||
|
{
|
||
|
typedef size_t ArticulationLinkHandle;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
template <class T, T INVLD> class PxsIslandManagerHook
|
||
|
{
|
||
|
friend class PxsIslandManager;
|
||
|
T index;
|
||
|
|
||
|
public:
|
||
|
|
||
|
static const T INVALID = INVLD;
|
||
|
|
||
|
PX_FORCE_INLINE PxsIslandManagerHook(): index(INVLD) {}
|
||
|
PX_FORCE_INLINE PxsIslandManagerHook(const T id): index(id) {}
|
||
|
PX_FORCE_INLINE PxsIslandManagerHook(const PxsIslandManagerHook<T,INVLD>& src) : index(src.index) {}
|
||
|
PX_FORCE_INLINE ~PxsIslandManagerHook(){}
|
||
|
|
||
|
PX_FORCE_INLINE bool isManaged() const { return index!=INVLD; }
|
||
|
|
||
|
private:
|
||
|
};
|
||
|
|
||
|
typedef PxsIslandManagerHook<NodeType,INVALID_NODE> PxsIslandManagerNodeHook;
|
||
|
typedef PxsIslandManagerHook<EdgeType,INVALID_EDGE> PxsIslandManagerEdgeHook;
|
||
|
typedef PxsIslandManagerHook<IslandType,INVALID_ISLAND> PxsIslandManagerIslandHook;
|
||
|
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
\brief PxsIslandObjects contains arrays of all rigid bodies, articulations, contact managers, and constraints that
|
||
|
belong to all awake islands. The per array indices denoting the ownership per island are stored in PxsIslandIndices.
|
||
|
|
||
|
@see PxsIslandManager::getIslandObjects
|
||
|
*/
|
||
|
struct PxsIslandObjects
|
||
|
{
|
||
|
/**
|
||
|
\brief Array of all rigid bodies in all awake islands.
|
||
|
|
||
|
\note Each rigid body corresponds to the void* passed to PxsIslandManager::addBody. The PxsRigidBody ptr is computed
|
||
|
by adding the rigid body offset value (passed to PxsIslandManager::create) to the void* pointer
|
||
|
ie [(PxsRigidBody*)((PxU8*)owner + rigidBodyOffset)]
|
||
|
|
||
|
@see PxsIslandManager::addBody, PxsIslandManager::create
|
||
|
*/
|
||
|
PxsRigidBody*const* bodies;
|
||
|
|
||
|
/**
|
||
|
\brief Array of all articulation roots in all awake islands.
|
||
|
|
||
|
\note Each Articulation* corresponds to Dy::getArticulation(articLinkHandle) where
|
||
|
articLinkHandle is the handle passed to PxsIslandManager::setArticulationRootLinkHandle.
|
||
|
|
||
|
@see PxsIslandManager::setArticulationRootLinkHandle, Dy::getArticulation
|
||
|
*/
|
||
|
Dy::Articulation*const* articulations;
|
||
|
|
||
|
/**
|
||
|
\brief Array of all articulation roots in all awake islands.
|
||
|
|
||
|
\note Each void* corresponds to the void* passed to PxsIslandManager::setArticulationRootLinkHandle
|
||
|
|
||
|
@see PxsIslandManager::setArticulationRootLinkHandle
|
||
|
*/
|
||
|
void*const* articulationOwners;
|
||
|
|
||
|
/**
|
||
|
\brief Array of all contact managers in all awake islands.
|
||
|
|
||
|
@see PxsIslandManager::setEdgeRigidCM
|
||
|
*/
|
||
|
struct PxsIndexedContactManager* contactManagers;
|
||
|
|
||
|
/**
|
||
|
\brief Array of all constraints in all awake islands.
|
||
|
|
||
|
@see PxsIslandManager::setEdgeConstraint
|
||
|
*/
|
||
|
struct PxsIndexedConstraint* constraints;
|
||
|
|
||
|
|
||
|
PxsIslandObjects() : bodies(NULL), articulations(NULL), articulationOwners(NULL), contactManagers(NULL), constraints(NULL)
|
||
|
{
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
\brief An array of PxsIslandIndices describes the rigid bodies, articulations, contacts and constraints that
|
||
|
belong to each island.
|
||
|
|
||
|
\note Given an array of PxsIslandIndices, the rigid bodies of the ith island span the inclusive range:
|
||
|
(PxsIslandObjects::bodies[PxsIslandIndices[i]], PxsIslandObjects::bodies[PxsIslandIndices[i+1]-1])
|
||
|
|
||
|
\note Given an array of PxsIslandIndices, the constraints of the ith island span the inclusive range:
|
||
|
(PxsIslandObjects::constraints[PxsIslandIndices[i]], PxsIslandObjects::constraints[PxsIslandIndices[i+1]-1])
|
||
|
|
||
|
@see PxsIslandObjects::getIslandIndices, PxsIslandObjects::getIslandCount
|
||
|
*/
|
||
|
class PxsIslandIndices
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
PxsIslandIndices(){}
|
||
|
~PxsIslandIndices(){}
|
||
|
|
||
|
/**
|
||
|
\brief Return true if the corresponding island has a contact with a static rigid body.
|
||
|
*/
|
||
|
PX_FORCE_INLINE bool getHasStaticContact() const
|
||
|
{
|
||
|
return (1 & hasStaticContact) ? true : false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
\brief The starting index of island rigid bodies in the array PxsIslandObjects::bodies
|
||
|
*/
|
||
|
NodeType bodies;
|
||
|
|
||
|
/**
|
||
|
\brief The starting index of island articulations in the arrays PxsIslandObjects::articulations and PxsIslandObjects::articulationOwners
|
||
|
|
||
|
\note The total number of articulations is clamped at 32767 on any platform that uses 16-bit handles.
|
||
|
*/
|
||
|
NodeType articulations : 8*sizeof(NodeType)-1;
|
||
|
|
||
|
private:
|
||
|
|
||
|
NodeType hasStaticContact : 1;
|
||
|
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
\brief The starting index of island contact managers in the array PxsIslandObjects::contactManagers.
|
||
|
*/
|
||
|
EdgeType contactManagers;
|
||
|
|
||
|
/**
|
||
|
\brief The starting index of island constraints in the array PxsIslandObjects::constraints.
|
||
|
|
||
|
\note islandId is for internal use only and is used for tracking islands that need a second pass.
|
||
|
*/
|
||
|
union
|
||
|
{
|
||
|
EdgeType constraints;
|
||
|
IslandType islandId;
|
||
|
};
|
||
|
|
||
|
//private:
|
||
|
|
||
|
/**
|
||
|
\brief Internal use only.
|
||
|
*/
|
||
|
PX_FORCE_INLINE void setHasStaticContact(const bool b)
|
||
|
{
|
||
|
hasStaticContact = NodeType(b ? 1 : 0);
|
||
|
}
|
||
|
};
|
||
|
PX_COMPILE_TIME_ASSERT(0==(0x07 & sizeof(PxsIslandIndices)));
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
typedef Dy::ArticulationLinkHandle PxsNodeType;
|
||
|
|
||
|
|
||
|
/**
|
||
|
\brief Each contact manager or constraint references two separate bodies, where
|
||
|
a body can be a dynamic rigid body, a kinematic rigid body, an articulation or a static.
|
||
|
The struct PxsIndexedInteraction describes the bodies that make up the pair.
|
||
|
*/
|
||
|
struct PxsIndexedInteraction
|
||
|
{
|
||
|
/**
|
||
|
\brief An enumerated list of all possible body types.
|
||
|
A body type is stored for each body in the pair.
|
||
|
*/
|
||
|
enum Enum
|
||
|
{
|
||
|
eBODY = 0,
|
||
|
eKINEMATIC = 1,
|
||
|
eARTICULATION = 2,
|
||
|
eWORLD = 3
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief An index describing how to access body0
|
||
|
|
||
|
\note If body0 is a dynamic (eBODY) rigid body then solverBody0 is an index into PxsIslandObjects::bodies.
|
||
|
\note If body0 is a kinematic (eKINEMATIC) rigid body then solverBody0 is an index into PxsIslandManager::getActiveKinematics.
|
||
|
|
||
|
\note If body0 is a static (eWORLD) then solverBody0 is PX_MAX_U32 or PX_MAX_U64, depending on the platform being 32- or 64-bit.
|
||
|
|
||
|
\note If body0 is an articulation then the articulation is found directly from Dy::getArticulation(articulation0)
|
||
|
*/
|
||
|
union
|
||
|
{
|
||
|
PxsNodeType solverBody0;
|
||
|
Dy::ArticulationLinkHandle articulation0;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief An index describing how to access body1
|
||
|
|
||
|
\note If body1 is a dynamic (eBODY) rigid body then solverBody1 is an index into PxsIslandObjects::bodies.
|
||
|
\note If body1 is a kinematic (eKINEMATIC) rigid body then solverBody1 is an index into PxsIslandManager::getActiveKinematics.
|
||
|
|
||
|
\note If body1 is a static (eWORLD) then solverBody1 is PX_MAX_U32 or PX_MAX_U64, depending on the platform being 32- or 64-bit.
|
||
|
|
||
|
\note If body1 is an articulation then the articulation is found directly from Dy::getArticulation(articulation1)
|
||
|
*/
|
||
|
union
|
||
|
{
|
||
|
PxsNodeType solverBody1;
|
||
|
Dy::ArticulationLinkHandle articulation1;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief The type (eBODY, eKINEMATIC etc) of body0
|
||
|
*/
|
||
|
PxU8 indexType0;
|
||
|
|
||
|
/**
|
||
|
\brief The type (eBODY, eKINEMATIC etc) of body1
|
||
|
*/
|
||
|
PxU8 indexType1;
|
||
|
|
||
|
PxU8 pad[2];
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
@see PxsIslandObjects, PxsIndexedInteraction
|
||
|
*/
|
||
|
struct PxsIndexedContactManager : public PxsIndexedInteraction
|
||
|
{
|
||
|
/**
|
||
|
\brief The contact manager corresponds to the value set in PxsIslandManager::setEdgeRigidCM
|
||
|
*/
|
||
|
PxsContactManager* contactManager;
|
||
|
|
||
|
PxsIndexedContactManager(PxsContactManager* cm) : contactManager(cm) {}
|
||
|
};
|
||
|
#if !PX_X64
|
||
|
PX_COMPILE_TIME_ASSERT(0==(sizeof(PxsIndexedContactManager) & 0x0f));
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
@see PxsIslandObjects, PxsIndexedInteraction
|
||
|
*/
|
||
|
struct PxsIndexedConstraint : public PxsIndexedInteraction
|
||
|
{
|
||
|
/**
|
||
|
\brief The constraint corresponds to the value set in PxsIslandManager::setEdgeConstraint
|
||
|
*/
|
||
|
Dy::Constraint* constraint;
|
||
|
|
||
|
PxsIndexedConstraint(Dy::Constraint* c) : constraint(c) {}
|
||
|
};
|
||
|
#if !PX_P64_FAMILY
|
||
|
PX_COMPILE_TIME_ASSERT(0==(sizeof(PxsIndexedConstraint) & 0x0f));
|
||
|
#endif
|
||
|
|
||
|
//----------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
\brief Any sleeping contact pair that finds itself in an awake island after 1st pass island gen
|
||
|
must participate in 2nd pass narrowphase so that contacts can be generated.
|
||
|
|
||
|
\note Contact managers in sleeping pairs are NULL until PxsIslandManager::setWokenPairContactManagers is complete.
|
||
|
|
||
|
@see PxsIslandManager::getNarrowPhaseSecondPassContactManagers, PxsIslandManager::getNumNarrowPhaseSecondPassContactManagers,
|
||
|
PxsIslandManager::setWokenPairContactManagers
|
||
|
*/
|
||
|
struct PxsNarrowPhaseSecondPassContactManager
|
||
|
{
|
||
|
/**
|
||
|
\brief The contact manager that is to participate in 2nd pass narrowphase.
|
||
|
|
||
|
\note This pointer is NULL after 1st pass island gen and remains NULL until PxsIslandManager::setWokenPairContactManagers
|
||
|
completes.
|
||
|
*/
|
||
|
PxsContactManager* mCM;
|
||
|
|
||
|
/**
|
||
|
\brief The corresponding entry in PxsIslandObjects::contactManagers.
|
||
|
|
||
|
\note All sleeping pairs have a null contact manager during 1st pass island gen. After 1st pass island gen completes,
|
||
|
the bodies to be woken are externally processed. Waking up bodies generates contact managers and passes the pointer to the
|
||
|
corresponding edge. So that the contact manager can be efficiently passed to PxsIslandObjects we store mEdgeId and mSolverCMId.
|
||
|
The contact manager pointers are set in PxsIslandManager::setWokenPairContactManagers
|
||
|
*/
|
||
|
EdgeType mSolverCMId; //Keeps a track of which entries in the solver islands temporarily have a null contact manager
|
||
|
|
||
|
/**
|
||
|
\brief The internal id of the corresponding edge.
|
||
|
*/
|
||
|
EdgeType mEdgeId;
|
||
|
};
|
||
|
|
||
|
|
||
|
} //namespace physx
|
||
|
|
||
|
|
||
|
#endif //PXS_ISLAND_MANAGER_TYPES_H
|