Revision control
++ // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
++ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
++ // SPDX-FileCopyrightText: Copyright (c) 2008-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
++ // SPDX-License-Identifier: Apache-2.0
++
++ #ifndef PX_BROAD_PHASE_H
++ #define PX_BROAD_PHASE_H
++
++ #include "PxPhysXConfig.h"
++ #include "foundation/PxBounds3.h"
++
++ #if !PX_DOXYGEN
++ namespace physx
++ {
++ #endif
++
++ class PxBaseTask;
++ class PxCudaContextManager;
++ class PxAllocatorCallback;
++
++ /**
++ \brief Broad phase algorithm used in the simulation
++
++ eSAP is a good generic choice with great performance when many objects are sleeping. Performance
++ can degrade significantly though, when all objects are moving, or when large numbers of objects
++ are added to or removed from the broad phase. This algorithm does not need world bounds to be
++ defined in order to work.
++
++ eMBP is an alternative broad phase algorithm that does not suffer from the same performance
++ issues as eSAP when all objects are moving or when inserting large numbers of objects. However
++ its generic performance when many objects are sleeping might be inferior to eSAP, and it requires
++ users to define world bounds in order to work.
++
++ eABP is a revisited implementation of MBP, which automatically manages broad-phase regions.
++ It offers the convenience of eSAP (no need to define world bounds or regions) and the performance
++ of eMBP when a lot of objects are moving. While eSAP can remain faster when most objects are
++ sleeping and eMBP can remain faster when it uses a large number of properly-defined regions,
++ eABP often gives the best performance on average and the best memory usage.
++
++ ePABP is a parallel implementation of ABP. It can often be the fastest (CPU) broadphase, but it
++ can use more memory than ABP.
++
++ eGPU is a GPU implementation of the incremental sweep and prune approach. Additionally, it uses a ABP-style
++ initial pair generation approach to avoid large spikes when inserting shapes. It not only has the advantage
++ of traditional SAP approch which is good for when many objects are sleeping, but due to being fully parallel,
++ it also is great when lots of shapes are moving or for runtime pair insertion and removal. It can become a
++ performance bottleneck if there are a very large number of shapes roughly projecting to the same values
++ on a given axis. If the scene has a very large number of shapes in an actor, e.g. a humanoid, it is recommended
++ to use an aggregate to represent multi-shape or multi-body actors to minimize stress placed on the broad phase.
++ */
++ struct PxBroadPhaseType
++ {
++ enum Enum
++ {
++ eSAP, //!< 3-axes sweep-and-prune
++ eMBP, //!< Multi box pruning
++ eABP, //!< Automatic box pruning
++ ePABP, //!< Parallel automatic box pruning
++ eGPU, //!< GPU broad phase
++ eLAST
++ };
++ };
++
++ /**
++ \brief "Region of interest" for the broad-phase.
++
++ This is currently only used for the PxBroadPhaseType::eMBP broad-phase, which requires zones or regions to be defined
++ when the simulation starts in order to work. Regions can overlap and be added or removed at runtime, but at least one
++ region needs to be defined when the scene is created.
++
++ If objects that do no overlap any region are inserted into the scene, they will not be added to the broad-phase and
++ thus collisions will be disabled for them. A PxBroadPhaseCallback out-of-bounds notification will be sent for each one
++ of those objects.
++
++ The total number of regions is limited by PxBroadPhaseCaps::mMaxNbRegions.
++
++ The number of regions has a direct impact on performance and memory usage, so it is recommended to experiment with
++ various settings to find the best combination for your game. A good default setup is to start with global bounds
++ around the whole world, and subdivide these bounds into 4*4 regions. The PxBroadPhaseExt::createRegionsFromWorldBounds
++ function can do that for you.
++
++ \see PxBroadPhaseCallback PxBroadPhaseExt.createRegionsFromWorldBounds
++ */
++ struct PxBroadPhaseRegion
++ {
++ PxBounds3 mBounds; //!< Region's bounds
++ void* mUserData; //!< Region's user-provided data
++ };
++
++ /**
++ \brief Information & stats structure for a region
++ */
++ struct PxBroadPhaseRegionInfo
++ {
++ PxBroadPhaseRegion mRegion; //!< User-provided region data
++ PxU32 mNbStaticObjects; //!< Number of static objects in the region
++ PxU32 mNbDynamicObjects; //!< Number of dynamic objects in the region
++ bool mActive; //!< True if region is currently used, i.e. it has not been removed
++ bool mOverlap; //!< True if region overlaps other regions (regions that are just touching are not considering overlapping)
++ };
++
++ /**
++ \brief Caps class for broad phase.
++ */
++ struct PxBroadPhaseCaps
++ {
++ PxU32 mMaxNbRegions; //!< Max number of regions supported by the broad-phase (0 = explicit regions not needed)
++ };
++
++ /**
++ \brief Descriptor for the GPU broad-phase.
++
++ This struct contains parameters that are only relevant for the GPU broad-phase.
++
++ \see PxBroadPhaseType::eGPU
++ */
++ struct PxGpuBroadPhaseDesc
++ {
++ PxGpuBroadPhaseDesc() :
++ gpuBroadPhaseNbBitsShiftX (4),
++ gpuBroadPhaseNbBitsShiftY (4),
++ gpuBroadPhaseNbBitsShiftZ (4),
++ gpuBroadPhaseNbBitsEnvIDX (0),
++ gpuBroadPhaseNbBitsEnvIDY (0),
++ gpuBroadPhaseNbBitsEnvIDZ (0)
++ {
++ }
++
++ // The GPU broadphase encodes bounds as integers, and then right-shifts the data by this amount of bits.
++ // This makes the bounds a bit larger, which avoids losing and recreating overlaps over and over when
++ // two objects are just touching. This effect is similar to what can be achieved with the contact distance
++ // parameter, and the amount by which the bounds are inflated depends on the distance from the bounds to
++ // the origin (as the bounds encoding does not use a regular float-to-integer conversion, but instead a
++ // reinterpretation of the float's bits). The default value in the GPU broadphase has always been 4 bits
++ // but it is safe to use 0 here for more accurate bounds.
++ PxU8 gpuBroadPhaseNbBitsShiftX; //!< number of bits used for "snap to grid" on the X axis
++ PxU8 gpuBroadPhaseNbBitsShiftY; //!< number of bits used for "snap to grid" on the Y axis
++ PxU8 gpuBroadPhaseNbBitsShiftZ; //!< number of bits used for "snap to grid" on the Z axis
++
++ // The bits lost by the previous shifts (gpuBroadPhaseNbBitsShiftXYZ) can be replaced with bits of the
++ // environment IDs. This only makes sense when these parameters are used (see PxActor::setEnvironmentID
++ // and PxAggregate::setEnvironmentID). In this case a number of bits from the environment IDs are stored
++ // in the MSBs of encoded bounds. This has the effect of virtually spreading the bounds over 3D space,
++ // which reduces the number of internal overlaps inside the broad-phase. This is mainly useful in RL
++ // scenarios with "co-located" environments, but it can also provide performance gains with regular grid
++ // configurations, that also generate a lot of internal overlaps on all coordinate axes.
++ //
++ // Beware: when using this feature, each object of each environment should be assigned a proper environment
++ // ID. Objects shared between all environments (i.e. objects whose environment ID is PX_INVALID_U32) will
++ // otherwise be internally assigned bounds that cover the entire 3D space, creating a lot of overlaps and
++ // potential performance issues. This is only a concern when gpuBroadPhaseNbBitsEnvIDX/Y/Z are non zero,
++ // shared objects are fine otherwise.
++ PxU8 gpuBroadPhaseNbBitsEnvIDX; //!< number of environment ID bits merged with the bounds on the X axis
++ PxU8 gpuBroadPhaseNbBitsEnvIDY; //!< number of environment ID bits merged with the bounds on the Y axis
++ PxU8 gpuBroadPhaseNbBitsEnvIDZ; //!< number of environment ID bits merged with the bounds on the Z axis
++
++ PX_INLINE bool isValid() const
++ {
++ // This is used on 32bit data so it makes no sense to shift more than 32 bits.
++ // It also makes no sense to shift all the bits of source data.
++ if( gpuBroadPhaseNbBitsShiftX > 31
++ || gpuBroadPhaseNbBitsShiftY > 31
++ || gpuBroadPhaseNbBitsShiftZ > 31)
++ return false;
++
++ if( gpuBroadPhaseNbBitsEnvIDX > 31
++ || gpuBroadPhaseNbBitsEnvIDY > 31
++ || gpuBroadPhaseNbBitsEnvIDZ > 31)
++ return false;
++
++ // We can only store bits from environment IDs in bits shifted away from the source data.
++ // So we need to drop (shift) at least as many bits of the source data as we need for env IDs.
++ if( gpuBroadPhaseNbBitsEnvIDX > gpuBroadPhaseNbBitsShiftX
++ || gpuBroadPhaseNbBitsEnvIDY > gpuBroadPhaseNbBitsShiftY
++ || gpuBroadPhaseNbBitsEnvIDZ > gpuBroadPhaseNbBitsShiftZ)
++ return false;
++ return true;
++ }
++ };
++
++ /**
++ \brief Broadphase descriptor.
++
++ This structure is used to create a standalone broadphase. It captures all the parameters needed to
++ initialize a broadphase.
++
++ For the GPU broadphase (PxBroadPhaseType::eGPU) it is necessary to provide a CUDA context manager.
++
++ The kinematic filtering flags are currently not supported by the GPU broadphase. They are used to
++ dismiss pairs that involve kinematic objects directly within the broadphase.
++
++ \see PxCreateBroadPhase
++ */
++ class PxBroadPhaseDesc
++ {
++ public:
++ PxBroadPhaseDesc(PxBroadPhaseType::Enum type = PxBroadPhaseType::eLAST) :
++ mType (type),
++ mContextID (0),
++ mContextManager (NULL),
++ mFoundLostPairsCapacity (256 * 1024),
++ mDiscardStaticVsKinematic (false),
++ mDiscardKinematicVsKinematic(false)
++ {}
++
++ PxBroadPhaseType::Enum mType; //!< Desired broadphase implementation
++ PxU64 mContextID; //!< Context ID for profiler. See PxProfilerCallback.
++
++ PxCudaContextManager* mContextManager; //!< (GPU) CUDA context manager, must be provided for PxBroadPhaseType::eGPU.
++ PxU32 mFoundLostPairsCapacity; //!< (GPU) Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP.
++
++ bool mDiscardStaticVsKinematic; //!< Static-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.
++ bool mDiscardKinematicVsKinematic; //!< kinematic-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.
++
++ PX_INLINE bool isValid() const
++ {
++ if(PxU32(mType)>=PxBroadPhaseType::eLAST)
++ return false;
++
++ if(mType==PxBroadPhaseType::eGPU && !mContextManager)
++ return false;
++
++ return true;
++ }
++ };
++
++ typedef PxU32 PxBpIndex; //!< Broadphase index. Indexes bounds, groups and distance arrays.
++ typedef PxU32 PxBpFilterGroup; //!< Broadphase filter group.
++ #define PX_INVALID_BP_FILTER_GROUP 0xffffffff //!< Invalid broadphase filter group
++
++ /**
++ \brief Retrieves the filter group for static objects.
++
++ Mark static objects with this group when adding them to the broadphase.
++ Overlaps between static objects will not be detected. All static objects
++ should have the same group.
++
++ \return Filter group for static objects.
++ \see PxBpFilterGroup
++ */
++ PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseStaticFilterGroup();
++
++ /**
++ \brief Retrieves a filter group for dynamic objects.
++
++ Mark dynamic objects with this group when adding them to the broadphase.
++ Each dynamic object must have an ID, and overlaps between dynamic objects that have
++ the same ID will not be detected. This is useful to dismiss overlaps between shapes
++ of the same (compound) actor directly within the broadphase.
++
++ \param id [in] ID/Index of dynamic object
++ \return Filter group for the object.
++ \see PxBpFilterGroup
++ */
++ PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseDynamicFilterGroup(PxU32 id);
++
++ /**
++ \brief Retrieves a filter group for kinematic objects.
++
++ Mark kinematic objects with this group when adding them to the broadphase.
++ Each kinematic object must have an ID, and overlaps between kinematic objects that have
++ the same ID will not be detected.
++
++ \param id [in] ID/Index of kinematic object
++ \return Filter group for the object.
++ \see PxBpFilterGroup
++ */
++ PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseKinematicFilterGroup(PxU32 id);
++
++ /**
++ \brief Broadphase data update structure.
++
++ This structure is used to update the low-level broadphase (PxBroadPhase). All added, updated and removed objects
++ must be batched and submitted at once to the broadphase.
++
++ Broadphase objects have bounds, a filtering group, and a distance. With the low-level broadphase the data must be
++ externally managed by the clients of the broadphase API, and passed to the update function.
++
++ The provided bounds are non-inflated "base" bounds that can be further extended by the broadphase using the passed
++ distance value. These can be contact offsets, or dynamically updated distance values for e.g. speculative contacts.
++ Either way they are optional and can be left to zero. The broadphase implementations efficiently combine the base
++ bounds with the per-object distance values at runtime.
++
++ The per-object filtering groups are used to discard some pairs directly within the broadphase, which is more
++ efficient than reporting the pairs and culling them in a second pass.
++
++ \see PxBpFilterGroup PxBpIndex PxBounds3 PxBroadPhase::update
++ */
++ class PxBroadPhaseUpdateData
++ {
++ public:
++
++ PxBroadPhaseUpdateData( const PxBpIndex* created, PxU32 nbCreated,
++ const PxBpIndex* updated, PxU32 nbUpdated,
++ const PxBpIndex* removed, PxU32 nbRemoved,
++ const PxBounds3* bounds, const PxBpFilterGroup* groups, const float* distances,
++ PxU32 capacity) :
++ mCreated (created), mNbCreated (nbCreated),
++ mUpdated (updated), mNbUpdated (nbUpdated),
++ mRemoved (removed), mNbRemoved (nbRemoved),
++ mBounds (bounds), mGroups (groups), mDistances (distances),
++ mCapacity (capacity)
++ {
++ }
++
++ PxBroadPhaseUpdateData(const PxBroadPhaseUpdateData& other) :
++ mCreated (other.mCreated), mNbCreated (other.mNbCreated),
++ mUpdated (other.mUpdated), mNbUpdated (other.mNbUpdated),
++ mRemoved (other.mRemoved), mNbRemoved (other.mNbRemoved),
++ mBounds (other.mBounds), mGroups (other.mGroups), mDistances (other.mDistances),
++ mCapacity (other.mCapacity)
++ {
++ }
++
++ PxBroadPhaseUpdateData& operator=(const PxBroadPhaseUpdateData& other);
++
++ const PxBpIndex* mCreated; //!< Indices of created objects.
++ const PxU32 mNbCreated; //!< Number of created objects.
++
++ const PxBpIndex* mUpdated; //!< Indices of updated objects.
++ const PxU32 mNbUpdated; //!< Number of updated objects.
++
++ const PxBpIndex* mRemoved; //!< Indices of removed objects.
++ const PxU32 mNbRemoved; //!< Number of removed objects.
++
++ const PxBounds3* mBounds; //!< (Persistent) array of bounds.
++ const PxBpFilterGroup* mGroups; //!< (Persistent) array of groups.
++ const float* mDistances; //!< (Persistent) array of distances.
++ const PxU32 mCapacity; //!< Capacity of bounds / groups / distance buffers.
++ };
++
++ /**
++ \brief Broadphase pair.
++
++ A pair of indices returned by the broadphase for found or lost pairs.
++
++ \see PxBroadPhaseResults
++ */
++ struct PxBroadPhasePair
++ {
++ PxBpIndex mID0; //!< Index of first object
++ PxBpIndex mID1; //!< Index of second object
++ };
++
++ /**
++ \brief Broadphase results.
++
++ Set of found and lost pairs after a broadphase update.
++
++ \see PxBroadPhasePair PxBroadPhase::fetchResults PxAABBManager::fetchResults
++ */
++ struct PxBroadPhaseResults
++ {
++ PxBroadPhaseResults() : mNbCreatedPairs(0), mCreatedPairs(NULL), mNbDeletedPairs(0), mDeletedPairs(NULL) {}
++
++ PxU32 mNbCreatedPairs; //!< Number of new/found/created pairs.
++ const PxBroadPhasePair* mCreatedPairs; //!< Array of new/found/created pairs.
++
++ PxU32 mNbDeletedPairs; //!< Number of lost/deleted pairs.
++ const PxBroadPhasePair* mDeletedPairs; //!< Array of lost/deleted pairs.
++ };
++
++ /**
++ \brief Broadphase regions.
++
++ An API to manage broadphase regions. Only needed for the MBP broadphase (PxBroadPhaseType::eMBP).
++
++ \see PxBroadPhase::getRegions()
++ */
++ class PxBroadPhaseRegions
++ {
++ protected:
++ PxBroadPhaseRegions() {}
++ virtual ~PxBroadPhaseRegions() {}
++ public:
++
++ /**
++ \brief Returns number of regions currently registered in the broad-phase.
++
++ \return Number of regions
++ */
++ virtual PxU32 getNbRegions() const = 0;
++
++ /**
++ \brief Gets broad-phase regions.
++
++ \param userBuffer [out] Returned broad-phase regions
++ \param bufferSize [in] Size of provided userBuffer.
++ \param startIndex [in] Index of first desired region, in [0 ; getNbRegions()[
++ \return Number of written out regions.
++ \see PxBroadPhaseRegionInfo
++ */
++ virtual PxU32 getRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
++
++ /**
++ \brief Adds a new broad-phase region.
++
++ The total number of regions is limited to PxBroadPhaseCaps::mMaxNbRegions. If that number is exceeded, the call is ignored.
++
++ The newly added region will be automatically populated with already existing objects that touch it, if the
++ 'populateRegion' parameter is set to true. Otherwise the newly added region will be empty, and it will only be
++ populated with objects when those objects are added to the simulation, or updated if they already exist.
++
++ Using 'populateRegion=true' has a cost, so it is best to avoid it if possible. In particular it is more efficient
++ to create the empty regions first (with populateRegion=false) and then add the objects afterwards (rather than
++ the opposite).
++
++ Objects automatically move from one region to another during their lifetime. The system keeps tracks of what
++ regions a given object is in. It is legal for an object to be in an arbitrary number of regions. However if an
++ object leaves all regions, or is created outside of all regions, several things happen:
++ - collisions get disabled for this object
++ - the object appears in the getOutOfBoundsObjects() array
++
++ If an out-of-bounds object, whose collisions are disabled, re-enters a valid broadphase region, then collisions
++ are re-enabled for that object.
++
++ \param region [in] User-provided region data
++ \param populateRegion [in] True to automatically populate the newly added region with existing objects touching it
++ \param bounds [in] User-managed array of bounds
++ \param distances [in] User-managed array of distances
++
++ \return Handle for newly created region, or 0xffffffff in case of failure.
++ \see PxBroadPhaseRegion getOutOfBoundsObjects()
++ */
++ virtual PxU32 addRegion(const PxBroadPhaseRegion& region, bool populateRegion, const PxBounds3* bounds, const float* distances) = 0;
++
++ /**
++ \brief Removes a broad-phase region.
++
++ If the region still contains objects, and if those objects do not overlap any region any more, they are not
++ automatically removed from the simulation. Instead, the PxBroadPhaseCallback::onObjectOutOfBounds notification
++ is used for each object. Users are responsible for removing the objects from the simulation if this is the
++ desired behavior.
++
++ If the handle is invalid, or if a valid handle is removed twice, an error message is sent to the error stream.
++
++ \param handle [in] Region's handle, as returned by addRegion
++ \return True if success
++ */
++ virtual bool removeRegion(PxU32 handle) = 0;
++
++ /*
++ \brief Return the number of objects that are not in any region.
++ */
++ virtual PxU32 getNbOutOfBoundsObjects() const = 0;
++
++ /*
++ \brief Return an array of objects that are not in any region.
++ */
++ virtual const PxU32* getOutOfBoundsObjects() const = 0;
++ };
++
++ /**
++ \brief Low-level broadphase API.
++
++ This low-level API only supports batched updates and leaves most of the data management to its clients.
++
++ This is useful if you want to use the broadphase with your own memory buffers. Note however that the GPU broadphase
++ works best with buffers allocated in CUDA memory. The getAllocator() function returns an allocator that is compatible
++ with the selected broadphase. It is recommended to allocate and deallocate the broadphase data (bounds, groups, distances)
++ using this allocator.
++
++ Important note: it must be safe to load 4 bytes past the end of the provided bounds array.
++
++ The high-level broadphase API (PxAABBManager) is an easier-to-use interface that automatically deals with these requirements.
++
++ \see PxCreateBroadPhase
++ */
++ class PxBroadPhase
++ {
++ protected:
++ PxBroadPhase() {}
++ virtual ~PxBroadPhase() {}
++ public:
++
++ /*
++ \brief Releases the broadphase.
++ */
++ virtual void release() = 0;
++
++ /**
++ \brief Gets the broadphase type.
++
++ \return Broadphase type.
++ \see PxBroadPhaseType::Enum
++ */
++ virtual PxBroadPhaseType::Enum getType() const = 0;
++
++ /**
++ \brief Gets broad-phase caps.
++
++ \param caps [out] Broad-phase caps
++ \see PxBroadPhaseCaps
++ */
++ virtual void getCaps(PxBroadPhaseCaps& caps) const = 0;
++
++ /**
++ \brief Retrieves the regions API if applicable.
++
++ For broadphases that do not use explicit user-defined regions, this call returns NULL.
++
++ \return Region API, or NULL.
++ \see PxBroadPhaseRegions
++ */
++ virtual PxBroadPhaseRegions* getRegions() = 0;
++
++ /**
++ \brief Retrieves the broadphase allocator.
++
++ User-provided buffers should ideally be allocated with this allocator, for best performance.
++ This is especially true for the GPU broadphases, whose buffers need to be allocated in CUDA
++ host memory.
++
++ \return The broadphase allocator.
++ \see PxAllocatorCallback
++ */
++ virtual PxAllocatorCallback* getAllocator() = 0;
++
++ /**
++ \brief Retrieves the profiler's context ID.
++
++ \return The context ID.
++ \see PxBroadPhaseDesc
++ */
++ virtual PxU64 getContextID() const = 0;
++
++ /**
++ \brief Sets a scratch buffer
++
++ Some broadphases might take advantage of a scratch buffer to limit runtime allocations.
++
++ All broadphases still work without providing a scratch buffer, this is an optional function
++ that can potentially reduce runtime allocations.
++
++ \param scratchBlock [in] The scratch buffer
++ \param size [in] Size of the scratch buffer in bytes
++ */
++ virtual void setScratchBlock(void* scratchBlock, PxU32 size) = 0;
++
++ /**
++ \brief Updates the broadphase and computes the lists of created/deleted pairs.
++
++ The provided update data describes changes to objects since the last broadphase update.
++
++ To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
++ task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
++ then run single-threaded.
++
++ \param updateData [in] The update data
++ \param continuation [in] Continuation task to enable multi-threaded implementations, or NULL.
++ \see PxBroadPhaseUpdateData PxBaseTask
++ */
++ virtual void update(const PxBroadPhaseUpdateData& updateData, PxBaseTask* continuation=NULL) = 0;
++
++ /**
++ \brief Retrieves the broadphase results after an update.
++
++ This should be called once after each update call to retrieve the results of the broadphase. The
++ results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.
++
++ \param results [out] The broadphase results
++ \see PxBroadPhaseResults
++ */
++ virtual void fetchResults(PxBroadPhaseResults& results) = 0;
++
++ /**
++ \brief Helper for single-threaded updates.
++
++ This short helper function performs a single-theaded update and reports the results in a single call.
++
++ \param results [out] The broadphase results
++ \param updateData [in] The update data
++ \see PxBroadPhaseUpdateData PxBroadPhaseResults
++ */
++ PX_FORCE_INLINE void updateAndFetchResults(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
++ {
++ update(updateData);
++ fetchResults(results);
++ }
++
++ /**
++ \brief Helper for single-threaded updates.
++
++ This short helper function performs a single-theaded update and reports the results in a single call.
++
++ \param results [out] The broadphase results
++ \param updateData [in] The update data
++ \see PxBroadPhaseUpdateData PxBroadPhaseResults
++ */
++ PX_DEPRECATED PX_FORCE_INLINE void update(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
++ {
++ update(updateData);
++ fetchResults(results);
++ }
++ };
++
++ /**
++ \brief Broadphase factory function.
++
++ Use this function to create a new standalone broadphase.
++
++ \param desc [in] Broadphase descriptor
++ \return Newly created broadphase, or NULL
++ \see PxBroadPhase PxBroadPhaseDesc
++ */
++ PX_C_EXPORT PX_PHYSX_CORE_API PxBroadPhase* PxCreateBroadPhase(const PxBroadPhaseDesc& desc);
++
++ /**
++ \brief High-level broadphase API.
++
++ The low-level broadphase API (PxBroadPhase) only supports batched updates and has a few non-trivial
++ requirements for managing the bounds data.
++
++ The high-level broadphase API (PxAABBManager) is an easier-to-use one-object-at-a-time API that
++ automatically deals with the quirks of the PxBroadPhase data management.
++
++ \see PxCreateAABBManager
++ */
++ class PxAABBManager
++ {
++ protected:
++ PxAABBManager() {}
++ virtual ~PxAABBManager() {}
++ public:
++
++ /*
++ \brief Releases the AABB manager.
++ */
++ virtual void release() = 0;
++
++ /**
++ \brief Retrieves the underlying broadphase.
++
++ \return The managed broadphase.
++ \see PxBroadPhase
++ */
++ virtual PxBroadPhase& getBroadPhase() = 0;
++
++ /**
++ \brief Retrieves the managed bounds.
++
++ This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.
++
++ \return The managed object bounds.
++ \see PxBounds3
++ */
++ virtual const PxBounds3* getBounds() const = 0;
++
++ /**
++ \brief Retrieves the managed distances.
++
++ This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.
++
++ \return The managed object distances.
++ */
++ virtual const float* getDistances() const = 0;
++
++ /**
++ \brief Retrieves the managed filter groups.
++
++ \return The managed object groups.
++ */
++ virtual const PxBpFilterGroup* getGroups() const = 0;
++
++ /**
++ \brief Retrieves the managed buffers' capacity.
++
++ Bounds, distances and groups buffers have the same capacity.
++
++ \return The managed buffers' capacity.
++ */
++ virtual PxU32 getCapacity() const = 0;
++
++ /**
++ \brief Adds an object to the manager.
++
++ Objects' indices are externally managed, i.e. they must be provided by users (as opposed to handles
++ that could be returned by this manager). The design allows users to identify an object by a single ID,
++ and use the same ID in multiple sub-systems.
++
++ \param index [in] The object's index
++ \param bounds [in] The object's bounds
++ \param group [in] The object's filter group
++ \param distance [in] The object's distance (optional)
++ \see PxBpIndex PxBounds3 PxBpFilterGroup
++ */
++ virtual void addObject(PxBpIndex index, const PxBounds3& bounds, PxBpFilterGroup group, float distance=0.0f) = 0;
++
++ /**
++ \brief Removes an object from the manager.
++
++ \param index [in] The object's index
++ \see PxBpIndex
++ */
++ virtual void removeObject(PxBpIndex index) = 0;
++
++ /**
++ \brief Updates an object in the manager.
++
++ This call can update an object's bounds, distance, or both.
++ It is not possible to update an object's filter group.
++
++ \param index [in] The object's index
++ \param bounds [in] The object's updated bounds, or NULL
++ \param distance [in] The object's updated distance, or NULL
++ \see PxBpIndex PxBounds3
++ */
++ virtual void updateObject(PxBpIndex index, const PxBounds3* bounds=NULL, const float* distance=NULL) = 0;
++
++ /**
++ \brief Updates the broadphase and computes the lists of created/deleted pairs.
++
++ The data necessary for updating the broadphase is internally computed by the AABB manager.
++
++ To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
++ task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
++ then run single-threaded.
++
++ \param continuation [in] Continuation task to enable multi-threaded implementations, or NULL.
++ \see PxBaseTask
++ */
++ virtual void update(PxBaseTask* continuation=NULL) = 0;
++
++ /**
++ \brief Retrieves the broadphase results after an update.
++
++ This should be called once after each update call to retrieve the results of the broadphase. The
++ results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.
++
++ \param results [out] The broadphase results
++ \see PxBroadPhaseResults
++ */
++ virtual void fetchResults(PxBroadPhaseResults& results) = 0;
++
++ /**
++ \brief Helper for single-threaded updates.
++
++ This short helper function performs a single-theaded update and reports the results in a single call.
++
++ \param results [out] The broadphase results
++ \see PxBroadPhaseResults
++ */
++ PX_FORCE_INLINE void updateAndFetchResults(PxBroadPhaseResults& results)
++ {
++ update();
++ fetchResults(results);
++ }
++
++ /**
++ \brief Helper for single-threaded updates.
++
++ This short helper function performs a single-theaded update and reports the results in a single call.
++
++ \param results [out] The broadphase results
++ \see PxBroadPhaseResults
++ */
++ PX_DEPRECATED PX_FORCE_INLINE void update(PxBroadPhaseResults& results)
++ {
++ update();
++ fetchResults(results);
++ }
++ };
++
++ /**
++ \brief AABB manager factory function.
++
++ Use this function to create a new standalone high-level broadphase.
++
++ \param broadphase [in] The broadphase that will be managed by the AABB manager
++ \return Newly created AABB manager, or NULL
++ \see PxAABBManager PxBroadPhase
++ */
++ PX_C_EXPORT PX_PHYSX_CORE_API PxAABBManager* PxCreateAABBManager(PxBroadPhase& broadphase);
++
++ #if !PX_DOXYGEN
++ } // namespace physx
++ #endif
++
++ #endif