Some tidying up of the LOD work.

This commit is contained in:
David Williams
2010-02-07 23:48:33 +00:00
parent 1448f95b0a
commit d3ad3d985b
3 changed files with 53 additions and 48 deletions

View File

@ -70,14 +70,14 @@ namespace PolyVox
POLYVOX_SHARED_PTR<IndexedSurfacePatch> extractSubset(std::set<uint8_t> setMaterials); POLYVOX_SHARED_PTR<IndexedSurfacePatch> extractSubset(std::set<uint8_t> setMaterials);
void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false); void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false);
void generateMaterialWeightedNormals();
//Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this? //Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this?
/*void growMaterialBoundary(void); /*void growMaterialBoundary(void);
int countMaterialBoundary(void);*/ int countMaterialBoundary(void);*/
bool isSubset(std::bitset<7> a, std::bitset<7> b); bool isSubset(std::bitset<VF_NO_OF_FLAGS> a, std::bitset<VF_NO_OF_FLAGS> b);
void decimate(float fMinDotProductForCollapse = 0.999f); void decimate(float fMinDotProductForCollapse = 0.999f);
@ -103,6 +103,12 @@ namespace PolyVox
//which cover a whole triangle are counted. Materials which only //which cover a whole triangle are counted. Materials which only
//exist on a material boundary do not count. //exist on a material boundary do not count.
std::set<uint8_t> m_mapUsedMaterials; std::set<uint8_t> m_mapUsedMaterials;
private:
void countNoOfNeighboursUsingMaterial(void);
//Data structures used during decimation
std::vector<uint8_t> m_vecNoOfNeighboursUsingMaterial;
}; };
} }

View File

@ -36,13 +36,14 @@ namespace PolyVox
{ {
enum POLYVOXCORE_API VertexFlags enum POLYVOXCORE_API VertexFlags
{ {
VF_ON_MATERIAL_EDGE = 0x00, VF_ON_MATERIAL_EDGE,
VF_ON_GEOMETRY_EDGE_NEG_X = 0x01, VF_ON_GEOMETRY_EDGE_NEG_X,
VF_ON_GEOMETRY_EDGE_POS_X = 0x02, VF_ON_GEOMETRY_EDGE_POS_X ,
VF_ON_GEOMETRY_EDGE_NEG_Y = 0x03, VF_ON_GEOMETRY_EDGE_NEG_Y ,
VF_ON_GEOMETRY_EDGE_POS_Y = 0x04, VF_ON_GEOMETRY_EDGE_POS_Y ,
VF_ON_GEOMETRY_EDGE_NEG_Z = 0x05, VF_ON_GEOMETRY_EDGE_NEG_Z ,
VF_ON_GEOMETRY_EDGE_POS_Z = 0x06, VF_ON_GEOMETRY_EDGE_POS_Z,
VF_NO_OF_FLAGS
}; };
class POLYVOXCORE_API SurfaceVertex class POLYVOXCORE_API SurfaceVertex
@ -81,11 +82,8 @@ namespace PolyVox
public: public:
Vector3DFloat position; Vector3DFloat position;
Vector3DFloat normal; Vector3DFloat normal;
Vector3DFloat materialNormal;
int noOfMatchingNeighbours;
std::vector<uint8_t> neighbourMaterials;
float material; //FIXME: This shouldn't be float on CPU? float material; //FIXME: This shouldn't be float on CPU?
std::bitset<7> m_bFlags; std::bitset<VF_NO_OF_FLAGS> m_bFlags;
}; };

View File

