Fix for linker errors when using MeshDecimator.
This commit is contained in:
parent
96cdf7b9a5
commit
5891d56e12
@ -8,6 +8,7 @@ SET(CORE_SRC_FILES
|
|||||||
source/AStarPathfinder.cpp
|
source/AStarPathfinder.cpp
|
||||||
source/GradientEstimators.cpp
|
source/GradientEstimators.cpp
|
||||||
source/Log.cpp
|
source/Log.cpp
|
||||||
|
source/MeshDecimator.cpp
|
||||||
source/Region.cpp
|
source/Region.cpp
|
||||||
source/VertexTypes.cpp
|
source/VertexTypes.cpp
|
||||||
source/VoxelFilters.cpp
|
source/VoxelFilters.cpp
|
||||||
|
@ -24,7 +24,10 @@ freely, subject to the following restrictions:
|
|||||||
#ifndef __PolyVox_MeshDecimator_H__
|
#ifndef __PolyVox_MeshDecimator_H__
|
||||||
#define __PolyVox_MeshDecimator_H__
|
#define __PolyVox_MeshDecimator_H__
|
||||||
|
|
||||||
|
#include "Vector.h"
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
@ -64,7 +67,7 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
//Used to keep track of when a vertex is
|
//Used to keep track of when a vertex is
|
||||||
//on one or more faces of the region
|
//on one or more faces of the region
|
||||||
enum POLYVOXCORE_API RegionFaceFlags
|
enum RegionFaceFlags
|
||||||
{
|
{
|
||||||
RFF_ON_REGION_FACE_NEG_X,
|
RFF_ON_REGION_FACE_NEG_X,
|
||||||
RFF_ON_REGION_FACE_POS_X ,
|
RFF_ON_REGION_FACE_POS_X ,
|
||||||
|
@ -116,131 +116,6 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
|
||||||
void MeshDecimator<PositionMaterial>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
|
|
||||||
{
|
|
||||||
vecVertexMetadata.clear();
|
|
||||||
vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
|
|
||||||
//Initialise the metadata
|
|
||||||
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
|
||||||
{
|
|
||||||
vecVertexMetadata[ct].normal.setElements(0,0,0);
|
|
||||||
vecVertexMetadata[ct].isOnMaterialEdge = false;
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Identify duplicate vertices, as they lie on the material edge. To do this we convert into integers and sort
|
|
||||||
//(first on z, then y, then x). They should be mostly in order as this is the order they come out of the
|
|
||||||
//CubicSurfaceExtractor in. Duplicates are now neighbours in the resulting list so just scan through for pairs.
|
|
||||||
std::vector<IntVertex> intVertices;
|
|
||||||
intVertices.reserve(m_pOutputMesh->m_vecVertices.size());
|
|
||||||
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
|
||||||
{
|
|
||||||
const Vector3DFloat& floatPos = m_pOutputMesh->m_vecVertices[ct].position;
|
|
||||||
IntVertex intVertex(static_cast<uint32_t>(floatPos.getX()), static_cast<uint32_t>(floatPos.getY()), static_cast<uint32_t>(floatPos.getZ()), ct);
|
|
||||||
intVertices.push_back(intVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Do the sorting so that duplicate become neighbours
|
|
||||||
sort(intVertices.begin(), intVertices.end());
|
|
||||||
|
|
||||||
//Find neighbours which are duplicates.
|
|
||||||
for(int ct = 0; ct < intVertices.size() - 1; ct++)
|
|
||||||
{
|
|
||||||
const IntVertex& v0 = intVertices[ct+0];
|
|
||||||
const IntVertex& v1 = intVertices[ct+1];
|
|
||||||
|
|
||||||
if((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z))
|
|
||||||
{
|
|
||||||
vecVertexMetadata[v0.index].isOnMaterialEdge = true;
|
|
||||||
vecVertexMetadata[v1.index].isOnMaterialEdge = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Compute an approcimation to the normal, used when deciding if an edge can collapse.
|
|
||||||
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
|
||||||
{
|
|
||||||
Vector3DFloat sumOfNormals(0.0f,0.0f,0.0f);
|
|
||||||
for(vector<uint32_t>::const_iterator iter = trianglesUsingVertex[ct].cbegin(); iter != trianglesUsingVertex[ct].cend(); iter++)
|
|
||||||
{
|
|
||||||
sumOfNormals += m_vecTriangles[*iter].normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
vecVertexMetadata[ct].normal = sumOfNormals;
|
|
||||||
vecVertexMetadata[ct].normal.normalise();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Identify those vertices on the edge of a region. Care will need to be taken when moving them.
|
|
||||||
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
|
||||||
{
|
|
||||||
Region regTransformed = m_pOutputMesh->m_Region;
|
|
||||||
regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int16_t>(-1));
|
|
||||||
|
|
||||||
//Plus and minus X
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
|
|
||||||
//Plus and minus Y
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
|
|
||||||
//Plus and minus Z
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void MeshDecimator<PositionMaterialNormal>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
|
|
||||||
{
|
|
||||||
vecVertexMetadata.clear();
|
|
||||||
vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
|
|
||||||
|
|
||||||
//Initialise the metadata
|
|
||||||
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
|
||||||
{
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.reset();
|
|
||||||
vecVertexMetadata[ct].isOnMaterialEdge = false;
|
|
||||||
vecVertexMetadata[ct].normal = m_pOutputMesh->m_vecVertices[ct].normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Identify those vertices on the edge of a region. Care will need to be taken when moving them.
|
|
||||||
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
|
||||||
{
|
|
||||||
Region regTransformed = m_pOutputMesh->m_Region;
|
|
||||||
regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int16_t>(-1));
|
|
||||||
|
|
||||||
//Plus and minus X
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
|
|
||||||
//Plus and minus Y
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
|
|
||||||
//Plus and minus Z
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
|
|
||||||
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//If all three vertices have the same material then we are not on a material edge. If any vertex has a different
|
|
||||||
//material then all three vertices are on a material edge. E.g. If one vertex has material 'a' and the other two
|
|
||||||
//have material 'b', then the two 'b's are still on an edge (with 'a') even though they are the same as eachother.
|
|
||||||
for(int ct = 0; ct < m_vecTriangles.size(); ct++)
|
|
||||||
{
|
|
||||||
uint32_t v0 = m_vecTriangles[ct].v0;
|
|
||||||
uint32_t v1 = m_vecTriangles[ct].v1;
|
|
||||||
uint32_t v2 = m_vecTriangles[ct].v2;
|
|
||||||
|
|
||||||
bool allMatch =
|
|
||||||
(m_pOutputMesh->m_vecVertices[v0].material == m_pOutputMesh->m_vecVertices[v1].material) &&
|
|
||||||
(m_pOutputMesh->m_vecVertices[v1].material == m_pOutputMesh->m_vecVertices[v2].material);
|
|
||||||
|
|
||||||
if(!allMatch)
|
|
||||||
{
|
|
||||||
vecVertexMetadata[v0].isOnMaterialEdge = true;
|
|
||||||
vecVertexMetadata[v1].isOnMaterialEdge = true;
|
|
||||||
vecVertexMetadata[v2].isOnMaterialEdge = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
uint32_t MeshDecimator<VertexType>::performDecimationPass(float m_fMinDotProductForCollapse)
|
uint32_t MeshDecimator<VertexType>::performDecimationPass(float m_fMinDotProductForCollapse)
|
||||||
{
|
{
|
||||||
@ -349,32 +224,6 @@ namespace PolyVox
|
|||||||
return bCanCollapse;
|
return bCanCollapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
|
||||||
bool MeshDecimator<PositionMaterialNormal>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
|
|
||||||
{
|
|
||||||
if(m_vecInitialVertexMetadata[uSrc].normal.dot(m_vecInitialVertexMetadata[uDst].normal) < m_fMinDotProductForCollapse)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//With the marching cubes surface we honour the user specified threshold
|
|
||||||
return !collapseChangesFaceNormals(uSrc, uDst, m_fMinDotProductForCollapse);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool MeshDecimator<PositionMaterial>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
|
|
||||||
{
|
|
||||||
//We don't actually use the normal here, because we want to allow face
|
|
||||||
//vertices to collapse onto edge vertices. Simply checking whether anything
|
|
||||||
//has flipped has proved to be the most robust approach, though rather slow.
|
|
||||||
//It's not sufficient to just check the normals, there can be holes in the middle
|
|
||||||
//of the mesh for example.
|
|
||||||
|
|
||||||
//User specified threshold is not used for cubic surface, any
|
|
||||||
//movement is too much (but allow for floating point error).
|
|
||||||
return !collapseChangesFaceNormals(uSrc, uDst, 0.999f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
bool MeshDecimator<VertexType>::canCollapseRegionEdge(uint32_t uSrc, uint32_t uDst)
|
bool MeshDecimator<VertexType>::canCollapseRegionEdge(uint32_t uSrc, uint32_t uDst)
|
||||||
{
|
{
|
||||||
|
157
library/PolyVoxCore/source/MeshDecimator.cpp
Normal file
157
library/PolyVoxCore/source/MeshDecimator.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#include "MeshDecimator.h"
|
||||||
|
|
||||||
|
#include "SurfaceMesh.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
POLYVOXCORE_API void MeshDecimator<PositionMaterial>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
|
||||||
|
{
|
||||||
|
vecVertexMetadata.clear();
|
||||||
|
vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
|
||||||
|
//Initialise the metadata
|
||||||
|
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
||||||
|
{
|
||||||
|
vecVertexMetadata[ct].normal.setElements(0,0,0);
|
||||||
|
vecVertexMetadata[ct].isOnMaterialEdge = false;
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Identify duplicate vertices, as they lie on the material edge. To do this we convert into integers and sort
|
||||||
|
//(first on z, then y, then x). They should be mostly in order as this is the order they come out of the
|
||||||
|
//CubicSurfaceExtractor in. Duplicates are now neighbours in the resulting list so just scan through for pairs.
|
||||||
|
std::vector<IntVertex> intVertices;
|
||||||
|
intVertices.reserve(m_pOutputMesh->m_vecVertices.size());
|
||||||
|
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
||||||
|
{
|
||||||
|
const Vector3DFloat& floatPos = m_pOutputMesh->m_vecVertices[ct].position;
|
||||||
|
IntVertex intVertex(static_cast<uint32_t>(floatPos.getX()), static_cast<uint32_t>(floatPos.getY()), static_cast<uint32_t>(floatPos.getZ()), ct);
|
||||||
|
intVertices.push_back(intVertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Do the sorting so that duplicate become neighbours
|
||||||
|
sort(intVertices.begin(), intVertices.end());
|
||||||
|
|
||||||
|
//Find neighbours which are duplicates.
|
||||||
|
for(int ct = 0; ct < intVertices.size() - 1; ct++)
|
||||||
|
{
|
||||||
|
const IntVertex& v0 = intVertices[ct+0];
|
||||||
|
const IntVertex& v1 = intVertices[ct+1];
|
||||||
|
|
||||||
|
if((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z))
|
||||||
|
{
|
||||||
|
vecVertexMetadata[v0.index].isOnMaterialEdge = true;
|
||||||
|
vecVertexMetadata[v1.index].isOnMaterialEdge = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compute an approcimation to the normal, used when deciding if an edge can collapse.
|
||||||
|
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
||||||
|
{
|
||||||
|
Vector3DFloat sumOfNormals(0.0f,0.0f,0.0f);
|
||||||
|
for(vector<uint32_t>::const_iterator iter = trianglesUsingVertex[ct].cbegin(); iter != trianglesUsingVertex[ct].cend(); iter++)
|
||||||
|
{
|
||||||
|
sumOfNormals += m_vecTriangles[*iter].normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
vecVertexMetadata[ct].normal = sumOfNormals;
|
||||||
|
vecVertexMetadata[ct].normal.normalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Identify those vertices on the edge of a region. Care will need to be taken when moving them.
|
||||||
|
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
||||||
|
{
|
||||||
|
Region regTransformed = m_pOutputMesh->m_Region;
|
||||||
|
regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int16_t>(-1));
|
||||||
|
|
||||||
|
//Plus and minus X
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
|
||||||
|
//Plus and minus Y
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
|
||||||
|
//Plus and minus Z
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
POLYVOXCORE_API void MeshDecimator<PositionMaterialNormal>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
|
||||||
|
{
|
||||||
|
vecVertexMetadata.clear();
|
||||||
|
vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
|
||||||
|
|
||||||
|
//Initialise the metadata
|
||||||
|
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
||||||
|
{
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.reset();
|
||||||
|
vecVertexMetadata[ct].isOnMaterialEdge = false;
|
||||||
|
vecVertexMetadata[ct].normal = m_pOutputMesh->m_vecVertices[ct].normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Identify those vertices on the edge of a region. Care will need to be taken when moving them.
|
||||||
|
for(int ct = 0; ct < vecVertexMetadata.size(); ct++)
|
||||||
|
{
|
||||||
|
Region regTransformed = m_pOutputMesh->m_Region;
|
||||||
|
regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int16_t>(-1));
|
||||||
|
|
||||||
|
//Plus and minus X
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
|
||||||
|
//Plus and minus Y
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
|
||||||
|
//Plus and minus Z
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
|
||||||
|
vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If all three vertices have the same material then we are not on a material edge. If any vertex has a different
|
||||||
|
//material then all three vertices are on a material edge. E.g. If one vertex has material 'a' and the other two
|
||||||
|
//have material 'b', then the two 'b's are still on an edge (with 'a') even though they are the same as eachother.
|
||||||
|
for(int ct = 0; ct < m_vecTriangles.size(); ct++)
|
||||||
|
{
|
||||||
|
uint32_t v0 = m_vecTriangles[ct].v0;
|
||||||
|
uint32_t v1 = m_vecTriangles[ct].v1;
|
||||||
|
uint32_t v2 = m_vecTriangles[ct].v2;
|
||||||
|
|
||||||
|
bool allMatch =
|
||||||
|
(m_pOutputMesh->m_vecVertices[v0].material == m_pOutputMesh->m_vecVertices[v1].material) &&
|
||||||
|
(m_pOutputMesh->m_vecVertices[v1].material == m_pOutputMesh->m_vecVertices[v2].material);
|
||||||
|
|
||||||
|
if(!allMatch)
|
||||||
|
{
|
||||||
|
vecVertexMetadata[v0].isOnMaterialEdge = true;
|
||||||
|
vecVertexMetadata[v1].isOnMaterialEdge = true;
|
||||||
|
vecVertexMetadata[v2].isOnMaterialEdge = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
POLYVOXCORE_API bool MeshDecimator<PositionMaterialNormal>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
|
||||||
|
{
|
||||||
|
if(m_vecInitialVertexMetadata[uSrc].normal.dot(m_vecInitialVertexMetadata[uDst].normal) < m_fMinDotProductForCollapse)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//With the marching cubes surface we honour the user specified threshold
|
||||||
|
return !collapseChangesFaceNormals(uSrc, uDst, m_fMinDotProductForCollapse);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
POLYVOXCORE_API bool MeshDecimator<PositionMaterial>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
|
||||||
|
{
|
||||||
|
//We don't actually use the normal here, because we want to allow face
|
||||||
|
//vertices to collapse onto edge vertices. Simply checking whether anything
|
||||||
|
//has flipped has proved to be the most robust approach, though rather slow.
|
||||||
|
//It's not sufficient to just check the normals, there can be holes in the middle
|
||||||
|
//of the mesh for example.
|
||||||
|
|
||||||
|
//User specified threshold is not used for cubic surface, any
|
||||||
|
//movement is too much (but allow for floating point error).
|
||||||
|
return !collapseChangesFaceNormals(uSrc, uDst, 0.999f);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user