include/cooking/PxTetrahedronMeshDesc.h

File members: include/cooking/PxTetrahedronMeshDesc.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-2024 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_TETRAHEDRON_MESH_DESC_H
#define PX_TETRAHEDRON_MESH_DESC_H

#include "PxPhysXConfig.h"
#include "foundation/PxVec3.h"
#include "foundation/PxFlags.h"
#include "common/PxCoreUtilityTypes.h"
#include "geometry/PxSimpleTriangleMesh.h"
#include "foundation/PxArray.h"

#if !PX_DOXYGEN
namespace physx
{
#endif
    class PxTetrahedronMeshDesc
    {
    public:

        enum PxMeshFormat
        {
            eTET_MESH,
            eHEX_MESH
        };

        PxTypedStridedData<PxDeformableMaterialTableIndex> materialIndices;

        PxBoundedData points;

        PxBoundedData tetrahedrons;

        PxMeshFlags flags;

        PxU16 tetsPerElement;

        PxTetrahedronMeshDesc()
        {
            points.count = 0;
            points.stride = 0;
            points.data = NULL;

            tetrahedrons.count = 0;
            tetrahedrons.stride = 0;
            tetrahedrons.data = NULL;

            tetsPerElement = 1;
        }

        PxTetrahedronMeshDesc(physx::PxArray<physx::PxVec3>& meshVertices, physx::PxArray<physx::PxU32>& meshTetIndices,
            const PxTetrahedronMeshDesc::PxMeshFormat meshFormat = eTET_MESH, PxU16 numberOfTetsPerHexElement = 5)
        {
            points.count = meshVertices.size();
            points.stride = sizeof(float) * 3;
            points.data = meshVertices.begin();

            tetrahedrons.count = meshTetIndices.size() / 4;
            tetrahedrons.stride = sizeof(int) * 4;
            tetrahedrons.data = meshTetIndices.begin();

            if (meshFormat == eTET_MESH)
                tetsPerElement = 1;
            else
                tetsPerElement = numberOfTetsPerHexElement;
        }

        PX_INLINE bool isValid() const
        {
            // Check geometry of the collision mesh
            if (points.count < 4)   //at least 1 tetrahedron's worth of points
                return false;
            if ((!tetrahedrons.data) && (points.count % 4))     // Non-indexed mesh => we must ensure the geometry defines an implicit number of tetrahedrons // i.e. numVertices can't be divided by 4
                return false;
            if (points.count > 0xffff && flags & PxMeshFlag::e16_BIT_INDICES)
                return false;
            if (!points.data)
                return false;
            if (points.stride < sizeof(PxVec3)) //should be at least one point's worth of data
                return false;

            //add more validity checks here
            if (materialIndices.data && materialIndices.stride < sizeof(PxDeformableMaterialTableIndex))
                return false;

            // The tetrahedrons pointer is not mandatory
            if (tetrahedrons.data)
            {
                // Indexed collision mesh
                PxU32 limit = (flags & PxMeshFlag::e16_BIT_INDICES) ? sizeof(PxU16) * 4 : sizeof(PxU32) * 4;
                if (tetrahedrons.stride < limit)
                    return false;
            }

            //The model can only be either a tetmesh (1 tet per element), or have 5 or 6 tets per hex element, otherwise invalid.
            if (tetsPerElement != 1 && tetsPerElement != 5 && tetsPerElement != 6)
                return false;

            return true;
        }
    };

    class PxDeformableVolumeSimulationDataDesc
    {
    public:
        PxBoundedData vertexToTet;

        PxDeformableVolumeSimulationDataDesc()
        {
            vertexToTet.count = 0;
            vertexToTet.stride = 0;
            vertexToTet.data = NULL;
        }

        PxDeformableVolumeSimulationDataDesc(physx::PxArray<physx::PxI32>& vertToTet)
        {
            vertexToTet.count = vertToTet.size();
            vertexToTet.stride = sizeof(PxI32);
            vertexToTet.data = vertToTet.begin();
        }

        PX_INLINE bool isValid() const
        {
            return true;
        }
    };

    typedef PX_DEPRECATED PxDeformableVolumeSimulationDataDesc PxSoftBodySimulationDataDesc;

#if !PX_DOXYGEN
} // namespace physx
#endif

#endif