@ -313,8 +313,11 @@ namespace PolyVox
} }
} }
void IndexedSurfacePatch::generateMaterialWeightedNormals() //This function looks at every vertex in the mesh and determines
//how many of it's neighbours have the same material.
void IndexedSurfacePatch::countNoOfNeighboursUsingMaterial(void)
{ {
//Find all the neighbouring vertices for each vertex
std::vector< std::set<int> > neighbouringVertices(m_vecVertices.size()); std::vector< std::set<int> > neighbouringVertices(m_vecVertices.size());
for(int triCt = 0; triCt < m_vecTriangleIndices.size() / 3; triCt++) for(int triCt = 0; triCt < m_vecTriangleIndices.size() / 3; triCt++)
{ {
@ -332,23 +335,18 @@ namespace PolyVox
neighbouringVertices[v2].insert(v1); neighbouringVertices[v2].insert(v1);
} }
//For each vertex, check how many neighbours have the same material
m_vecNoOfNeighboursUsingMaterial.resize(m_vecVertices.size());
for(int vertCt = 0; vertCt < m_vecVertices.size(); vertCt++) for(int vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
{ {
m_vecVertices[vertCt].noOfMatchingNeighbours = 0; m_vecNoOfNeighboursUsingMaterial[vertCt] = 0;
m_vecVertices[vertCt].neighbourMaterials.clear();
Vector3DFloat materialNormal(0,0,0);
for(std::set<int>::iterator iter = neighbouringVertices[vertCt].begin(); iter != neighbouringVertices[vertCt].end(); iter++) for(std::set<int>::iterator iter = neighbouringVertices[vertCt].begin(); iter != neighbouringVertices[vertCt].end(); iter++)
{ {
m_vecVertices[vertCt].neighbourMaterials.push_back(m_vecVertices[*iter].getMaterial());
materialNormal += (m_vecVertices[*iter].getPosition() - m_vecVertices[vertCt].getPosition()) * m_vecVertices[vertCt].getMaterial();
if(m_vecVertices[vertCt].getMaterial() == m_vecVertices[*iter].getMaterial()) if(m_vecVertices[vertCt].getMaterial() == m_vecVertices[*iter].getMaterial())
{ {
m_vecVertices[vertCt].noOfMatchingNeighbours++; m_vecNoOfNeighboursUsingMaterial[vertCt]++;
} }
} }
materialNormal.normalise();
m_vecVertices[vertCt].materialNormal = materialNormal;
} }
} }
@ -459,23 +457,17 @@ namespace PolyVox
void IndexedSurfacePatch::decimate(float fMinDotProductForCollapse) void IndexedSurfacePatch::decimate(float fMinDotProductForCollapse)
{ {
generateMaterialWeightedNormals(); // We will need the information from this function to
// determine when material boundary edges can collapse.
countNoOfNeighboursUsingMaterial();
uint32_t noOfEdgesCollapsed = 0; uint32_t noOfEdgesCollapsed;
do do
{ {
//generateAveragedFaceNormals(true);
noOfEdgesCollapsed = performDecimationPass(fMinDotProductForCollapse); noOfEdgesCollapsed = performDecimationPass(fMinDotProductForCollapse);
removeDegenerateTris(); removeDegenerateTris();
}while(noOfEdgesCollapsed > 0); }while(noOfEdgesCollapsed > 0);
//cout << "Collapsed " << performDecimationPass(fMinDotProductForCollapse) << " edges." << endl; removeDegenerateTris();
/*cout << "Collapsed " << performDecimationPass(fMinDotProductForCollapse) << " edges." << endl; removeDegenerateTris();
cout << "Collapsed " << performDecimationPass(fMinDotProductForCollapse) << " edges." << endl; removeDegenerateTris();
cout << "Collapsed " << performDecimationPass(fMinDotProductForCollapse) << " edges." << endl; removeDegenerateTris();
cout << "Collapsed " << performDecimationPass(fMinDotProductForCollapse) << " edges." << endl; removeDegenerateTris();*/
//Decimation will have invalidated LOD levels. //Decimation will have invalidated LOD levels.
m_vecLodRecords.clear(); m_vecLodRecords.clear();
LodRecord lodRecord; LodRecord lodRecord;
@ -484,8 +476,8 @@ namespace PolyVox
m_vecLodRecords.push_back(lodRecord); m_vecLodRecords.push_back(lodRecord);
} }
/*Returns true if every bit which is set in 'a' is also set in 'b'. The reverse does not need to be true.*/ // Returns true if every bit which is set in 'a' is also set in 'b'. The reverse does not need to be true.
bool IndexedSurfacePatch::isSubset(std::bitset<7> a, std::bitset<7> b) bool IndexedSurfacePatch::isSubset(std::bitset<VF_NO_OF_FLAGS> a, std::bitset<VF_NO_OF_FLAGS> b)
{ {
bool result = true; bool result = true;
@ -578,23 +570,17 @@ namespace PolyVox
{ {
if(true) if(true)
{ {
bool pass = false; bool pass = false;
//if(m_vecVertices[v0].materialNormal.dot(m_vecVertices[v1].materialNormal) < 0.9999)
/*if(m_vecVertices[v0].isOnMaterialEdge() && m_vecVertices[v1].isOnMaterialEdge())
{
if(m_vecVertices[v0].getMaterial() == m_vecVertices[v1].getMaterial())
{
pass = true;
}
}*/
bool allMatch = false; bool allMatch = false;
if(m_vecVertices[v0].noOfMatchingNeighbours == m_vecVertices[v1].noOfMatchingNeighbours) // On the original undecimated mesh a material boundary vertex on a straight edge will
// have four neighbours with the same material. If it's on a corner it will have a
// different number. We only collapse straight edges to avoid changingthe shape of the
// material boundary.
if(m_vecNoOfNeighboursUsingMaterial[v0] == m_vecNoOfNeighboursUsingMaterial[v1])
{ {
if(m_vecVertices[v0].noOfMatchingNeighbours == 4) if(m_vecNoOfNeighboursUsingMaterial[v0] == 4)
{ {
allMatch = true; allMatch = true;
} }
@ -618,6 +604,21 @@ namespace PolyVox
movementValid = true; movementValid = true;
} }
if(movement.dot(Vector3DFloat(0,0,-1)) > 0.999)
{
movementValid = true;
}
if(movement.dot(Vector3DFloat(0,-1,0)) > 0.999)
{
movementValid = true;
}
if(movement.dot(Vector3DFloat(-1,0,0)) > 0.999)
{
movementValid = true;
}
if(movementValid && allMatch) if(movementValid && allMatch)
{ {
pass = true; pass = true;