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 GU_PRUNER_H
++ #define GU_PRUNER_H
++
++ #include "foundation/PxUserAllocated.h"
++ #include "foundation/PxTransform.h"
++ #include "GuPrunerPayload.h"
++ #include "GuPrunerTypedef.h"
++
++ namespace physx
++ {
++ class PxRenderOutput;
++ class PxBounds3;
++
++ namespace Gu
++ {
++ class ShapeData;
++
++ struct PrunerRaycastCallback
++ {
++ PrunerRaycastCallback() {}
++ virtual ~PrunerRaycastCallback() {}
++
++ virtual bool invoke(PxReal& distance, PxU32 primIndex, const PrunerPayload* payloads, const PxTransform* transforms) = 0;
++ };
++
++ struct PrunerOverlapCallback
++ {
++ PrunerOverlapCallback() {}
++ virtual ~PrunerOverlapCallback() {}
++
++ virtual bool invoke(PxU32 primIndex, const PrunerPayload* payloads, const PxTransform* transforms) = 0;
++ };
++
++ class BasePruner : public PxUserAllocated
++ {
++ public:
++ BasePruner() {}
++ virtual ~BasePruner() {}
++
++ // shift the origin of the pruner objects
++ virtual void shiftOrigin(const PxVec3& shift) = 0;
++
++ // additional 'internal' interface
++ virtual void visualize(PxRenderOutput&, PxU32, PxU32) const {}
++ };
++
++ class Pruner : public BasePruner
++ {
++ public:
++ Pruner() {}
++ virtual ~Pruner() {}
++
++ /**
++ \brief Adds objects to the pruner.
++
++ \param[out] results Returned handles for added objects
++ \param[in] bounds Bounds of added objects. These bounds are used as-is so they should be pre-inflated if inflation is needed.
++ \param[in] data Payloads for added objects.
++ \param[in] transforms Transforms of added objects.
++ \param[in] count Number of objects in the arrays
++ \param[in] hasPruningStructure True if added objects have pruning structure. The structure will be merged later, adding the objects will not invalidate the pruner.
++
++ \return true if success, false if internal allocation failed. The first failing add results in a INVALID_PRUNERHANDLE.
++
++ \see PxPruningStructure
++ */
++ virtual bool addObjects(PrunerHandle* results, const PxBounds3* bounds, const PrunerPayload* data, const PxTransform* transforms, PxU32 count, bool hasPruningStructure) = 0;
++
++ /**
++ \brief Removes objects from the pruner.
++
++ \param[in] handles The objects to remove
++ \param[in] count The number of objects to remove
++ \param[in] removalCallback Optional callback, called for each removed object (giving access to its payload for keeping external structures in sync)
++ */
++ virtual void removeObjects(const PrunerHandle* handles, PxU32 count, PrunerPayloadRemovalCallback* removalCallback) = 0;
++
++ /**
++ \brief Updates objects with new bounds & transforms.
++
++ There are two ways to use this function:
++
++ 1) manual bounds update: you can manually update the bounds via "getPayloadData" calls prior to calling "updateObjects".
++ In this case "updateObjects" only notifies the system that the data for these objects has changed. In this mode the
++ "inflation", "boundsIndices", "newBounds" and "newTransforms" parameters should remain null.
++
++ 2) synchronization mode: in this case the new bounds (and optionally the new transforms) have been computed by an
++ external source and "updateObjects" tells the system to update its data from passed buffers. The new bounds are
++ always inflated by the "inflation" parameter while being copied. "boundsIndices" is an optional remap table, allowing
++ this call to only update a subset of the existing bounds (i.e. the updated bounds don't have to be first copied to a
++ separate contiguous buffer).
++
++ \param[in] handles The objects to update
++ \param[in] count The number of objects to update
++ \param[in] inflation Bounds inflation value
++ \param[in] boundsIndices The indices of the bounds in the bounds array (or NULL)
++ \param[in] newBounds Updated bounds array (or NULL)
++ \param[in] newTransforms Updated transforms array (or NULL)
++ */
++ virtual void updateObjects(const PrunerHandle* handles, PxU32 count, float inflation=0.0f, const PxU32* boundsIndices=NULL, const PxBounds3* newBounds=NULL, const PxTransform32* newTransforms=NULL) = 0;
++
++ /**
++ \brief Gets rid of internal accel struct.
++ */
++ virtual void purge() = 0;
++
++ /**
++ \brief Makes the queries consistent with previous changes.
++
++ This function must be called before starting queries on an updated Pruner and assert otherwise.
++ */
++ virtual void commit() = 0;
++
++ /**
++ \brief Merges pruning structure to current pruner, parameters may differ for each pruner implementation.
++
++ \param[in] mergeParams Implementation-dependent merge data
++ */
++ virtual void merge(const void* mergeParams) = 0;
++
++ /**
++ * Query functions
++ *
++ * Note: return value may disappear if PrunerCallback contains the necessary information
++ * currently it is still used for the dynamic pruner internally (to decide if added objects must be queried)
++ */
++ virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, PxReal& inOutDistance, PrunerRaycastCallback&) const = 0;
++ virtual bool overlap(const Gu::ShapeData& queryVolume, PrunerOverlapCallback&) const = 0;
++ virtual bool sweep(const Gu::ShapeData& queryVolume, const PxVec3& unitDir, PxReal& inOutDistance, PrunerRaycastCallback&) const = 0;
++
++ /**
++ \brief Retrieves the object's payload and data associated with the handle.
++
++ This function returns the payload associated with a given handle. Additionally it can return the
++ destination addresses for the object's bounds & transform. The user can then write the new bounds
++ and transform there, before eventually calling updateObjects().
++
++ \param[in] handle Object handle (initially returned by addObjects())
++ \param[out] data Optional location where to store the internal data associated with the payload.
++
++ \return The payload associated with the given handle.
++ */
++ virtual const PrunerPayload& getPayloadData(PrunerHandle handle, PrunerPayloadData* data=NULL) const = 0;
++
++ /**
++ \brief Preallocate space
++
++ \param[in] nbEntries The number of entries to preallocate space for
++ */
++ virtual void preallocate(PxU32 nbEntries) = 0;
++
++ /**
++ \brief Sets object's transform
++
++ \note This is equivalent to retrieving the transform's address with "getPayloadData" and writing
++ the transform there.
++
++ \param[in] handle Object handle (initially returned by addObjects())
++ \param[in] transform New transform
++
++ \return True if success
++ */
++ virtual bool setTransform(PrunerHandle handle, const PxTransform& transform) = 0;
++
++ // PT: from the SQ branch, maybe temporary, unclear if a getType() function would be better etc
++ virtual bool isDynamic() const { return false; }
++
++ virtual void getGlobalBounds(PxBounds3&) const = 0;
++ };
++
++ /**
++ * Pruner building accel structure over time base class
++ */
++ class DynamicPruner : public Pruner
++ {
++ public:
++
++ /**
++ * sets the rebuild hint rate used for step building the accel structure.
++ */
++ virtual void setRebuildRateHint(PxU32 nbStepsForRebuild) = 0;
++
++ /**
++ * Steps the accel structure build.
++ * synchronousCall specifies if initialization can happen. It should not initialize build when called from a different thread
++ * returns true if finished
++ */
++ virtual bool buildStep(bool synchronousCall = true) = 0;
++
++ /**
++ * Prepares new tree build
++ * returns true if new tree is needed
++ */
++ virtual bool prepareBuild() = 0;
++ };
++ }
++ }
++
++ #endif