Custom Geometry#

Introduction#

This section describes how to use PhysX’s Custom Geometry feature.

The purpose of the Custom Geometry feature is to allow the creation of application specific collision geometries (e.g. a voxel map) that can seamlessly interact with the PhysX’s built-in geometry types. Any custom geometry is represented by the PxCustomGeometry class in the PhysX SDK. The constructor of the class expects a reference to an object implementing the PxCustomGeometry::Callbacks virtual interface.

This is how an example of a custom geometry usage could look like:

gVoxelMap = gPhysics->createRigidStatic(PxTransform(PxIdentity));
gVoxelMapCallbacks = new VoxelMapCallbacks();
gVoxelMapGeometry = PxCustomGeometry(*gVoxelMapCallbacks);
PxRigidActorExt::createExclusiveShape(*gVoxelMap, gVoxelMapGeometry, *gDefaultMaterial);
gScene->addActor(*gVoxelMap);

Every custom geometry type needs to implement all or some functions of the callbacks interface in order to enable the functionality required for the application.

Note: Custom geometry only stores a reference to the callback object; multiple custom geometries can maintain a reference to the same callback object; managing a callback object’s lifetime is the user’s responsibility.

Custom Geometry Callbacks#

A custom callbacks class inherited from the PxCustomGeometry::Callbacks interface will need to implement 9 virtual functions, serving to provide following functionality:

Custom Type#

PhysX doesn’t use Custom Geometry’s Custom Type, but it may be useful for users to identify a custom geometry object if they have more than one type of custom geometry in their application. The function PxCustomGeometry::Callbacks::getCustomType() returns a custom type unique to each implementation. The custom type is set using the macros DECLARE_CUSTOM_GEOMETRY_TYPE and IMPLEMENT_CUSTOM_GEOMETRY_TYPE.

// VoxelMap.h

struct VoxelMapCallbacks : PxCustomGeometry::Callbacks
{
    DECLARE_CUSTOM_GEOMETRY_TYPE
    ...
};

// VoxelMap.cpp

#include "VoxelMap.h"

IMPLEMENT_CUSTOM_GEOMETRY_TYPE(VoxelMapCallbacks)

...

// Test if custom geometry is a voxel map
if (gCustomGeometry.getCustomType() != VoxelMapCallbacks::TYPE())
    return false;

Collision Detection#

To enable collision detection for a custom geometry, the following virtual functions need to be implemented:

PxBounds3 PxCustomGeometry::Callbacks::getLocalBounds(const PxGeometry& geometry) const;

PxCustomGeometry::Callbacks::getLocalBounds() is used to determine overlapping bounds in BroadPhase.

bool PxCustomGeometry::Callbacks::generateContacts(const PxGeometry& geom0, const PxGeometry& geom1,
        const PxTransform& pose0, const PxTransform& pose1,
        const PxReal contactDistance, const PxReal meshContactMargin, const PxReal toleranceLength,
        PxContactBuffer& contactBuffer) const;

PxCustomGeometry::Callbacks::generateContacts() is used for exact contact points computation in NarrowPhase.

bool PxCustomGeometry::Callbacks::usePersistentContactManifold(const PxGeometry& geometry,
        PxReal& breakingThreshold) const;

PxCustomGeometry::Callbacks::usePersistentContactManifold() should return true if the geometry has complex structure and may generate many (more than 32) contact points.

Note: Cutom Geometry is CPU-only yet, and thus can not interact with the GPU-only features like deformable bodies or particles.

Scene Queries#

These 4 functions will allow the geometry to participate in scene queries:

PxBounds3 PxCustomGeometry::Callbacks::getLocalBounds(const PxGeometry& geometry) const;

PxCustomGeometry::Callbacks::getLocalBounds() is used for preliminary testing.

PxU32 PxCustomGeometry::Callbacks::raycast(const PxVec3& origin, const PxVec3& unitDir,
        const PxGeometry& geom, const PxTransform& pose, PxReal maxDist, PxHitFlags hitFlags,
        PxU32 maxHits, PxGeomRaycastHit* rayHits, PxU32 stride,
        PxRaycastThreadContext* threadContext) const;

PxCustomGeometry::Callbacks::raycast() is used for raycast queries against the geometry.

bool PxCustomGeometry::Callbacks::overlap(const PxGeometry& geom0, const PxTransform& pose0,
        const PxGeometry& geom1, const PxTransform& pose1,
        PxOverlapThreadContext* threadContext) const;

PxCustomGeometry::Callbacks::overlap() is used for overlap queries against the geometry.

bool PxCustomGeometry::Callbacks::sweep(const PxVec3& unitDir, const PxReal maxDist,
        const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1,
        const PxTransform& pose1, PxGeomSweepHit& sweepHit, PxHitFlags hitFlags,
        const PxReal inflation, PxSweepThreadContext* threadContext) const;

PxCustomGeometry::Callbacks::sweep() is used for sweep queries against the geometry.

Debug Visualization#

Users can implement this function to have their custom geometry drawn in PhysX’s debug visualization.

void PxCustomGeometry::Callbacks::visualize(const PxGeometry& geometry, PxRenderOutput& out,
        const PxTransform& absPose, const PxBounds3& cullbox) const;

PxCustomGeometry::Callbacks::visualize() is used for debug visualization of the geometry.

Mass Properties Computation#

To enable automatic dynamic rigid body mass computation.

void PxCustomGeometry::Callbacks::computeMassProperties(const PxGeometry& geometry,
        PxMassProperties& massProperties) const;

PxCustomGeometry::Callbacks::computeMassProperties() for the geometry that can be used with dynamic rigid bodies.

Extensions#

PhysXExtensions module’s PxCustomGeometryExt API provides two pre-made custom geometry callbacks classes.

Pre-made callbacks classes#