From 1a7647027db92aa9bd7b3b1ee926a2eb6b0b7cc8 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 14 May 2011 12:30:39 +0100 Subject: [PATCH] Tidying up ImprovedCubicSurfaceExtractor. --- .../include/ImprovedCubicSurfaceExtractor.h | 37 ++++++++----------- .../include/ImprovedCubicSurfaceExtractor.inl | 13 ++++--- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.h b/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.h index fa03f813..165d6c5a 100644 --- a/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.h +++ b/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.h @@ -32,11 +32,6 @@ freely, subject to the following restrictions: namespace PolyVox { - struct Quad - { - uint32_t vertices[4]; - }; - template< template class VolumeType, typename VoxelType> class ImprovedCubicSurfaceExtractor { @@ -57,17 +52,23 @@ namespace PolyVox NoOfFaces }; + struct Quad + { + uint32_t vertices[4]; + }; + public: ImprovedCubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result, bool bMergeQuads = true); - void execute(); - - int32_t addVertex(float fX, float fY, float fZ, uint8_t uMaterial, Array<3, IndexAndMaterial>& existingVertices); + void execute(); private: + int32_t addVertex(float fX, float fY, float fZ, uint8_t uMaterial, Array<3, IndexAndMaterial>& existingVertices); + bool performQuadMerging(std::list& quads); + bool mergeQuads(Quad& q1, Quad& q2); + //The volume data and a sampler to access it. VolumeType* m_volData; - typename VolumeType::Sampler m_sampVolume; //Information about the region we are currently processing Region m_regSizeInVoxels; @@ -75,28 +76,22 @@ namespace PolyVox //The surface patch we are currently filling. SurfaceMesh* m_meshCurrent; - //Array<4, IndexAndMaterial> m_vertices; + //Used to avoid creating duplicate vertices. Array<3, IndexAndMaterial> m_previousSliceVertices; Array<3, IndexAndMaterial> m_currentSliceVertices; - Array<4, uint8_t> m_faces; - + //During extraction we create a number of different lists of quads. All the + //quads in a given list are in the same plane and facing in the same direction. std::vector< std::list > m_vecQuads[NoOfFaces]; + //Controls whether quad merging should be performed. This might be undesirable + //is the user needs per-vertex attributes, or to perform per vertex lighting. bool m_bMergeQuads; //Although we try to avoid creating multiple vertices at the same location, sometimes this is unavoidable //if they have different materials. For example, four different materials next to each other would mean //four quads (though more triangles) sharing the vertex. As far as I can tell, four is the worst case scenario. - static const uint32_t MaxQuadsSharingVertex; - - //////////////////////////////////////////////////////////////////////////////// - // Decimation - //////////////////////////////////////////////////////////////////////////////// - - bool decimate(std::list& quads); - - bool mergeQuads(Quad& q1, Quad& q2); + static const uint32_t MaxQuadsSharingVertex; }; } diff --git a/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.inl b/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.inl index 403b2af9..80e6f067 100644 --- a/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/ImprovedCubicSurfaceExtractor.inl @@ -35,7 +35,6 @@ namespace PolyVox template< template class VolumeType, typename VoxelType> ImprovedCubicSurfaceExtractor::ImprovedCubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result, bool bMergeQuads) :m_volData(volData) - ,m_sampVolume(volData) ,m_regSizeInVoxels(region) ,m_meshCurrent(result) ,m_bMergeQuads(bMergeQuads) @@ -58,8 +57,6 @@ namespace PolyVox uint32_t uRegionWidth = m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 1; uint32_t uRegionHeight = m_regSizeInVoxels.getUpperCorner().getY() - m_regSizeInVoxels.getLowerCorner().getY() + 1; uint32_t uRegionDepth = m_regSizeInVoxels.getUpperCorner().getZ() - m_regSizeInVoxels.getLowerCorner().getZ() + 1; - m_faces.resize(ArraySizes(uRegionWidth)(uRegionHeight)(uRegionDepth)(NoOfFaces)); - memset(m_faces.getRawData(), 0x00, m_faces.getNoOfElements() * sizeof(uint8_t)); //Note: hard-coded type uint8_t m_vecQuads[NegativeX].resize(m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 2); m_vecQuads[PositiveX].resize(m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 2); @@ -218,7 +215,9 @@ namespace PolyVox if(m_bMergeQuads) { - while(decimate(listQuads)){} + //Repeatedly call this function until it returns + //false to indicate nothing more can be done. + while(performQuadMerging(listQuads)){} } std::list::iterator iterEnd = listQuads.end(); @@ -274,7 +273,7 @@ namespace PolyVox } template< template class VolumeType, typename VoxelType> - bool ImprovedCubicSurfaceExtractor::decimate(std::list& quads) + bool ImprovedCubicSurfaceExtractor::performQuadMerging(std::list& quads) { bool bDidMerge = false; for(std::list::iterator outerIter = quads.begin(); outerIter != quads.end(); outerIter++) @@ -310,6 +309,9 @@ namespace PolyVox //so just check that the first pair or vertices match. if(fabs(m_meshCurrent->getVertices()[q1.vertices[0]].getMaterial() - m_meshCurrent->getVertices()[q2.vertices[0]].getMaterial()) < 0.001) { + //Now check whether quad 2 is adjacent to quad one by comparing vertices. + //Adjacent quads must share two vertices, and the second quad could be to the + //top, bottom, left, of right of the first one. This gives four combinations to test. if((q1.vertices[0] == q2.vertices[1]) && ((q1.vertices[3] == q2.vertices[2]))) { q1.vertices[0] = q2.vertices[0]; @@ -336,6 +338,7 @@ namespace PolyVox } } + //Quads cannot be merged. return false; } } \ No newline at end of file