353 lines
13 KiB
C
353 lines
13 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-2023 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 PX_ISOSURFACE_EXTRACTION_H
|
||
|
#define PX_ISOSURFACE_EXTRACTION_H
|
||
|
/** \addtogroup extensions
|
||
|
@{
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "cudamanager/PxCudaContext.h"
|
||
|
#include "cudamanager/PxCudaContextManager.h"
|
||
|
|
||
|
#include "foundation/PxSimpleTypes.h"
|
||
|
#include "foundation/PxVec4.h"
|
||
|
#include "PxParticleSystem.h"
|
||
|
|
||
|
#include "PxSparseGridParams.h"
|
||
|
|
||
|
#include "foundation/PxArray.h"
|
||
|
#include "PxParticleGpu.h"
|
||
|
|
||
|
#if !PX_DOXYGEN
|
||
|
namespace physx
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
#if PX_SUPPORT_GPU_PHYSX
|
||
|
|
||
|
/**
|
||
|
\brief Identifies filter type to be applied on the isosurface grid.
|
||
|
*/
|
||
|
struct PxIsosurfaceGridFilteringType
|
||
|
{
|
||
|
enum Enum
|
||
|
{
|
||
|
eNONE = 0, //!< No filtering
|
||
|
eSMOOTH = 1, //!< Gaussian-blur-like filtering
|
||
|
eGROW = 2, //!< A dilate/erode operation will be applied that makes the fluid grow approximately one cell size
|
||
|
eSHRINK = 3 //!< A dilate/erode operation will be applied that makes the fluid shrink approximately one cell size
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief Parameters to define the isosurface extraction settings like isosurface level, filtering etc.
|
||
|
*/
|
||
|
struct PxIsosurfaceParams
|
||
|
{
|
||
|
/**
|
||
|
\brief Default constructor.
|
||
|
*/
|
||
|
PX_INLINE PxIsosurfaceParams()
|
||
|
{
|
||
|
particleCenterToIsosurfaceDistance = 0.2f;
|
||
|
numMeshSmoothingPasses = 4;
|
||
|
numMeshNormalSmoothingPasses = 4;
|
||
|
gridFilteringFlags = 0;
|
||
|
gridSmoothingRadius = 0.2f;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
\brief Clears the filtering operations
|
||
|
*/
|
||
|
PX_INLINE void clearFilteringPasses()
|
||
|
{
|
||
|
gridFilteringFlags = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
\brief Adds a smoothing pass after the existing ones
|
||
|
|
||
|
At most 32 smoothing passes can be defined. Every pass can repeat itself up to 4 times.
|
||
|
|
||
|
\param[in] operation The smoothing operation to add
|
||
|
\return The index of the smoothing pass that was added
|
||
|
*/
|
||
|
PX_INLINE PxU64 addGridFilteringPass(PxIsosurfaceGridFilteringType::Enum operation)
|
||
|
{
|
||
|
for (PxU32 i = 0; i < 32; ++i)
|
||
|
{
|
||
|
PxIsosurfaceGridFilteringType::Enum o;
|
||
|
if (!getGridFilteringPass(i, o))
|
||
|
{
|
||
|
setGridFilteringPass(i, operation);
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
return 0xFFFFFFFFFFFFFFFF;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
\brief Sets the operation of a smoothing pass
|
||
|
|
||
|
\param[in] passIndex The index of the smoothing pass whose operation should be set <b>Range:</b> [0, 31]
|
||
|
\param[in] operation The operation the modified smoothing will perform
|
||
|
*/
|
||
|
PX_INLINE void setGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum operation)
|
||
|
{
|
||
|
PX_ASSERT(passIndex < 32u);
|
||
|
PxU32 shift = passIndex * 2;
|
||
|
gridFilteringFlags &= ~(PxU64(3) << shift);
|
||
|
gridFilteringFlags |= PxU64(operation) << shift;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
\brief Returns the operation of a smoothing pass
|
||
|
|
||
|
\param[in] passIndex The index of the smoothing pass whose operation is requested <b>Range:</b> [0, 31]
|
||
|
\param[out] operation The operation the requested smoothing pass will perform
|
||
|
\return true if the requested pass performs an operation
|
||
|
*/
|
||
|
PX_INLINE bool getGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum& operation) const
|
||
|
{
|
||
|
PxU32 shift = passIndex * 2;
|
||
|
PxU64 v = gridFilteringFlags >> shift;
|
||
|
v &= 3; //Extract last 2 bits
|
||
|
operation = PxIsosurfaceGridFilteringType::Enum(v);
|
||
|
return operation != PxIsosurfaceGridFilteringType::eNONE;
|
||
|
}
|
||
|
|
||
|
PxReal particleCenterToIsosurfaceDistance; //!< Distance form a particle center to the isosurface
|
||
|
PxU32 numMeshSmoothingPasses; //!< Number of Taubin mesh postprocessing smoothing passes. Using an even number of passes lead to less shrinking.
|
||
|
PxU32 numMeshNormalSmoothingPasses; //!< Number of mesh normal postprocessing smoothing passes.
|
||
|
PxU64 gridFilteringFlags; //!< Encodes the smoothing steps to apply on the sparse grid. Use setGridSmoothingPass method to set up.
|
||
|
PxReal gridSmoothingRadius; //!< Gaussian blur smoothing kernel radius used for smoothing operations on the grid
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief Base class for isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use.
|
||
|
*/
|
||
|
class PxIsosurfaceExtractor
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
\brief Returns the isosurface parameters.
|
||
|
|
||
|
\return The isosurfacesettings used for the isosurface extraction
|
||
|
*/
|
||
|
virtual PxIsosurfaceParams getIsosurfaceParams() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Set the isosurface extraction parameters
|
||
|
|
||
|
Allows to configure the isosurface extraction by controlling threshold value, smoothing options etc.
|
||
|
|
||
|
\param[in] params A collection of settings to control the isosurface extraction
|
||
|
*/
|
||
|
virtual void setIsosurfaceParams(const PxIsosurfaceParams& params) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Returns the number of vertices that the current isosurface triangle mesh uses
|
||
|
|
||
|
\return The number of vertices currently in use
|
||
|
*/
|
||
|
virtual PxU32 getNumVertices() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Returns the number of triangles that the current isosurface triangle mesh uses
|
||
|
|
||
|
\return The number of triangles currently in use
|
||
|
*/
|
||
|
virtual PxU32 getNumTriangles() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Returns the maximum number of vertices that the isosurface triangle mesh can contain
|
||
|
|
||
|
\return The maximum number of vertices that can be genrated
|
||
|
*/
|
||
|
virtual PxU32 getMaxVertices() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Returns the maximum number of triangles that the isosurface triangle mesh can contain
|
||
|
|
||
|
\return The maximum number of triangles that can be generated
|
||
|
*/
|
||
|
virtual PxU32 getMaxTriangles() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Resizes the internal triangle mesh buffers.
|
||
|
|
||
|
If the output buffers are device buffers, nothing will get resized but new output buffers can be set using setResultBufferDevice.
|
||
|
For host side output buffers, temporary buffers will get resized. The new host side result buffers with the same size must be set using setResultBufferHost.
|
||
|
|
||
|
\param[in] maxNumVertices The maximum number of vertices the output buffer can hold
|
||
|
\param[in] maxNumTriangles The maximum number of triangles the ouput buffer can hold
|
||
|
*/
|
||
|
virtual void setMaxVerticesAndTriangles(PxU32 maxNumVertices, PxU32 maxNumTriangles) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief The maximal number of particles the isosurface extractor can process
|
||
|
|
||
|
\return The maximal number of particles
|
||
|
*/
|
||
|
virtual PxU32 getMaxParticles() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Sets the maximal number of particles the isosurface extractor can process
|
||
|
|
||
|
\param[in] maxParticles The maximal number of particles
|
||
|
*/
|
||
|
virtual void setMaxParticles(PxU32 maxParticles) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Releases the isosurface extractor instance and its data
|
||
|
*/
|
||
|
virtual void release() = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Triggers the compuation of a new isosurface based on the specified particle locations
|
||
|
|
||
|
\param[in] deviceParticlePos A gpu pointer pointing to the start of the particle array
|
||
|
\param[in] numParticles The number of particles
|
||
|
\param[in] stream The stream on which all the gpu work will be performed
|
||
|
\param[in] phases A phase value per particle
|
||
|
\param[in] validPhaseMask A mask that specifies which phases should contribute to the isosurface. If the binary and operation
|
||
|
between this mask and the particle phase is non zero, then the particle will contribute to the isosurface
|
||
|
\param[in] activeIndices Optional array with indices of all active particles
|
||
|
\param[in] anisotropy1 Optional anisotropy information, x axis direction (xyz) and scale in w component
|
||
|
\param[in] anisotropy2 Optional anisotropy information, y axis direction (xyz) and scale in w component
|
||
|
\param[in] anisotropy3 Optional anisotropy information, z axis direction (xyz) and scale in w component
|
||
|
\param[in] anisotropyFactor A factor to multiply with the anisotropy scale
|
||
|
*/
|
||
|
virtual void extractIsosurface(PxVec4* deviceParticlePos, const PxU32 numParticles, CUstream stream, PxU32* phases = NULL, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid,
|
||
|
PxU32* activeIndices = NULL, PxVec4* anisotropy1 = NULL, PxVec4* anisotropy2 = NULL, PxVec4* anisotropy3 = NULL, PxReal anisotropyFactor = 1.0f) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored
|
||
|
|
||
|
\param[in] vertices A host buffer to store the vertices of the isosurface mesh
|
||
|
\param[in] triIndices A host buffer to store the triangles of the isosurface mesh
|
||
|
\param[in] normals A host buffer to store the normals of the isosurface mesh
|
||
|
*/
|
||
|
virtual void setResultBufferHost(PxVec4* vertices, PxU32* triIndices, PxVec4* normals = NULL) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored
|
||
|
|
||
|
\param[in] vertices A device buffer to store the vertices of the isosurface mesh
|
||
|
\param[in] triIndices A device buffer to store the triangles of the isosurface mesh
|
||
|
\param[in] normals A device buffer to store the normals of the isosurface mesh
|
||
|
*/
|
||
|
virtual void setResultBufferDevice(PxVec4* vertices, PxU32* triIndices, PxVec4* normals) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Enables or disables the isosurface extractor
|
||
|
|
||
|
\param[in] enabled The boolean to set the extractor to enabled or disabled
|
||
|
*/
|
||
|
virtual void setEnabled(bool enabled) = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Allows to query if the isosurface extractor is enabled
|
||
|
|
||
|
\return True if enabled, false otherwise
|
||
|
*/
|
||
|
virtual bool isEnabled() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Destructor
|
||
|
*/
|
||
|
virtual ~PxIsosurfaceExtractor() {}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief Base class for sparse grid based isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use.
|
||
|
*/
|
||
|
class PxSparseGridIsosurfaceExtractor : public PxIsosurfaceExtractor
|
||
|
{
|
||
|
/**
|
||
|
\brief Returns the sparse grid parameters.
|
||
|
|
||
|
\return The sparse grid settings used for the isosurface extraction
|
||
|
*/
|
||
|
virtual PxSparseGridParams getSparseGridParams() const = 0;
|
||
|
|
||
|
/**
|
||
|
\brief Set the sparse grid parameters
|
||
|
|
||
|
Allows to configure cell size, number of subgrids etc.
|
||
|
|
||
|
\param[in] params A collection of settings to control the isosurface grid
|
||
|
*/
|
||
|
virtual void setSparseGridParams(const PxSparseGridParams& params) = 0;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
\brief Default implementation of a particle system callback to trigger the isosurface extraction. A call to fetchResultsParticleSystem() on the
|
||
|
PxScene will synchronize the work such that the caller knows that the post solve task completed.
|
||
|
*/
|
||
|
class PxIsosurfaceCallback : public PxParticleSystemCallback
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
\brief Initializes the isosurface callback
|
||
|
|
||
|
\param[in] isosurfaceExtractor The isosurface extractor
|
||
|
\param[in] validPhaseMask The valid phase mask marking the phase bits that particles must have set in order to contribute to the isosurface
|
||
|
*/
|
||
|
void initialize(PxIsosurfaceExtractor* isosurfaceExtractor, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid)
|
||
|
{
|
||
|
mIsosurfaceExtractor = isosurfaceExtractor;
|
||
|
mValidPhaseMask = validPhaseMask;
|
||
|
}
|
||
|
|
||
|
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream)
|
||
|
{
|
||
|
mIsosurfaceExtractor->extractIsosurface(reinterpret_cast<PxVec4*>(gpuParticleSystem.mHostPtr->mUnsortedPositions_InvMass),
|
||
|
gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream, gpuParticleSystem.mHostPtr->mUnsortedPhaseArray, mValidPhaseMask);
|
||
|
}
|
||
|
|
||
|
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
|
||
|
|
||
|
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
|
||
|
|
||
|
private:
|
||
|
PxIsosurfaceExtractor* mIsosurfaceExtractor;
|
||
|
PxU32 mValidPhaseMask;
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if !PX_DOXYGEN
|
||
|
} // namespace physx
|
||
|
#endif
|
||
|
|
||
|
/** @} */
|
||
|
#endif
|