228 lines
8.8 KiB
C++
228 lines
8.8 KiB
C++
// 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 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
|