// 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-2025 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 SQ_PRUNER_H #define SQ_PRUNER_H #include "foundation/PxBounds3.h" #include "foundation/PxUserAllocated.h" #include "foundation/PxFlags.h" #include "GuPruner.h" #include "SqTypedef.h" namespace physx { namespace Gu { class BVH; } namespace Sq { /** \brief Compound-pruner-specific flags for scene queries. */ struct PxCompoundPrunerQueryFlag { enum Enum { eSTATIC = (1<<0), //!< Traverse static compounds eDYNAMIC = (1<<1), //!< Traverse dynamic compounds }; }; /** \brief Flags typedef for the set of bits defined in PxCompoundPrunerQueryFlag. */ typedef PxFlags PxCompoundPrunerQueryFlags; PX_FLAGS_OPERATORS(PxCompoundPrunerQueryFlag::Enum,PxU32) struct CompoundPrunerRaycastCallback { CompoundPrunerRaycastCallback() {} virtual ~CompoundPrunerRaycastCallback() {} virtual bool invoke(PxReal& distance, PxU32 primIndex, const Gu::PrunerPayload* payloads, const PxTransform* transforms, const PxTransform* compoundPose) = 0; }; struct CompoundPrunerOverlapCallback { CompoundPrunerOverlapCallback() {} virtual ~CompoundPrunerOverlapCallback() {} virtual bool invoke(PxU32 primIndex, const Gu::PrunerPayload* payloads, const PxTransform* transforms, const PxTransform* compoundPose) = 0; }; ////////////////////////////////////////////////////////////////////////// /** * Pruner holding compound objects */ ////////////////////////////////////////////////////////////////////////// class CompoundPruner : public Gu::BasePruner { public: virtual ~CompoundPruner() {} /** \brief Adds compound to the pruner. \param results [out] an array for resulting handles \param bvh [in] BVH \param compoundId [in] compound id \param transform [in] compound transform \param data [in] an array of object data \return true if success, false if internal allocation failed. The first failing add results in a INVALID_PRUNERHANDLE. Handles are usable as indices. Each handle is either be a recycled handle returned by the client via removeObjects(), or a fresh handle that is either zero, or one greater than the last fresh handle returned. */ virtual bool addCompound(Gu::PrunerHandle* results, const Gu::BVH& bvh, PrunerCompoundId compoundId, const PxTransform& transform, bool isDynamic, const Gu::PrunerPayload* data, const PxTransform* transforms) = 0; /** Removes compound from the pruner. \param compoundId [in] compound to remove */ virtual bool removeCompound(PrunerCompoundId compoundId, Gu::PrunerPayloadRemovalCallback* removalCallback) = 0; /** Updates compound object \param compoundId [in] compound to update \param transform [in] compound transformation */ virtual bool updateCompound(PrunerCompoundId compoundId, const PxTransform& transform) = 0; /** Updates object after manually updating their bounds via "getPayload" calls. \param compoundId [in] compound that the object belongs to \param handle [in] the object to update */ virtual void updateObjectAfterManualBoundsUpdates(PrunerCompoundId compoundId, const Gu::PrunerHandle handle) = 0; /** Removes object from compound pruner. \param compoundId [in] compound that the object belongs to \param handle [in] the object to remove */ virtual void removeObject(PrunerCompoundId compoundId, const Gu::PrunerHandle handle, Gu::PrunerPayloadRemovalCallback* removalCallback) = 0; /** \brief Adds object to the pruner. \param compoundId [in] compound that the object belongs to \param result [out] an array for resulting handles \param bounds [in] an array of bounds. These bounds are used as-is so they should be pre-inflated if inflation is needed. \param userData [in] an array of object data \return true if success, false if internal allocation failed. The first failing add results in a INVALID_PRUNERHANDLE. */ virtual bool addObject(PrunerCompoundId compoundId, Gu::PrunerHandle& result, const PxBounds3& bounds, const Gu::PrunerPayload userData, const PxTransform& transform) = 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, CompoundPrunerRaycastCallback&, PxCompoundPrunerQueryFlags flags) const = 0; virtual bool overlap(const Gu::ShapeData& queryVolume, CompoundPrunerOverlapCallback&, PxCompoundPrunerQueryFlags flags) const = 0; virtual bool sweep(const Gu::ShapeData& queryVolume, const PxVec3& unitDir, PxReal& inOutDistance, CompoundPrunerRaycastCallback&, PxCompoundPrunerQueryFlags flags) 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[in] compoundId The compound id \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 Gu::PrunerPayload& getPayloadData(Gu::PrunerHandle handle, PrunerCompoundId compoundId, Gu::PrunerPayloadData* data) const = 0; /** \brief Preallocate space \param[in] nbEntries The number of entries to preallocate space for */ virtual void preallocate(PxU32 nbEntries) = 0; // PT: beware, shape transform virtual bool setTransform(Gu::PrunerHandle handle, PrunerCompoundId compoundId, const PxTransform& transform) = 0; // PT: beware, actor transform virtual const PxTransform& getTransform(PrunerCompoundId compoundId) const = 0; virtual void visualizeEx(PxRenderOutput& out, PxU32 color, bool drawStatic, bool drawDynamic) const = 0; }; } } #endif