Refactoring work... working on meshes

This commit is contained in:
David Williams 2007-09-02 11:16:58 +00:00
parent abe66c3d81
commit 80c6f149a5
7 changed files with 188 additions and 37 deletions

View File

@ -4,8 +4,7 @@
#include <list> #include <list>
#include <vector> #include <vector>
#include "SurfaceVertex.h" #include "IntegralVector3.h"
#include "SurfaceTriangle.h"
#include "VolumeIterator.h" #include "VolumeIterator.h"
@ -19,6 +18,11 @@ namespace Ogre
SOBEL SOBEL
}; };
class SurfaceVertex;
typedef std::set<SurfaceVertex>::iterator SurfaceVertexIterator;
class SurfaceTriangle;
typedef std::set<SurfaceTriangle>::iterator SurfaceTriangleIterator;
class SurfacePatch class SurfacePatch
{ {
public: public:
@ -34,11 +38,15 @@ namespace Ogre
void computeNormalsFromVolume(VolumeIterator volIter); void computeNormalsFromVolume(VolumeIterator volIter);
void decimate(void);
//bool verticesArePlanar(SurfaceVertexIterator iterCurrentVertex);
UIntVector3 m_v3dOffset; UIntVector3 m_v3dOffset;
private: private:
std::set<SurfaceVertex> m_setVertices; std::set<SurfaceVertex> m_setVertices;
std::list<SurfaceTriangle> m_listTriangles; std::set<SurfaceTriangle> m_setTriangles;
//std::vector<SurfaceVertex> m_vecVertexData; //std::vector<SurfaceVertex> m_vecVertexData;
//std::vector<uint> m_vecIndexData; //std::vector<uint> m_vecIndexData;

View File

@ -22,30 +22,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "OgrePrerequisites.h" #include "OgrePrerequisites.h"
#include "OgreVector3.h"
namespace Ogre namespace Ogre
{ {
class SurfaceVertex; class SurfaceVertex;
typedef std::set<SurfaceVertex>::iterator SurfaceVertexIterator;
class SurfaceTriangle;
typedef std::set<SurfaceTriangle>::iterator SurfaceTriangleIterator;
class SurfaceTriangle class SurfaceTriangle
{ {
public: public:
//FIXME - maybe these should be short? SurfaceVertexIterator v0;
/*ulong v0; SurfaceVertexIterator v1;
ulong v1; SurfaceVertexIterator v2;
ulong v2;*/
std::set<SurfaceVertex>::iterator v0;
std::set<SurfaceVertex>::iterator v1;
std::set<SurfaceVertex>::iterator v2;
SurfaceTriangle(); SurfaceTriangle();
SurfaceTriangle(std::set<SurfaceVertex>::iterator v0ToSet, std::set<SurfaceVertex>::iterator v1ToSet, std::set<SurfaceVertex>::iterator v2ToSet); SurfaceTriangle(SurfaceVertexIterator v0ToSet, SurfaceVertexIterator v1ToSet, SurfaceVertexIterator v2ToSet);
//bool operator < (const SurfaceTriangle& rhs) const;
}; };
typedef std::set<SurfaceTriangle>::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 #endif

View File

@ -26,28 +26,34 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "IntegralVector3.h" #include "IntegralVector3.h"
namespace Ogre namespace Ogre
{ {
class SurfaceVertex;
typedef std::set<SurfaceVertex>::iterator SurfaceVertexIterator;
class SurfaceTriangle; class SurfaceTriangle;
typedef std::set<SurfaceTriangle>::iterator SurfaceTriangleIterator;
class SurfaceVertex class SurfaceVertex
{ {
public: public:
UIntVector3 position; UIntVector3 position;
Vector3 normal; Vector3 normal;
float alpha; float alpha;
std::list<std::list<SurfaceTriangle>::iterator> listTrianglesUsingThisVertex; std::list<SurfaceTriangleIterator> listTrianglesUsingThisVertex;
std::list<SurfaceVertexIterator> listConnectedVertices;
SurfaceVertex(); SurfaceVertex();
SurfaceVertex(UIntVector3 positionToSet); SurfaceVertex(UIntVector3 positionToSet);
SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet); SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet);
bool operator==(const SurfaceVertex& rhs) const;
bool operator < (const SurfaceVertex& rhs) const;
}; };
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 #endif

View File

@ -1008,6 +1008,7 @@ namespace Ogre
iterPatch->second.m_v3dOffset = offset; iterPatch->second.m_v3dOffset = offset;
iterPatch->second.computeNormalsFromVolume(volIter); iterPatch->second.computeNormalsFromVolume(volIter);
iterPatch->second.endDefinition(); iterPatch->second.endDefinition();
//iterPatch->second.decimate();
} }
//LogManager::getSingleton().logMessage("Finished Generating Mesh Data"); //LogManager::getSingleton().logMessage("Finished Generating Mesh Data");
@ -1133,6 +1134,7 @@ namespace Ogre
#endif #endif
bool PolyVoxSceneManager::verticesArePlanar3(uint uCurrentVertex, std::set<uint> setConnectedVertices, std::vector<SurfaceVertex>& vertexData) const bool PolyVoxSceneManager::verticesArePlanar3(uint uCurrentVertex, std::set<uint> setConnectedVertices, std::vector<SurfaceVertex>& vertexData) const
{ {
//FIXME - specially handle the case where they are all the same. //FIXME - specially handle the case where they are all the same.

View File

@ -1,6 +1,9 @@
#include "SurfacePatch.h" #include "SurfacePatch.h"
#include "Constants.h" #include "Constants.h"
#include "SurfaceVertex.h"
#include "SurfaceTriangle.h"
#include "OgreLogManager.h" #include "OgreLogManager.h"
#include "OgreStringConverter.h" #include "OgreStringConverter.h"
@ -11,7 +14,7 @@ namespace Ogre
SurfacePatch::SurfacePatch() SurfacePatch::SurfacePatch()
{ {
m_setVertices.clear(); m_setVertices.clear();
m_listTriangles.clear(); m_setTriangles.clear();
m_uTrianglesAdded = 0; m_uTrianglesAdded = 0;
m_uVerticesAdded = 0; m_uVerticesAdded = 0;
@ -49,17 +52,17 @@ namespace Ogre
triangle.v1 = m_setVertices.insert(v1).first; triangle.v1 = m_setVertices.insert(v1).first;
triangle.v2 = m_setVertices.insert(v2).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.v0->listTrianglesUsingThisVertex.push_back(iterTriangle);
triangle.v1->listTrianglesUsingThisVertex.push_back(m_listTriangles.end()); triangle.v1->listTrianglesUsingThisVertex.push_back(iterTriangle);
triangle.v2->listTrianglesUsingThisVertex.push_back(m_listTriangles.end()); triangle.v2->listTrianglesUsingThisVertex.push_back(iterTriangle);
} }
void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter) void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter)
{ {
//LogManager::getSingleton().logMessage("In SurfacePatch::computeNormalsFromVolume"); //LogManager::getSingleton().logMessage("In SurfacePatch::computeNormalsFromVolume");
for(std::set<SurfaceVertex>::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"); //LogManager::getSingleton().logMessage("In Loop");
const float posX = (vertexIter->position.x + m_v3dOffset.x) / 2.0f; const float posX = (vertexIter->position.x + m_v3dOffset.x) / 2.0f;
@ -152,7 +155,7 @@ namespace Ogre
vertexData.resize(m_setVertices.size()); vertexData.resize(m_setVertices.size());
std::copy(m_setVertices.begin(), m_setVertices.end(), vertexData.begin()); std::copy(m_setVertices.begin(), m_setVertices.end(), vertexData.begin());
for(std::list<SurfaceTriangle>::iterator iterTriangles = m_listTriangles.begin(); iterTriangles != m_listTriangles.end(); ++iterTriangles) for(SurfaceTriangleIterator iterTriangles = m_setTriangles.begin(); iterTriangles != m_setTriangles.end(); ++iterTriangles)
{ {
std::vector<SurfaceVertex>::iterator iterVertex; std::vector<SurfaceVertex>::iterator iterVertex;
@ -166,4 +169,90 @@ namespace Ogre
indexData.push_back(iterVertex - vertexData.begin()); 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<SurfaceTriangleIterator>::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<uint>::iterator iterConnectedVertices;
std::list<SurfaceVertexIterator> listConnectedVertices = iterCurrentVertex->listConnectedVertices;
std::list<SurfaceVertexIterator>::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;
}*/
} }

View File

@ -1,4 +1,5 @@
#include "SurfaceTriangle.h" #include "SurfaceTriangle.h"
#include "SurfaceVertex.h"
namespace Ogre namespace Ogre
{ {
@ -6,10 +7,42 @@ namespace Ogre
{ {
} }
SurfaceTriangle::SurfaceTriangle(std::set<SurfaceVertex>::iterator v0ToSet, std::set<SurfaceVertex>::iterator v1ToSet, std::set<SurfaceVertex>::iterator v2ToSet) SurfaceTriangle::SurfaceTriangle(SurfaceVertexIterator v0ToSet, SurfaceVertexIterator v1ToSet, SurfaceVertexIterator v2ToSet)
:v0(v0ToSet) :v0(v0ToSet)
,v1(v1ToSet) ,v1(v1ToSet)
,v2(v2ToSet) ,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);
}*/
} }

View File

@ -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. //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 /*return
@ -45,13 +45,13 @@ namespace Ogre
return value == rhsValue;*/ 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); 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) /*if((*this) == rhs)
{ {
@ -92,9 +92,20 @@ namespace Ogre
return value < rhsValue;*/ 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); 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);
}*/
} }