Work on mesh decimation.

This commit is contained in:
David Williams 2007-09-07 23:13:10 +00:00
parent 49846fa5d9
commit c2194378cd
11 changed files with 248 additions and 32 deletions

View File

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __IntegralVector3_H__
#include <OgrePrerequisites.h>
#include <OgreVector3.h>
namespace Ogre
{
@ -55,7 +56,12 @@ namespace Ogre
return (z < rhs.z);
else
return false; //They are equal
}
}
Vector3 toOgreVector3(void)
{
return Vector3(Real(x), Real(y), Real(z));
}
Type x;
Type y;

View File

@ -39,11 +39,18 @@ namespace Ogre
SurfaceTriangleIterator triangle;
SurfaceEdgeIterator previousHalfEdge;
SurfaceEdgeIterator nextHalfEdge;
SurfaceEdgeIterator otherHalfEdge;
//FIXME - could use boost::optional for this?
bool hasOtherHalfEdge;
SurfaceEdge();
std::string toString(void);
};
bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs);

View File

@ -40,7 +40,9 @@ namespace Ogre
void computeNormalsFromVolume(VolumeIterator volIter);
//void decimate(void);
void computeOtherHalfEdges(void);
bool decimate(void);
//bool verticesArePlanar(SurfaceVertexIterator iterCurrentVertex);

View File

@ -38,6 +38,8 @@ namespace Ogre
SurfaceEdgeIterator edge;
SurfaceTriangle();
//std::string toString(void);
};
bool operator == (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs);

View File

@ -48,7 +48,9 @@ namespace Ogre
SurfaceVertex(UIntVector3 positionToSet);
SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet);
SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet);
std::string toString(void);
};
bool operator==(const SurfaceVertex& lhs, const SurfaceVertex& rhs);

View File

@ -1009,7 +1009,12 @@ namespace Ogre
iterPatch->second.m_v3dOffset = offset;
iterPatch->second.computeNormalsFromVolume(volIter);
iterPatch->second.endDefinition();
//iterPatch->second.decimate();
bool removedVertex = false;
do
{
removedVertex = iterPatch->second.decimate();
}
while(removedVertex);
}
//LogManager::getSingleton().logMessage("Finished Generating Mesh Data");

View File

@ -5,28 +5,36 @@
namespace Ogre
{
SurfaceEdge::SurfaceEdge()
:hasOtherHalfEdge(false)
{
}
bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs)
{
return
(
(lhs.target == rhs.target) &&
(lhs.triangle == rhs.triangle)
);
}
std::string SurfaceEdge::toString(void)
{
std::stringstream ss;
ss << "SurfaceEdge: Target Vertex = " << target->toString();
return ss.str();
}
bool operator < (const SurfaceEdge& lhs, const SurfaceEdge& rhs)
bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs)
{
return
(
(lhs.target == rhs.target) &&
(lhs.triangle == rhs.triangle)
);
}
bool operator < (const SurfaceEdge& lhs, const SurfaceEdge& rhs)
{
if(lhs.target == rhs.target)
{
if(lhs.target == rhs.target)
if(lhs.triangle == rhs.triangle)
{
if(lhs.triangle == rhs.triangle)
{
return false;
}
return (*(lhs.triangle) < *(rhs.triangle));
return false;
}
return (*(lhs.target) < *(rhs.target));
return (*(lhs.triangle) < *(rhs.triangle));
}
return (*(lhs.target) < *(rhs.target));
}
}

View File

