235 lines
9.1 KiB
C++
235 lines
9.1 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-2019 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_PHYSICS_GEOMUTILS_PX_ADJACENCIES
|
|
#define PX_PHYSICS_GEOMUTILS_PX_ADJACENCIES
|
|
|
|
#define MSH_ADJACENCIES_INCLUDE_CONVEX_BITS
|
|
#include "foundation/Px.h"
|
|
#include "GuTriangle32.h"
|
|
|
|
namespace physx
|
|
{
|
|
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_CONVEX_BITS
|
|
#define ADJ_TRIREF_MASK 0x1fffffff //!< Masks 3 bits
|
|
#define IS_CONVEX_EDGE(x) (x & 0x20000000) //!< Returns true for convex edges
|
|
#else
|
|
#define ADJ_TRIREF_MASK 0x3fffffff //!< Masks 2 bits
|
|
#endif
|
|
|
|
#define MAKE_ADJ_TRI(x) (x & ADJ_TRIREF_MASK) //!< Transforms a link into a triangle reference.
|
|
#define GET_EDGE_NB(x) (x>>30) //!< Transforms a link into a counterpart edge ID.
|
|
// #define IS_BOUNDARY(x) (x==PX_INVALID_U32) //!< Returns true for boundary edges.
|
|
#define IS_BOUNDARY(x) ((x & ADJ_TRIREF_MASK)==ADJ_TRIREF_MASK) //!< Returns true for boundary edges.
|
|
|
|
// Forward declarations
|
|
class Adjacencies;
|
|
|
|
enum SharedEdgeIndex
|
|
{
|
|
EDGE01 = 0,
|
|
EDGE02 = 1,
|
|
EDGE12 = 2
|
|
};
|
|
|
|
/* PX_INLINE void GetEdgeIndices(SharedEdgeIndex edge_index, PxU32& id0, PxU32& id1)
|
|
{
|
|
if(edge_index==0)
|
|
{
|
|
id0 = 0;
|
|
id1 = 1;
|
|
}
|
|
else if(edge_index==1)
|
|
{
|
|
id0 = 0;
|
|
id1 = 2;
|
|
}
|
|
else if(edge_index==2)
|
|
{
|
|
id0 = 1;
|
|
id1 = 2;
|
|
}
|
|
}*/
|
|
|
|
//! Sets a new edge code
|
|
#define SET_EDGE_NB(link, code) \
|
|
link&=ADJ_TRIREF_MASK; \
|
|
link|=code<<30; \
|
|
|
|
//! A triangle class used to compute the adjacency structures.
|
|
class AdjTriangle
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_TOPOLOGY
|
|
: public IndexedTriangle
|
|
#else
|
|
: public Ps::UserAllocated
|
|
#endif
|
|
{
|
|
public:
|
|
//! Constructor
|
|
PX_INLINE AdjTriangle() {}
|
|
//! Destructor
|
|
PX_INLINE ~AdjTriangle() {}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes the number of boundary edges in a triangle.
|
|
* \return the number of boundary edges. (0 => 3)
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
PxU32 ComputeNbBoundaryEdges() const;
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes the number of valid neighbors.
|
|
* \return the number of neighbors. (0 => 3)
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
PxU32 ComputeNbNeighbors() const;
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Checks whether the triangle has a particular neighbor or not.
|
|
* \param tref [in] the triangle reference to look for
|
|
* \param index [out] the corresponding index in the triangle (NULL if not needed)
|
|
* \return true if the triangle has the given neighbor
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool HasNeighbor(PxU32 tref, PxU32* index=NULL) const;
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Flips the winding.
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void Flip();
|
|
|
|
// Data access
|
|
PX_INLINE PxU32 GetLink(SharedEdgeIndex edge_index) const { return mATri[edge_index]; }
|
|
PX_INLINE PxU32 GetAdjTri(SharedEdgeIndex edge_index) const { return MAKE_ADJ_TRI(mATri[edge_index]); }
|
|
PX_INLINE PxU32 GetAdjEdge(SharedEdgeIndex edge_index) const { return GET_EDGE_NB(mATri[edge_index]); }
|
|
PX_INLINE Ps::IntBool IsBoundaryEdge(SharedEdgeIndex edge_index) const { return IS_BOUNDARY(mATri[edge_index]); }
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_CONVEX_BITS
|
|
PX_INLINE Ps::IntBool HasActiveEdge01() const { return Ps::IntBool(IS_CONVEX_EDGE(mATri[EDGE01])); }
|
|
PX_INLINE Ps::IntBool HasActiveEdge20() const { return Ps::IntBool(IS_CONVEX_EDGE(mATri[EDGE02])); }
|
|
PX_INLINE Ps::IntBool HasActiveEdge12() const { return Ps::IntBool(IS_CONVEX_EDGE(mATri[EDGE12])); }
|
|
PX_INLINE Ps::IntBool HasActiveEdge(PxU32 i) const { return Ps::IntBool(IS_CONVEX_EDGE(mATri[i])); }
|
|
#endif
|
|
// private:
|
|
//! Links/References of adjacent triangles. The 2 most significant bits contains the counterpart edge in the adjacent triangle.
|
|
//! mATri[0] refers to edge 0-1
|
|
//! mATri[1] refers to edge 0-2
|
|
//! mATri[2] refers to edge 1-2
|
|
PxU32 mATri[3];
|
|
};
|
|
|
|
//! The adjacencies creation structure.
|
|
struct ADJACENCIESCREATE
|
|
{
|
|
//! Constructor
|
|
ADJACENCIESCREATE() : NbFaces(0), DFaces(NULL), WFaces(NULL)
|
|
{
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_CONVEX_BITS
|
|
Verts = NULL;
|
|
Epsilon = 0.1f;
|
|
// Epsilon = 0.001f;
|
|
#endif
|
|
}
|
|
|
|
PxU32 NbFaces; //!< Number of faces in source topo
|
|
const PxU32* DFaces; //!< List of faces (dwords) or NULL
|
|
const PxU16* WFaces; //!< List of faces (words) or NULL
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_CONVEX_BITS
|
|
const PxVec3* Verts;
|
|
float Epsilon;
|
|
#endif
|
|
};
|
|
|
|
class Adjacencies : public Ps::UserAllocated
|
|
{
|
|
public:
|
|
Adjacencies();
|
|
~Adjacencies();
|
|
|
|
PxU32 mNbFaces; //!< Number of faces involved in the computation.
|
|
AdjTriangle* mFaces; //!< A list of AdjTriangles (one/face)
|
|
|
|
bool Load(PxInputStream& stream);
|
|
// Basic mesh walking
|
|
PX_INLINE const AdjTriangle* GetAdjacentFace(const AdjTriangle& current_tri, SharedEdgeIndex edge_nb) const
|
|
{
|
|
// No checkings here, make sure mFaces has been created
|
|
|
|
// Catch the link
|
|
PxU32 Link = current_tri.GetLink(edge_nb);
|
|
|
|
// Returns NULL for boundary edges
|
|
if(IS_BOUNDARY(Link)) return NULL;
|
|
|
|
// Else transform into face index
|
|
PxU32 Id = MAKE_ADJ_TRI(Link);
|
|
|
|
// Possible counterpart edge is:
|
|
// PxU32 Edge = GET_EDGE_NB(Link);
|
|
|
|
// And returns adjacent triangle
|
|
return &mFaces[Id];
|
|
}
|
|
// Helpers
|
|
PxU32 ComputeNbBoundaryEdges() const;
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_TOPOLOGY
|
|
bool GetBoundaryVertices(PxU32 nb_verts, bool* bound_status) const;
|
|
#else
|
|
bool GetBoundaryVertices(PxU32 nb_verts, bool* bound_status, const Gu::TriangleT<PxU32>* faces) const;
|
|
#endif
|
|
//
|
|
#ifdef MSH_ADJACENCIES_INCLUDE_TOPOLOGY
|
|
bool MakeLastRef(AdjTriangle& cur_tri, PxU32 vref);
|
|
#else
|
|
bool MakeLastRef(AdjTriangle& cur_tri, PxU32 vref, Gu::TriangleT<PxU32>* cur_topo);
|
|
#endif
|
|
private:
|
|
// New edge codes assignment
|
|
void AssignNewEdgeCode(PxU32 link, PxU8 edge_nb);
|
|
};
|
|
|
|
//#ifdef PX_COOKING
|
|
class AdjacenciesBuilder : public Adjacencies
|
|
{
|
|
public:
|
|
AdjacenciesBuilder();
|
|
~AdjacenciesBuilder();
|
|
|
|
bool Init(const ADJACENCIESCREATE& create);
|
|
// bool Save(Stream& stream) const;
|
|
};
|
|
//#endif
|
|
|
|
}
|
|
|
|
#endif
|