From 2f5f1798864c50ad69abe56d553a27d57e07045c Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 21 Sep 2007 12:54:11 +0000 Subject: [PATCH] Work on mesh decimation. --- include/SurfacePatch.h | 3 +- source/SurfacePatch.cpp | 85 +++++++++++++++++++++++++++++-------- source/VolumeSerializer.cpp | 2 +- 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/include/SurfacePatch.h b/include/SurfacePatch.h index a21692e1..c7fdb8e7 100644 --- a/include/SurfacePatch.h +++ b/include/SurfacePatch.h @@ -57,7 +57,8 @@ namespace Ogre #endif bool canRemoveVertex(SurfaceVertexIterator vertexIter); - std::list findConnectedVertices(SurfaceVertexIterator vertexIter); + bool canRemoveVertexFrom(SurfaceVertexIterator vertexIter, std::list listConnectedIter, bool isEdge); + std::list findConnectedVertices(SurfaceVertexIterator vertexIter, bool& isEdge); std::list removeTrianglesAndFindEdges(SurfaceVertexIterator vertexIter); bool decimate3(void); diff --git a/source/SurfacePatch.cpp b/source/SurfacePatch.cpp index 53c05d80..8e8046e7 100644 --- a/source/SurfacePatch.cpp +++ b/source/SurfacePatch.cpp @@ -47,17 +47,17 @@ namespace Ogre void SurfacePatch::addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2) { - if(v0.position.x > 8) + if(v0.position.x > 16) return; - if(v0.position.y > 8) + if(v0.position.y > 16) return; - if(v1.position.x > 8) + if(v1.position.x > 16) return; - if(v1.position.y > 8) + if(v1.position.y > 16) return; - if(v2.position.x > 8) + if(v2.position.x > 16) return; - if(v2.position.y > 8) + if(v2.position.y > 16) return; @@ -388,8 +388,55 @@ namespace Ogre return allXMatch || allYMatch || allZMatch; } - std::list SurfacePatch::findConnectedVertices(SurfaceVertexIterator vertexIter) + bool SurfacePatch::canRemoveVertexFrom(SurfaceVertexIterator vertexIter, std::list listConnectedIter, bool isEdge) { + bool allXMatch = true; + bool allYMatch = true; + bool allZMatch = true; + bool allNormalsMatch = true; + bool twoEdgesMatch = true; + + for(std::list::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 SurfacePatch::findConnectedVertices(SurfaceVertexIterator vertexIter, bool& isEdge) + { + isEdge = false; std::list result; //LogManager::getSingleton().logMessage("findConnectedVertices " + vertexIter->toString()); @@ -418,6 +465,8 @@ namespace Ogre //LogManager::getSingleton().logMessage("Is edge"); //In this case vertexIter is on an edge/ + isEdge = true; + nextEdge = firstEdge; previousEdge = firstEdge; @@ -525,27 +574,27 @@ namespace Ogre //int movable = 0; for(SurfaceVertexIterator vertexIter = m_listVertices.begin(); vertexIter != m_listVertices.end(); ++vertexIter) { - LogManager::getSingleton().logMessage("Examining vertex " + vertexIter->toString()); - if(canRemoveVertex(vertexIter) == false) - { - continue; - } - LogManager::getSingleton().logMessage("Vertex can be removed"); + LogManager::getSingleton().logMessage("Examining vertex " + vertexIter->toString()); - std::list listConnectedVertices = findConnectedVertices(vertexIter); + bool isEdge; + std::list listConnectedVertices = findConnectedVertices(vertexIter,isEdge); listConnectedVertices.remove(vertexIter); listConnectedVertices.unique(); - - SurfaceEdgeIterator firstEdge = vertexIter->edge; - SurfaceEdgeIterator nextEdge = firstEdge; - LogManager::getSingleton().logMessage("No of connected vertices = " + StringConverter::toString(listConnectedVertices.size())); for(std::list::iterator iter = listConnectedVertices.begin(); iter != listConnectedVertices.end(); ++iter) { 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; std::list edgesToRemove = removeTrianglesAndFindEdges(vertexIter); /*do diff --git a/source/VolumeSerializer.cpp b/source/VolumeSerializer.cpp index a65c2db2..0e367f6e 100644 --- a/source/VolumeSerializer.cpp +++ b/source/VolumeSerializer.cpp @@ -70,7 +70,7 @@ namespace Ogre 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. if(z%OGRE_BLOCK_SIDE_LENGTH == OGRE_BLOCK_SIDE_LENGTH-1)