diff --git a/library/PolyVoxCore/include/IndexedSurfacePatch.h b/library/PolyVoxCore/include/IndexedSurfacePatch.h index aca7f04d..1d8bd906 100644 --- a/library/PolyVoxCore/include/IndexedSurfacePatch.h +++ b/library/PolyVoxCore/include/IndexedSurfacePatch.h @@ -70,14 +70,14 @@ namespace PolyVox POLYVOX_SHARED_PTR extractSubset(std::set setMaterials); void generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices = false); - void generateMaterialWeightedNormals(); + //Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this? /*void growMaterialBoundary(void); int countMaterialBoundary(void);*/ - bool isSubset(std::bitset<7> a, std::bitset<7> b); + bool isSubset(std::bitset a, std::bitset b); void decimate(float fMinDotProductForCollapse = 0.999f); @@ -103,6 +103,12 @@ namespace PolyVox //which cover a whole triangle are counted. Materials which only //exist on a material boundary do not count. std::set m_mapUsedMaterials; + + private: + void countNoOfNeighboursUsingMaterial(void); + + //Data structures used during decimation + std::vector m_vecNoOfNeighboursUsingMaterial; }; } diff --git a/library/PolyVoxCore/include/SurfaceVertex.h b/library/PolyVoxCore/include/SurfaceVertex.h index f09557d4..1b09b4f3 100644 --- a/library/PolyVoxCore/include/SurfaceVertex.h +++ b/library/PolyVoxCore/include/SurfaceVertex.h @@ -36,13 +36,14 @@ namespace PolyVox { enum POLYVOXCORE_API VertexFlags { - VF_ON_MATERIAL_EDGE = 0x00, - VF_ON_GEOMETRY_EDGE_NEG_X = 0x01, - VF_ON_GEOMETRY_EDGE_POS_X = 0x02, - VF_ON_GEOMETRY_EDGE_NEG_Y = 0x03, - VF_ON_GEOMETRY_EDGE_POS_Y = 0x04, - VF_ON_GEOMETRY_EDGE_NEG_Z = 0x05, - VF_ON_GEOMETRY_EDGE_POS_Z = 0x06, + VF_ON_MATERIAL_EDGE, + VF_ON_GEOMETRY_EDGE_NEG_X, + VF_ON_GEOMETRY_EDGE_POS_X , + VF_ON_GEOMETRY_EDGE_NEG_Y , + VF_ON_GEOMETRY_EDGE_POS_Y , + VF_ON_GEOMETRY_EDGE_NEG_Z , + VF_ON_GEOMETRY_EDGE_POS_Z, + VF_NO_OF_FLAGS }; class POLYVOXCORE_API SurfaceVertex @@ -81,11 +82,8 @@ namespace PolyVox public: Vector3DFloat position; Vector3DFloat normal; - Vector3DFloat materialNormal; - int noOfMatchingNeighbours; - std::vector neighbourMaterials; float material; //FIXME: This shouldn't be float on CPU? - std::bitset<7> m_bFlags; + std::bitset m_bFlags; }; diff --git a/library/PolyVoxCore/source/IndexedSurfacePatch.cpp b/library/PolyVoxCore/source/IndexedSurfacePatch.cpp index 89b6fb15..ec2d1b4e 100644 --- a/library/PolyVoxCore/source/IndexedSurfacePatch.cpp +++ b/library/PolyVoxCore/source/IndexedSurfacePatch.cpp @@ -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 > neighbouringVertices(m_vecVertices.size()); for(int triCt = 0; triCt < m_vecTriangleIndices.size() / 3; triCt++) { @@ -332,23 +335,18 @@ namespace PolyVox 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++) { - m_vecVertices[vertCt].noOfMatchingNeighbours = 0; - m_vecVertices[vertCt].neighbourMaterials.clear(); - Vector3DFloat materialNormal(0,0,0); + m_vecNoOfNeighboursUsingMaterial[vertCt] = 0; for(std::set::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()) { - 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) { - 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 { - //generateAveragedFaceNormals(true); noOfEdgesCollapsed = performDecimationPass(fMinDotProductForCollapse); removeDegenerateTris(); }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. m_vecLodRecords.clear(); LodRecord lodRecord; @@ -484,8 +476,8 @@ namespace PolyVox 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.*/ - bool IndexedSurfacePatch::isSubset(std::bitset<7> a, std::bitset<7> b) + // 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 a, std::bitset b) { bool result = true; @@ -578,23 +570,17 @@ namespace PolyVox { if(true) { - 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 pass = 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; } @@ -618,6 +604,21 @@ namespace PolyVox 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) { pass = true;