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