From 80c6f149a55e92594958ccdd1e81cd537868afbb Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 2 Sep 2007 11:16:58 +0000 Subject: [PATCH] Refactoring work... working on meshes --- include/SurfacePatch.h | 14 ++++- include/SurfaceTriangle.h | 26 +++++---- include/SurfaceVertex.h | 22 ++++--- source/PolyVoxSceneManager.cpp | 2 + source/SurfacePatch.cpp | 103 ++++++++++++++++++++++++++++++--- source/SurfaceTriangle.cpp | 35 ++++++++++- source/SurfaceVertex.cpp | 23 ++++++-- 7 files changed, 188 insertions(+), 37 deletions(-) diff --git a/include/SurfacePatch.h b/include/SurfacePatch.h index 394d26e9..4f13cf1e 100644 --- a/include/SurfacePatch.h +++ b/include/SurfacePatch.h @@ -4,8 +4,7 @@ #include #include -#include "SurfaceVertex.h" -#include "SurfaceTriangle.h" +#include "IntegralVector3.h" #include "VolumeIterator.h" @@ -19,6 +18,11 @@ namespace Ogre SOBEL }; + class SurfaceVertex; + typedef std::set::iterator SurfaceVertexIterator; + class SurfaceTriangle; + typedef std::set::iterator SurfaceTriangleIterator; + class SurfacePatch { public: @@ -34,11 +38,15 @@ namespace Ogre void computeNormalsFromVolume(VolumeIterator volIter); + void decimate(void); + + //bool verticesArePlanar(SurfaceVertexIterator iterCurrentVertex); + UIntVector3 m_v3dOffset; private: std::set m_setVertices; - std::list m_listTriangles; + std::set m_setTriangles; //std::vector m_vecVertexData; //std::vector m_vecIndexData; diff --git a/include/SurfaceTriangle.h b/include/SurfaceTriangle.h index 25d32802..b925d12d 100644 --- a/include/SurfaceTriangle.h +++ b/include/SurfaceTriangle.h @@ -22,30 +22,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "OgrePrerequisites.h" -#include "OgreVector3.h" - namespace Ogre { class SurfaceVertex; + typedef std::set::iterator SurfaceVertexIterator; + class SurfaceTriangle; + typedef std::set::iterator SurfaceTriangleIterator; class SurfaceTriangle { public: - //FIXME - maybe these should be short? - /*ulong v0; - ulong v1; - ulong v2;*/ - std::set::iterator v0; - std::set::iterator v1; - std::set::iterator v2; + SurfaceVertexIterator v0; + SurfaceVertexIterator v1; + SurfaceVertexIterator v2; SurfaceTriangle(); - SurfaceTriangle(std::set::iterator v0ToSet, std::set::iterator v1ToSet, std::set::iterator v2ToSet); - - //bool operator < (const SurfaceTriangle& rhs) const; + SurfaceTriangle(SurfaceVertexIterator v0ToSet, SurfaceVertexIterator v1ToSet, SurfaceVertexIterator v2ToSet); }; + + typedef std::set::iterator SurfaceTriangleIterator; + + bool operator == (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs); + bool operator < (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs); + + //bool operator < (const SurfaceTriangleIterator& lhs, const SurfaceTriangleIterator& rhs); } #endif diff --git a/include/SurfaceVertex.h b/include/SurfaceVertex.h index 0f3c599c..83c5d4bc 100644 --- a/include/SurfaceVertex.h +++ b/include/SurfaceVertex.h @@ -26,28 +26,34 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "IntegralVector3.h" namespace Ogre -{ +{ + class SurfaceVertex; + typedef std::set::iterator SurfaceVertexIterator; class SurfaceTriangle; + typedef std::set::iterator SurfaceTriangleIterator; class SurfaceVertex { - public: + public: UIntVector3 position; Vector3 normal; float alpha; - std::list::iterator> listTrianglesUsingThisVertex; + std::list listTrianglesUsingThisVertex; + std::list listConnectedVertices; SurfaceVertex(); SurfaceVertex(UIntVector3 positionToSet); - SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet); - - bool operator==(const SurfaceVertex& rhs) const; - - bool operator < (const SurfaceVertex& rhs) const; + SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet); }; + + bool operator==(const SurfaceVertex& lhs, const SurfaceVertex& rhs); + bool operator < (const SurfaceVertex& lhs, const SurfaceVertex& rhs); + + + //bool operator < (const SurfaceVertexIterator& lhs, const SurfaceVertexIterator& rhs); } #endif diff --git a/source/PolyVoxSceneManager.cpp b/source/PolyVoxSceneManager.cpp index 658323bb..cbef386c 100644 --- a/source/PolyVoxSceneManager.cpp +++ b/source/PolyVoxSceneManager.cpp @@ -1008,6 +1008,7 @@ namespace Ogre iterPatch->second.m_v3dOffset = offset; iterPatch->second.computeNormalsFromVolume(volIter); iterPatch->second.endDefinition(); + //iterPatch->second.decimate(); } //LogManager::getSingleton().logMessage("Finished Generating Mesh Data"); @@ -1133,6 +1134,7 @@ namespace Ogre #endif + bool PolyVoxSceneManager::verticesArePlanar3(uint uCurrentVertex, std::set setConnectedVertices, std::vector& vertexData) const { //FIXME - specially handle the case where they are all the same. diff --git a/source/SurfacePatch.cpp b/source/SurfacePatch.cpp index 71eec583..3bdbac67 100644 --- a/source/SurfacePatch.cpp +++ b/source/SurfacePatch.cpp @@ -1,6 +1,9 @@ #include "SurfacePatch.h" #include "Constants.h" +#include "SurfaceVertex.h" +#include "SurfaceTriangle.h" + #include "OgreLogManager.h" #include "OgreStringConverter.h" @@ -11,7 +14,7 @@ namespace Ogre SurfacePatch::SurfacePatch() { m_setVertices.clear(); - m_listTriangles.clear(); + m_setTriangles.clear(); m_uTrianglesAdded = 0; m_uVerticesAdded = 0; @@ -49,17 +52,17 @@ namespace Ogre triangle.v1 = m_setVertices.insert(v1).first; triangle.v2 = m_setVertices.insert(v2).first; - m_listTriangles.push_back(triangle); + SurfaceTriangleIterator iterTriangle = m_setTriangles.insert(triangle).first; - triangle.v0->listTrianglesUsingThisVertex.push_back(m_listTriangles.end()); - triangle.v1->listTrianglesUsingThisVertex.push_back(m_listTriangles.end()); - triangle.v2->listTrianglesUsingThisVertex.push_back(m_listTriangles.end()); + triangle.v0->listTrianglesUsingThisVertex.push_back(iterTriangle); + triangle.v1->listTrianglesUsingThisVertex.push_back(iterTriangle); + triangle.v2->listTrianglesUsingThisVertex.push_back(iterTriangle); } void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter) { //LogManager::getSingleton().logMessage("In SurfacePatch::computeNormalsFromVolume"); - for(std::set::iterator vertexIter = m_setVertices.begin(); vertexIter != m_setVertices.end(); ++vertexIter) + for(SurfaceVertexIterator vertexIter = m_setVertices.begin(); vertexIter != m_setVertices.end(); ++vertexIter) { //LogManager::getSingleton().logMessage("In Loop"); const float posX = (vertexIter->position.x + m_v3dOffset.x) / 2.0f; @@ -152,7 +155,7 @@ namespace Ogre vertexData.resize(m_setVertices.size()); std::copy(m_setVertices.begin(), m_setVertices.end(), vertexData.begin()); - for(std::list::iterator iterTriangles = m_listTriangles.begin(); iterTriangles != m_listTriangles.end(); ++iterTriangles) + for(SurfaceTriangleIterator iterTriangles = m_setTriangles.begin(); iterTriangles != m_setTriangles.end(); ++iterTriangles) { std::vector::iterator iterVertex; @@ -166,4 +169,90 @@ namespace Ogre indexData.push_back(iterVertex - vertexData.begin()); } } + + void SurfacePatch::decimate(void) + { + //Build the lists of connected vertices + for(SurfaceVertexIterator vertexIter = m_setVertices.begin(); vertexIter != m_setVertices.end(); ++vertexIter) + { + for(std::list::iterator triangleIter = vertexIter->listTrianglesUsingThisVertex.begin(); triangleIter != vertexIter->listTrianglesUsingThisVertex.end(); ++triangleIter) + { + if(find(vertexIter->listConnectedVertices.begin(),vertexIter->listConnectedVertices.end(),(*triangleIter)->v0) == vertexIter->listConnectedVertices.end()) + vertexIter->listConnectedVertices.push_back((*triangleIter)->v0); + if(find(vertexIter->listConnectedVertices.begin(),vertexIter->listConnectedVertices.end(),(*triangleIter)->v1) == vertexIter->listConnectedVertices.end()) + vertexIter->listConnectedVertices.push_back((*triangleIter)->v1); + if(find(vertexIter->listConnectedVertices.begin(),vertexIter->listConnectedVertices.end(),(*triangleIter)->v2) == vertexIter->listConnectedVertices.end()) + vertexIter->listConnectedVertices.push_back((*triangleIter)->v2); + } + } + + //do the vertex merging + for(SurfaceVertexIterator vertexIter = m_setVertices.begin(); vertexIter != m_setVertices.end(); ++vertexIter) + { + if(vertexIter->alpha < 0.9) + continue; + + if(true/*verticesArePlanar(vertexIter)*/) + { + //Find a vertex to merge with + SurfaceVertexIterator vertexToMergeWith = (*(vertexIter->listTrianglesUsingThisVertex.begin()))->v0; + if(vertexIter == vertexToMergeWith) + { + vertexToMergeWith = (*(vertexIter->listTrianglesUsingThisVertex.begin()))->v1; + } + + //Change triangles to use new vertex + for(SurfaceTriangleIterator iterTriangles = m_setTriangles.begin(); iterTriangles != m_setTriangles.end(); ++iterTriangles) + { + if(iterTriangles->v0 == vertexIter) + iterTriangles->v0 = vertexToMergeWith; + if(iterTriangles->v1 == vertexIter) + iterTriangles->v1 = vertexToMergeWith; + if(iterTriangles->v2 == vertexIter) + iterTriangles->v2 = vertexToMergeWith; + } + + //Change connected vertices to use new vertex + } + } + } + + /*bool SurfacePatch::verticesArePlanar(SurfaceVertexIterator iterCurrentVertex) + { + //FIXME - specially handle the case where they are all the same. + //This is happening a lot after many vertices have been moved round? + bool allXMatch = true; + bool allYMatch = true; + bool allZMatch = true; + bool allNormalsMatch = true; + + //FIXME - reorder come of these tests based on likelyness to fail? + + //std::set::iterator iterConnectedVertices; + + std::list listConnectedVertices = iterCurrentVertex->listConnectedVertices; + std::list::iterator iterConnectedVertices; + for(iterConnectedVertices = listConnectedVertices.begin(); iterConnectedVertices != listConnectedVertices.end(); ++iterConnectedVertices) + { + if(iterCurrentVertex->position.x != (*iterConnectedVertices)->position.x) + { + allXMatch = false; + } + if(iterCurrentVertex->position.y != (*iterConnectedVertices)->position.y) + { + allYMatch = false; + } + if(iterCurrentVertex->position.z != (*iterConnectedVertices)->position.z) + { + allZMatch = false; + } + //FIXME - are these already normalised? We should make sure they are... + if(iterCurrentVertex->normal.normalisedCopy().dotProduct((*iterConnectedVertices)->normal.normalisedCopy()) < 0.99) + { + return false; + } + } + + return allXMatch || allYMatch || allZMatch; + }*/ } diff --git a/source/SurfaceTriangle.cpp b/source/SurfaceTriangle.cpp index c173b7b7..7d29b955 100644 --- a/source/SurfaceTriangle.cpp +++ b/source/SurfaceTriangle.cpp @@ -1,4 +1,5 @@ #include "SurfaceTriangle.h" +#include "SurfaceVertex.h" namespace Ogre { @@ -6,10 +7,42 @@ namespace Ogre { } - SurfaceTriangle::SurfaceTriangle(std::set::iterator v0ToSet, std::set::iterator v1ToSet, std::set::iterator v2ToSet) + SurfaceTriangle::SurfaceTriangle(SurfaceVertexIterator v0ToSet, SurfaceVertexIterator v1ToSet, SurfaceVertexIterator v2ToSet) :v0(v0ToSet) ,v1(v1ToSet) ,v2(v2ToSet) { } + + bool operator == (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs) + { + return + ( + (lhs.v0 == rhs.v0) && + (lhs.v1 == rhs.v1) && + (lhs.v2 == rhs.v2) + ); + } + + bool operator < (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs) + { + if(lhs.v0 == rhs.v0) + { + if(lhs.v1 == rhs.v1) + { + if(lhs.v2 == rhs.v2) + { + return false; + } + return (*(lhs.v2) < *(rhs.v2)); + } + return (*(lhs.v1) < *(rhs.v1)); + } + return (*(lhs.v0) < *(rhs.v0)); + } + + /*bool operator < (const SurfaceTriangleIterator& lhs, const SurfaceTriangleIterator& rhs) + { + return (*lhs) < (*rhs); + }*/ } diff --git a/source/SurfaceVertex.cpp b/source/SurfaceVertex.cpp index 8d9835b8..1ecd2bc0 100644 --- a/source/SurfaceVertex.cpp +++ b/source/SurfaceVertex.cpp @@ -18,7 +18,7 @@ namespace Ogre { } - bool SurfaceVertex::operator==(const SurfaceVertex& rhs) const + bool operator==(const SurfaceVertex& lhs, const SurfaceVertex& rhs) { //We dont't check the normal here as it may not have been set. But if two vertices have the same position they should have the same normal too. /*return @@ -45,13 +45,13 @@ namespace Ogre return value == rhsValue;*/ - unsigned long offset = (position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (position.z); + unsigned long lhsOffset = (lhs.position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (lhs.position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (lhs.position.z); unsigned long rhsOffset = (rhs.position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (rhs.position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (rhs.position.z); - return offset == rhsOffset; + return (lhsOffset == rhsOffset) && (abs(lhs.alpha - rhs.alpha) <= 0.01); } - bool SurfaceVertex::operator < (const SurfaceVertex& rhs) const + bool operator < (const SurfaceVertex& lhs, const SurfaceVertex& rhs) { /*if((*this) == rhs) { @@ -92,9 +92,20 @@ namespace Ogre return value < rhsValue;*/ - unsigned long offset = (position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (position.z); + unsigned long lhsOffset = (lhs.position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (lhs.position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (lhs.position.z); unsigned long rhsOffset = (rhs.position.x*(OGRE_REGION_SIDE_LENGTH*2+1)*(OGRE_REGION_SIDE_LENGTH*2+1)) + (rhs.position.y*(OGRE_REGION_SIDE_LENGTH*2+1)) + (rhs.position.z); - return offset < rhsOffset; + return lhsOffset < rhsOffset; + + if(lhsOffset == rhsOffset) + { + return (lhs.alpha < rhs.alpha); + } + return (lhsOffset < rhsOffset); } + + /*bool operator < (const SurfaceVertexIterator& lhs, const SurfaceVertexIterator& rhs) + { + return (*lhs) < (*rhs); + }*/ }