Optimisations to the MeshDecimator.
This commit is contained in:
parent
149dde9460
commit
2b70409baa
@ -92,6 +92,48 @@ namespace PolyVox
|
||||
uint32_t v2;
|
||||
Vector3DFloat normal;
|
||||
};
|
||||
|
||||
struct IntVertex
|
||||
{
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
uint32_t index;
|
||||
|
||||
IntVertex(int32_t xVal, int32_t yVal, int32_t zVal, uint32_t indexVal)
|
||||
:x(xVal)
|
||||
,y(yVal)
|
||||
,z(zVal)
|
||||
,index(indexVal)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const IntVertex& rhs) const
|
||||
{
|
||||
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
|
||||
}
|
||||
|
||||
bool operator<(const IntVertex& rhs) const
|
||||
{
|
||||
if (z < rhs.z)
|
||||
return true;
|
||||
if (rhs.z < z)
|
||||
return false;
|
||||
|
||||
if (y < rhs.y)
|
||||
return true;
|
||||
if (rhs.y < y)
|
||||
return false;
|
||||
|
||||
if (x < rhs.x)
|
||||
return true;
|
||||
if (rhs.x < x)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
///Constructor
|
||||
MeshDecimator(const SurfaceMesh<VertexType>* pInputMesh, SurfaceMesh<VertexType>* pOutputMesh, float fEdgeCollapseThreshold = 0.95f);
|
||||
@ -125,7 +167,7 @@ namespace PolyVox
|
||||
std::vector<uint32_t> vertexMapper;
|
||||
|
||||
std::vector<Triangle> m_vecTriangles;
|
||||
std::vector< list<uint32_t> > trianglesUsingVertex; //Should probably use vector of vectors, and resise in advance.
|
||||
std::vector< std::vector<uint32_t> > trianglesUsingVertex; //Should probably use vector of vectors, and resise in advance.
|
||||
|
||||
std::vector<InitialVertexMetadata> m_vecInitialVertexMetadata;
|
||||
|
||||
|
@ -104,6 +104,10 @@ namespace PolyVox
|
||||
//For each vertex, determine which triangles are using it.
|
||||
trianglesUsingVertex.clear();
|
||||
trianglesUsingVertex.resize(m_pOutputMesh->m_vecVertices.size());
|
||||
for(int ct = 0; ct < trianglesUsingVertex.size(); ct++)
|
||||
{
|
||||
trianglesUsingVertex[ct].reserve(6);
|
||||
}
|
||||
for(int ct = 0; ct < m_vecTriangles.size(); ct++)
|
||||
{
|
||||
trianglesUsingVertex[m_vecTriangles[ct].v0].push_back(ct);
|
||||
@ -125,19 +129,31 @@ namespace PolyVox
|
||||
vecVertexMetadata[ct].isOnRegionFace.reset();
|
||||
}
|
||||
|
||||
//Identify duplicate vertices, as they lie on the material edge. Note that this is a particularly slow way of
|
||||
//findong the duplicates. Better to hash into integer (with upper bits being z and lower bits being x) and sort
|
||||
//the resulting integers. The should be mostly in order as this is the order they come out of the
|
||||
//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.
|
||||
for(int outerCt = 0; outerCt < m_pOutputMesh->m_vecVertices.size()-1; outerCt++)
|
||||
std::vector<IntVertex> intVertices;
|
||||
intVertices.reserve(m_pOutputMesh->m_vecVertices.size());
|
||||
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
||||
{
|
||||
for(int innerCt = outerCt+1; innerCt < m_pOutputMesh->m_vecVertices.size(); innerCt++)
|
||||
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))
|
||||
{
|
||||
if((m_pOutputMesh->m_vecVertices[innerCt].position - m_pOutputMesh->m_vecVertices[outerCt].position).lengthSquared() < 0.001f)
|
||||
{
|
||||
vecVertexMetadata[innerCt].isOnMaterialEdge = true;
|
||||
vecVertexMetadata[outerCt].isOnMaterialEdge = true;
|
||||
}
|
||||
vecVertexMetadata[v0.index].isOnMaterialEdge = true;
|
||||
vecVertexMetadata[v1.index].isOnMaterialEdge = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +161,7 @@ namespace PolyVox
|
||||
for(int ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
|
||||
{
|
||||
Vector3DFloat sumOfNormals(0.0f,0.0f,0.0f);
|
||||
for(list<uint32_t>::const_iterator iter = trianglesUsingVertex[ct].cbegin(); iter != trianglesUsingVertex[ct].cend(); iter++)
|
||||
for(vector<uint32_t>::const_iterator iter = trianglesUsingVertex[ct].cbegin(); iter != trianglesUsingVertex[ct].cend(); iter++)
|
||||
{
|
||||
sumOfNormals += m_vecTriangles[*iter].normal;
|
||||
}
|
||||
@ -392,15 +408,15 @@ namespace PolyVox
|
||||
bool MeshDecimator<VertexType>::collapseChangesFaceNormals(uint32_t uSrc, uint32_t uDst, float fThreshold)
|
||||
{
|
||||
bool faceFlipped = false;
|
||||
list<uint32_t>& triangles = trianglesUsingVertex[uSrc];
|
||||
vector<uint32_t>& triangles = trianglesUsingVertex[uSrc];
|
||||
|
||||
for(list<uint32_t>::iterator triIter = triangles.begin(); triIter != triangles.end(); triIter++)
|
||||
for(vector<uint32_t>::iterator triIter = triangles.begin(); triIter != triangles.end(); triIter++)
|
||||
{
|
||||
uint32_t tri = *triIter;
|
||||
|
||||
uint32_t v0Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3];
|
||||
uint32_t v1Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3 + 1];
|
||||
uint32_t v2Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3 + 2];
|
||||
const uint32_t& v0Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3];
|
||||
const uint32_t& v1Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3 + 1];
|
||||
const uint32_t& v2Old = m_pOutputMesh->m_vecTriangleIndices[tri * 3 + 2];
|
||||
|
||||
//Check if degenerate
|
||||
if((v0Old == v1Old) || (v1Old == v2Old) || (v2Old == v0Old))
|
||||
@ -425,13 +441,13 @@ namespace PolyVox
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3DFloat v0OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v0Old]].getPosition(); //Note: we need the vertex mapper here. These neighbouring vertices may have been moved.
|
||||
Vector3DFloat v1OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v1Old]].getPosition();
|
||||
Vector3DFloat v2OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v2Old]].getPosition();
|
||||
const Vector3DFloat& v0OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v0Old]].getPosition(); //Note: we need the vertex mapper here. These neighbouring vertices may have been moved.
|
||||
const Vector3DFloat& v1OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v1Old]].getPosition();
|
||||
const Vector3DFloat& v2OldPos = m_pOutputMesh->m_vecVertices[vertexMapper[v2Old]].getPosition();
|
||||
|
||||
Vector3DFloat v0NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v0New]].getPosition();
|
||||
Vector3DFloat v1NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v1New]].getPosition();
|
||||
Vector3DFloat v2NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v2New]].getPosition();
|
||||
const Vector3DFloat& v0NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v0New]].getPosition();
|
||||
const Vector3DFloat& v1NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v1New]].getPosition();
|
||||
const Vector3DFloat& v2NewPos = m_pOutputMesh->m_vecVertices[vertexMapper[v2New]].getPosition();
|
||||
|
||||
Vector3DFloat OldNormal = (v1OldPos - v0OldPos).cross(v2OldPos - v1OldPos);
|
||||
Vector3DFloat NewNormal = (v1NewPos - v0NewPos).cross(v2NewPos - v1NewPos);
|
||||
|
Loading…
x
Reference in New Issue
Block a user