Work on mesh decimation.

This commit is contained in:
David Williams 2007-09-21 12:54:11 +00:00
parent d467a3a314
commit 2f5f179886
3 changed files with 70 additions and 20 deletions

View File

@ -57,7 +57,8 @@ namespace Ogre
#endif #endif
bool canRemoveVertex(SurfaceVertexIterator vertexIter); bool canRemoveVertex(SurfaceVertexIterator vertexIter);
std::list<SurfaceVertexIterator> findConnectedVertices(SurfaceVertexIterator vertexIter); bool canRemoveVertexFrom(SurfaceVertexIterator vertexIter, std::list<SurfaceVertexIterator> listConnectedIter, bool isEdge);
std::list<SurfaceVertexIterator> findConnectedVertices(SurfaceVertexIterator vertexIter, bool& isEdge);
std::list<SurfaceEdgeIterator> removeTrianglesAndFindEdges(SurfaceVertexIterator vertexIter); std::list<SurfaceEdgeIterator> removeTrianglesAndFindEdges(SurfaceVertexIterator vertexIter);
bool decimate3(void); bool decimate3(void);

View File

@ -47,17 +47,17 @@ namespace Ogre
void SurfacePatch::addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2) void SurfacePatch::addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2)
{ {
if(v0.position.x > 8) if(v0.position.x > 16)
return; return;
if(v0.position.y > 8) if(v0.position.y > 16)
return; return;
if(v1.position.x > 8) if(v1.position.x > 16)
return; return;
if(v1.position.y > 8) if(v1.position.y > 16)
return; return;
if(v2.position.x > 8) if(v2.position.x > 16)
return; return;
if(v2.position.y > 8) if(v2.position.y > 16)
return; return;
@ -388,8 +388,55 @@ namespace Ogre
return allXMatch || allYMatch || allZMatch; return allXMatch || allYMatch || allZMatch;
} }
std::list<SurfaceVertexIterator> SurfacePatch::findConnectedVertices(SurfaceVertexIterator vertexIter) bool SurfacePatch::canRemoveVertexFrom(SurfaceVertexIterator vertexIter, std::list<SurfaceVertexIterator> listConnectedIter, bool isEdge)
{ {
bool allXMatch = true;
bool allYMatch = true;
bool allZMatch = true;
bool allNormalsMatch = true;
bool twoEdgesMatch = true;
for(std::list<SurfaceVertexIterator>::iterator connectedIter = listConnectedIter.begin(); connectedIter != listConnectedIter.end(); ++connectedIter)
{
if((*connectedIter)->position.x != vertexIter->position.x)
{
allXMatch = false;
}
if((*connectedIter)->position.y != vertexIter->position.y)
{
allYMatch = false;
}
if((*connectedIter)->position.z != vertexIter->position.z)
{
allZMatch = false;
}
//FIXME - already normalised?
if((*connectedIter)->normal.normalisedCopy().dotProduct(vertexIter->normal.normalisedCopy()) < 0.99)
{
return false;
}
}
if(isEdge)
{
SurfaceVertexIterator firstExtreme = *(listConnectedIter.begin());
SurfaceVertexIterator secondExtreme = *(--listConnectedIter.end());
bool edgeXMatch = (firstExtreme->position.x == vertexIter->position.x) && (secondExtreme->position.x == vertexIter->position.x);
bool edgeYMatch = (firstExtreme->position.y == vertexIter->position.y) && (secondExtreme->position.y == vertexIter->position.y);
bool edgeZMatch = (firstExtreme->position.z == vertexIter->position.z) && (secondExtreme->position.z == vertexIter->position.z);
twoEdgesMatch = ((edgeXMatch&&edgeYMatch) || (edgeXMatch&&edgeZMatch) || (edgeYMatch&&edgeZMatch));
}
return (allXMatch || allYMatch || allZMatch)
&& (twoEdgesMatch);
}
std::list<SurfaceVertexIterator> SurfacePatch::findConnectedVertices(SurfaceVertexIterator vertexIter, bool& isEdge)
{
isEdge = false;
std::list<SurfaceVertexIterator> result; std::list<SurfaceVertexIterator> result;
//LogManager::getSingleton().logMessage("findConnectedVertices " + vertexIter->toString()); //LogManager::getSingleton().logMessage("findConnectedVertices " + vertexIter->toString());
@ -418,6 +465,8 @@ namespace Ogre
//LogManager::getSingleton().logMessage("Is edge"); //LogManager::getSingleton().logMessage("Is edge");
//In this case vertexIter is on an edge/ //In this case vertexIter is on an edge/
isEdge = true;
nextEdge = firstEdge; nextEdge = firstEdge;
previousEdge = firstEdge; previousEdge = firstEdge;
@ -526,26 +575,26 @@ namespace Ogre
for(SurfaceVertexIterator vertexIter = m_listVertices.begin(); vertexIter != m_listVertices.end(); ++vertexIter) for(SurfaceVertexIterator vertexIter = m_listVertices.begin(); vertexIter != m_listVertices.end(); ++vertexIter)
{ {
LogManager::getSingleton().logMessage("Examining vertex " + vertexIter->toString()); LogManager::getSingleton().logMessage("Examining vertex " + vertexIter->toString());
if(canRemoveVertex(vertexIter) == false)
{
continue;
}
LogManager::getSingleton().logMessage("Vertex can be removed");
std::list<SurfaceVertexIterator> listConnectedVertices = findConnectedVertices(vertexIter); bool isEdge;
std::list<SurfaceVertexIterator> listConnectedVertices = findConnectedVertices(vertexIter,isEdge);
listConnectedVertices.remove(vertexIter); listConnectedVertices.remove(vertexIter);
listConnectedVertices.unique(); listConnectedVertices.unique();
SurfaceEdgeIterator firstEdge = vertexIter->edge;
SurfaceEdgeIterator nextEdge = firstEdge;
LogManager::getSingleton().logMessage("No of connected vertices = " + StringConverter::toString(listConnectedVertices.size())); LogManager::getSingleton().logMessage("No of connected vertices = " + StringConverter::toString(listConnectedVertices.size()));
for(std::list<SurfaceVertexIterator>::iterator iter = listConnectedVertices.begin(); iter != listConnectedVertices.end(); ++iter) for(std::list<SurfaceVertexIterator>::iterator iter = listConnectedVertices.begin(); iter != listConnectedVertices.end(); ++iter)
{ {
LogManager::getSingleton().logMessage(" Connected vertex = " + (*iter)->toString()); LogManager::getSingleton().logMessage(" Connected vertex = " + (*iter)->toString());
} }
if(canRemoveVertexFrom(vertexIter, listConnectedVertices, isEdge) == false)
{
continue;
}
LogManager::getSingleton().logMessage("Vertex can be removed");
SurfaceEdgeIterator firstEdge = vertexIter->edge;
SurfaceEdgeIterator nextEdge = firstEdge;
nextEdge = firstEdge; nextEdge = firstEdge;
std::list<SurfaceEdgeIterator> edgesToRemove = removeTrianglesAndFindEdges(vertexIter); std::list<SurfaceEdgeIterator> edgesToRemove = removeTrianglesAndFindEdges(vertexIter);
/*do /*do

View File

@ -70,7 +70,7 @@ namespace Ogre
volIter.setVoxelAt(x,y,z,0); volIter.setVoxelAt(x,y,z,0);
} }
} }
volIter.setVoxelAt(130,130,23,0); //volIter.setVoxelAt(130,130,23,0);
//Periodically see if we can tidy the memory to avoid excessive usage during loading. //Periodically see if we can tidy the memory to avoid excessive usage during loading.
if(z%OGRE_BLOCK_SIDE_LENGTH == OGRE_BLOCK_SIDE_LENGTH-1) if(z%OGRE_BLOCK_SIDE_LENGTH == OGRE_BLOCK_SIDE_LENGTH-1)