@ -40,10 +40,38 @@ namespace Ogre
//LogManager::getSingleton().logMessage("No of triangles present = " + StringConverter::toString(m_listTriangles.size()));
//LogManager::getSingleton().logMessage("No of vertices added = " + StringConverter::toString(m_uVerticesAdded));
//LogManager::getSingleton().logMessage("No of vertices present = " + StringConverter::toString(m_setVertices.size()));
/*m_listVertices.clear();
m_listTriangles.clear();
m_listEdges.clear();*/
//addTriangle(SurfaceVertex(UIntVector3(40 ,40 ,15)),SurfaceVertex(UIntVector3(42 ,42 ,15)),SurfaceVertex(UIntVector3(40 ,42 ,15)));
//addTriangle(SurfaceVertex(UIntVector3(40 ,40 ,15)),SurfaceVertex(UIntVector3(42 ,42 ,15)),SurfaceVertex(UIntVector3(42 ,40 ,15)));
computeOtherHalfEdges();
/*for(SurfaceTriangleIterator triangleIter = m_listTriangles.begin(); triangleIter != m_listTriangles.end(); triangleIter++)
{
LogManager::getSingleton().logMessage(triangleIter->toString());
}*/
}
void SurfacePatch::addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2)
{
/*if(v0.position.x > 16)
return;
if(v0.position.y > 16)
return;
if(v1.position.x > 16)
return;
if(v1.position.y > 16)
return;
if(v2.position.x > 16)
return;
if(v2.position.y > 16)
return;*/
//if(m_uTrianglesAdded > 1) return;
//LogManager::getSingleton().logMessage("Adding Triangle " + StringConverter::toString(m_uTrianglesAdded));
m_uTrianglesAdded++;
@ -109,6 +137,10 @@ namespace Ogre
v1v2Iter->nextHalfEdge = v2v0Iter;
v2v0Iter->nextHalfEdge = v0v1Iter;
v0v1Iter->previousHalfEdge = v2v0Iter;
v1v2Iter->previousHalfEdge = v0v1Iter;
v2v0Iter->previousHalfEdge = v1v2Iter;
SurfaceTriangle triangle;
triangle.edge = v0v1Iter;
@ -218,16 +250,16 @@ namespace Ogre
vertexData.resize(m_listVertices.size());
std::copy(m_listVertices.begin(), m_listVertices.end(), vertexData.begin());
/*LogManager::getSingleton().logMessage("----------Vertex Data----------");
LogManager::getSingleton().logMessage("----------Vertex Data----------");
for(std::vector<SurfaceVertex>::iterator vertexIter = vertexData.begin(); vertexIter != vertexData.end(); ++vertexIter)
{
LogManager::getSingleton().logMessage(StringConverter::toString(vertexIter->position.x) + "," + StringConverter::toString(vertexIter->position.y) + "," + StringConverter::toString(vertexIter->position.z));
}
LogManager::getSingleton().logMessage("----------End Vertex Data----------");*/
LogManager::getSingleton().logMessage("----------End Vertex Data----------");
for(SurfaceTriangleIterator iterTriangles = m_listTriangles.begin(); iterTriangles != m_listTriangles.end(); ++iterTriangles)
{
//LogManager::getSingleton().logMessage("Begin Triangle:");
LogManager::getSingleton().logMessage("Begin Triangle:");
std::vector<SurfaceVertex>::iterator iterVertex;
SurfaceEdgeIterator edgeIter;
@ -239,15 +271,43 @@ namespace Ogre
edgeIter = edgeIter->nextHalfEdge;
iterVertex = find(vertexData.begin(), vertexData.end(), *(edgeIter->target));
//LogManager::getSingleton().logMessage(" " + StringConverter::toString(iterVertex->position.x) + "," + StringConverter::toString(iterVertex->position.y) + "," + StringConverter::toString(iterVertex->position.z));
LogManager::getSingleton().logMessage(" " + StringConverter::toString(iterVertex->position.x) + "," + StringConverter::toString(iterVertex->position.y) + "," + StringConverter::toString(iterVertex->position.z));
indexData.push_back(iterVertex - vertexData.begin());
edgeIter = edgeIter->nextHalfEdge;
iterVertex = find(vertexData.begin(), vertexData.end(), *(edgeIter->target));
//LogManager::getSingleton().logMessage(" " + StringConverter::toString(iterVertex->position.x) + "," + StringConverter::toString(iterVertex->position.y) + "," + StringConverter::toString(iterVertex->position.z));
LogManager::getSingleton().logMessage(" " + StringConverter::toString(iterVertex->position.x) + "," + StringConverter::toString(iterVertex->position.y) + "," + StringConverter::toString(iterVertex->position.z));
indexData.push_back(iterVertex - vertexData.begin());
//LogManager::getSingleton().logMessage("End Triangle");
LogManager::getSingleton().logMessage("End Triangle");
}
}
void SurfacePatch::computeOtherHalfEdges(void)
{
//Clear all other edges
for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter)
{
edgeIter->otherHalfEdge = m_listEdges.end();
edgeIter->hasOtherHalfEdge = false;
}
//FIXME - speed this up by storing edges in a container which sorts by edge 'target'.
//Assign all other edges
for(SurfaceEdgeIterator outerEdgeIter = m_listEdges.begin(); outerEdgeIter != m_listEdges.end(); ++outerEdgeIter)
{
for(SurfaceEdgeIterator innerEdgeIter = m_listEdges.begin(); innerEdgeIter != m_listEdges.end(); ++innerEdgeIter)
{
if((innerEdgeIter->target == outerEdgeIter->previousHalfEdge->target) && (outerEdgeIter->target == innerEdgeIter->previousHalfEdge->target))
{
innerEdgeIter->otherHalfEdge = outerEdgeIter;
outerEdgeIter->otherHalfEdge = innerEdgeIter;
innerEdgeIter->hasOtherHalfEdge = true;
outerEdgeIter->hasOtherHalfEdge = true;
}
}
}
}
@ -274,6 +334,98 @@ namespace Ogre
}
}*/
bool SurfacePatch::decimate(void)
{
bool removedEdge = false;
//LogManager::getSingleton().logMessage("Performing decimation");
//LogManager::getSingleton().logMessage("No of triangles = " + StringConverter::toString(m_listTriangles.size()));
for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter)
{
//LogManager::getSingleton().logMessage("Examining Edge " + edgeIter->toString());
SurfaceVertexIterator targetVertexIter = edgeIter->target;
SurfaceVertexIterator otherVertexIter = edgeIter->nextHalfEdge->nextHalfEdge->target;
//LogManager::getSingleton().logMessage("Target Vertex = " + targetVertexIter->toString());
//LogManager::getSingleton().logMessage("Other Vertex = " + otherVertexIter->toString());
if((targetVertexIter->flags == 0) /*&& (otherVertexIter->flags == 0)*/)
{
//LogManager::getSingleton().logMessage(" Collapsing Edge");
for(SurfaceEdgeIterator innerEdgeIter = m_listEdges.begin(); innerEdgeIter != m_listEdges.end(); ++innerEdgeIter)
{
if(innerEdgeIter->target == targetVertexIter)
{
//LogManager::getSingleton().logMessage(" Reset Edge Target");
innerEdgeIter->target = otherVertexIter;
}
}
if(edgeIter->hasOtherHalfEdge)
{
//LogManager::getSingleton().logMessage(" Has Other Edge");
SurfaceEdgeIterator otherEdgeIter = edgeIter->otherHalfEdge;
//LogManager::getSingleton().logMessage(" Removing Other Edges");
SurfaceTriangleIterator otherTriangleIter = otherEdgeIter->triangle;
SurfaceEdgeIterator currentIter = otherTriangleIter->edge;
for(uint ct = 0; ct < 3; ++ct)
{
SurfaceEdgeIterator previousIter = currentIter;
currentIter = currentIter->nextHalfEdge;
if(previousIter->hasOtherHalfEdge)
{
previousIter->otherHalfEdge->hasOtherHalfEdge = false;
}
m_listEdges.erase(previousIter);
}
//LogManager::getSingleton().logMessage(" Removing Other Triangle");
m_listTriangles.erase(otherTriangleIter);
}
else
{
//LogManager::getSingleton().logMessage(" Does Not Have Other Edge");
}
//LogManager::getSingleton().logMessage(" Removing Edges");
SurfaceTriangleIterator triangleIter = edgeIter->triangle;
SurfaceEdgeIterator currentIter = triangleIter->edge;
for(uint ct = 0; ct < 3; ++ct)
{
SurfaceEdgeIterator previousIter = currentIter;
currentIter = currentIter->nextHalfEdge;
if(previousIter->hasOtherHalfEdge)
{
previousIter->otherHalfEdge->hasOtherHalfEdge = false;
}
m_listEdges.erase(previousIter);
}
//LogManager::getSingleton().logMessage(" Removing Triangle");
m_listTriangles.erase(triangleIter);
//LogManager::getSingleton().logMessage(" Removing Vertex");
m_listVertices.erase(targetVertexIter);
removedEdge = true;
break;
}
else
{
//LogManager::getSingleton().logMessage(" Not Collapsing Edge");
//LogManager::getSingleton().logMessage("Edge Target Vertex = " + StringConverter::toString(edgeIter->target->position.toOgreVector3()));
//LogManager::getSingleton().logMessage("Other Edge Non-Existant");
}
}
//LogManager::getSingleton().logMessage("Done decimation");
//LogManager::getSingleton().logMessage("No of triangles = " + StringConverter::toString(m_listTriangles.size()));
return removedEdge;
}
#ifdef BLAH
void SurfacePatch::decimate(void)

