include/PxParticleBuffer.h

File members: include/PxParticleBuffer.h

// 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_PARTICLE_BUFFER_H
#define PX_PARTICLE_BUFFER_H
#include "common/PxBase.h"
#include "common/PxPhysXCommonConfig.h"
#include "common/PxTypeInfo.h"

#include "PxParticleSystemFlag.h"

#include "foundation/PxBounds3.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"

#if !PX_DOXYGEN
namespace physx
{
#endif

#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif

class PxCudaContextManager;
struct PxParticleRigidFilterPair;
struct PxParticleRigidAttachment;

PX_ALIGN_PREFIX(16)
struct PxParticleVolume
{
    PxBounds3   bound;
    PxU32       particleIndicesOffset;
    PxU32       numParticles;
} PX_ALIGN_SUFFIX(16);

class PxParticleBuffer : public PxBase
{
public:

    virtual PxVec4*             getPositionInvMasses() const = 0;

    virtual PxVec4*             getVelocities() const = 0;

    virtual PxU32*              getPhases() const = 0;

    virtual PxParticleVolume*   getParticleVolumes() const = 0;

    virtual void                setNbActiveParticles(PxU32 nbActiveParticles) = 0;

    virtual PxU32               getNbActiveParticles() const = 0;

    virtual PxU32               getMaxParticles() const = 0;

    virtual PxU32               getNbParticleVolumes() const = 0;

    virtual void                setNbParticleVolumes(PxU32 nbParticleVolumes) = 0;

    virtual PxU32               getMaxParticleVolumes() const = 0;

    virtual void                setRigidFilters(PxParticleRigidFilterPair* filters, PxU32 nbFilters) = 0;

    virtual void                setRigidAttachments(PxParticleRigidAttachment* attachments, PxU32 nbAttachments) = 0;

    virtual PxU32               getFlatListStartIndex() const = 0;

    virtual void                raiseFlags(PxParticleBufferFlag::Enum flags) = 0;

    virtual void                release() = 0;

    virtual void                onParticleSystemDestroy() = 0;

    virtual void                setInternalData(void* data) = 0;

    PxU32                       bufferIndex;

    const PxU32                 bufferUniqueId;

protected:

    virtual                     ~PxParticleBuffer() { }
    PX_INLINE                   PxParticleBuffer(PxU32 uniqueId) : PxBase(PxConcreteType::ePARTICLE_BUFFER, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), bufferIndex(0xffffffff), bufferUniqueId(uniqueId){}
    PX_INLINE                   PxParticleBuffer(PxU32 uniqueId, PxType type) : PxBase(type, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), bufferIndex(0xffffffff), bufferUniqueId(uniqueId){}

private:
    PX_NOCOPY(PxParticleBuffer)
};

class PxDiffuseParticleParams
{
public:
    PX_INLINE PxDiffuseParticleParams()
    {
        threshold = 100.0f;
        lifetime = 5.0f;
        airDrag = 0.0f;
        bubbleDrag = 0.5f;
        buoyancy = 0.8f;
        kineticEnergyWeight = 0.01f;
        pressureWeight = 1.0f;
        divergenceWeight = 5.0f;
        collisionDecay = 0.5f;
        useAccurateVelocity = false;
    }

    PX_INLINE void setToDefault()
    {
        *this = PxDiffuseParticleParams();
    }

    PxReal  threshold;
    PxReal  lifetime;
    PxReal  airDrag;
    PxReal  bubbleDrag;
    PxReal  buoyancy;
    PxReal  kineticEnergyWeight;
    PxReal  pressureWeight;
    PxReal  divergenceWeight;
    PxReal  collisionDecay;
    bool    useAccurateVelocity;
};

class PxParticleAndDiffuseBuffer : public PxParticleBuffer
{
public:

    virtual PxVec4*                 getDiffusePositionLifeTime() const = 0;

    virtual PxU32                   getNbActiveDiffuseParticles() const = 0;

    virtual void                    setMaxActiveDiffuseParticles(PxU32 maxActiveDiffuseParticles) = 0;

    virtual PxU32                   getMaxDiffuseParticles() const = 0;

    virtual void                    setDiffuseParticleParams(const PxDiffuseParticleParams& params) = 0;

    virtual PxDiffuseParticleParams getDiffuseParticleParams() const = 0;

protected:

    virtual                         ~PxParticleAndDiffuseBuffer() {}
    PX_INLINE                       PxParticleAndDiffuseBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_DIFFUSE_BUFFER){}

private:
    PX_NOCOPY(PxParticleAndDiffuseBuffer)
};