View File

@ -8,6 +8,31 @@ namespace Ogre
{
}
/*std::string SurfaceTriangle::toString(void)
{
std::stringstream ss;
uint ct = 0;
SurfaceEdgeIterator edgeIter = edge;
ss << "SurfaceTriangle:";
do
{
ss << "\n Edge " << ct << " = " << edgeIter->toString();
if(edgeIter->hasOtherHalfEdge)
{
ss << "\n Opp Edge " << ct << " = " << edgeIter->otherHalfEdge->toString();
}
else
{
ss << "\n No Other Half";
}
edgeIter = edgeIter->nextHalfEdge;
++ct;
}
while(edgeIter != edge);
return ss.str();
}*/
bool operator == (const SurfaceTriangle& lhs, const SurfaceTriangle& rhs)
{
/*return

View File

@ -38,6 +38,13 @@ namespace Ogre
flags |= 0x08;
}
std::string SurfaceVertex::toString(void)
{
std::stringstream ss;
ss << "SurfaceVertex: Position = (" << position.x << "," << position.y << "," << position.z << "), Flags = " << int(flags);
return ss.str();
}
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.
@ -122,5 +129,5 @@ namespace Ogre
return (lhs.alpha < rhs.alpha);
}
return (lhsOffset < rhsOffset)*/;
}
}
}

View File

@ -59,15 +59,15 @@ namespace Ogre
LogManager::getSingleton().logMessage("Value is " + StringConverter::toString(int(value)));
}*/
volIter.setVoxelAt(x,y,z,value);
/*if(z < 24)
if(z < 24)
{
if(x % 32 < 16)
//if(x % 32 < 16)
volIter.setVoxelAt(x,y,z,4);
else
volIter.setVoxelAt(x,y,z,5);
/*else
volIter.setVoxelAt(x,y,z,5);*/
}
else
volIter.setVoxelAt(x,y,z,0);*/
volIter.setVoxelAt(x,y,z,0);
}
}