struct PX_ALIGN_PREFIX(8) PxParticleSpring
{
    PxU32 ind0;
    PxU32 ind1;
    PxReal length;
    PxReal stiffness;
    PxReal damping;
    PxReal pad;
} PX_ALIGN_SUFFIX(8);

struct PxParticleCloth
{
    PxU32   startVertexIndex;
    PxU32   numVertices;
    PxReal  clothBlendScale;
    PxReal  restVolume;
    PxReal  pressure;
    PxU32   startTriangleIndex;
    PxU32   numTriangles;

    bool operator <= (const PxParticleCloth& other) const { return startVertexIndex <= other.startVertexIndex; }
    bool operator >= (const PxParticleCloth& other) const { return startVertexIndex >= other.startVertexIndex; }
    bool operator < (const PxParticleCloth& other) const { return startVertexIndex < other.startVertexIndex; }
    bool operator > (const PxParticleCloth& other) const { return startVertexIndex > other.startVertexIndex; }
    bool operator == (const PxParticleCloth& other) const { return startVertexIndex == other.startVertexIndex; }
};

struct PxParticleClothDesc
{
    PxParticleClothDesc() : cloths(NULL), triangles(NULL), springs(NULL), restPositions(NULL),
        nbCloths(0), nbSprings(0), nbTriangles(0), nbParticles(0)
    {
    }

    PxParticleCloth*    cloths;
    PxU32*              triangles;
    PxParticleSpring*   springs;
    PxVec4*             restPositions;
    PxU32               nbCloths;
    PxU32               nbSprings;
    PxU32               nbTriangles;
    PxU32               nbParticles;
};

struct PX_PHYSX_CORE_API PxPartitionedParticleCloth
{
    PxU32*                      accumulatedSpringsPerPartitions;
    PxU32*                      accumulatedCopiesPerParticles;
    PxU32*                      remapOutput;
    PxParticleSpring*           orderedSprings;
    PxU32*                      sortedClothStartIndices;
    PxParticleCloth*            cloths;

    PxU32                       remapOutputSize;
    PxU32                       nbPartitions;
    PxU32                       nbSprings;
    PxU32                       nbCloths;
    PxU32                       maxSpringsPerPartition;

    PxCudaContextManager*       mCudaManager;

    PxPartitionedParticleCloth();
    ~PxPartitionedParticleCloth();

    void allocateBuffers(PxU32 nbParticles, PxCudaContextManager* cudaManager);
};

class PxParticleClothBuffer : public PxParticleBuffer
{
public:

    virtual PxVec4*             getRestPositions() = 0;

    virtual PxU32*              getTriangles() const = 0;

    virtual void                setNbTriangles(PxU32 nbTriangles) = 0;

    virtual PxU32               getNbTriangles() const = 0;

    virtual PxU32               getNbSprings() const = 0;

    virtual PxParticleSpring*   getSprings() = 0;

    virtual void                setCloths(PxPartitionedParticleCloth& cloths) = 0;

protected:

    virtual                     ~PxParticleClothBuffer() {}
    PX_INLINE                   PxParticleClothBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_CLOTH_BUFFER) {}

private:
    PX_NOCOPY(PxParticleClothBuffer)
};

class PxParticleRigidBuffer : public PxParticleBuffer
{
public:
    virtual PxU32*  getRigidOffsets() const = 0;

    virtual PxReal* getRigidCoefficients() const = 0;

    virtual PxVec4* getRigidLocalPositions() const = 0;

    virtual PxVec4* getRigidTranslations() const = 0;

    virtual PxVec4* getRigidRotations() const = 0;

    virtual PxVec4* getRigidLocalNormals() const = 0;

    virtual void    setNbRigids(PxU32 nbRigids) = 0;

    virtual PxU32   getNbRigids() const = 0;

protected:

    virtual         ~PxParticleRigidBuffer() {}
    PX_INLINE       PxParticleRigidBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_RIGID_BUFFER) {}

private:
    PX_NOCOPY(PxParticleRigidBuffer)
};

class PxParticleClothPreProcessor
{
public:

    virtual void    release() = 0;

    virtual void    partitionSprings(const PxParticleClothDesc& clothDesc, PxPartitionedParticleCloth& output) = 0;

protected:
    virtual         ~PxParticleClothPreProcessor(){}
};

#if PX_VC
#pragma warning(pop)
#endif

#if !PX_DOXYGEN
} // namespace physx
#endif

PX_C_EXPORT PX_PHYSX_CORE_API physx::PxParticleClothPreProcessor* PX_CALL_CONV PxCreateParticleClothPreProcessor(physx::PxCudaContextManager* cudaContextManager);

#endif