From 0b410eaed3df9f5c5e6cc913be6287896cb66c1b Mon Sep 17 00:00:00 2001 From: David Williams Date: Wed, 20 Oct 2010 22:14:03 +0000 Subject: [PATCH] Memory improvements for surface extractor. --- .../include/CubicSurfaceExtractor.h | 11 ++++- .../include/CubicSurfaceExtractor.inl | 44 +++++++++++-------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/library/PolyVoxCore/include/CubicSurfaceExtractor.h b/library/PolyVoxCore/include/CubicSurfaceExtractor.h index 324acfe7..6b55875f 100644 --- a/library/PolyVoxCore/include/CubicSurfaceExtractor.h +++ b/library/PolyVoxCore/include/CubicSurfaceExtractor.h @@ -45,7 +45,7 @@ namespace PolyVox void execute(); - int32_t addVertex(float fX, float fY, float fZ, uint8_t uMaterial); + int32_t addVertex(float fX, float fY, float fZ, uint8_t uMaterial, Array<3, IndexAndMaterial>& existingVertices); private: //The volume data and a sampler to access it. @@ -59,7 +59,14 @@ namespace PolyVox Region m_regSizeInVoxels; Region m_regSizeInCells; - Array<4, IndexAndMaterial> m_vertices; + //Array<4, IndexAndMaterial> m_vertices; + Array<3, IndexAndMaterial> m_previousSliceVertices; + Array<3, IndexAndMaterial> m_currentSliceVertices; + + //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; }; } diff --git a/library/PolyVoxCore/include/CubicSurfaceExtractor.inl b/library/PolyVoxCore/include/CubicSurfaceExtractor.inl index 240da871..6245b610 100644 --- a/library/PolyVoxCore/include/CubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/CubicSurfaceExtractor.inl @@ -29,6 +29,9 @@ freely, subject to the following restrictions: namespace PolyVox { + template + const uint32_t CubicSurfaceExtractor::MaxQuadsSharingVertex = 4; + template CubicSurfaceExtractor::CubicSurfaceExtractor(Volume* volData, Region region, SurfaceMesh* result) :m_volData(volData) @@ -46,9 +49,11 @@ namespace PolyVox template void CubicSurfaceExtractor::execute() { - uint32_t arraySize[4]= {m_regSizeInVoxels.width()+2, m_regSizeInVoxels.height()+2, m_regSizeInVoxels.depth()+2, 4}; - m_vertices.resize(arraySize); - memset(m_vertices.getRawData(), 0xff, m_vertices.getNoOfElements() * sizeof(IndexAndMaterial)); + uint32_t arraySize[3]= {m_regSizeInVoxels.width()+2, m_regSizeInVoxels.height()+2, MaxQuadsSharingVertex}; + m_previousSliceVertices.resize(arraySize); + m_currentSliceVertices.resize(arraySize); + memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial)); + memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial)); for(uint16_t z = m_regSizeInVoxels.getLowerCorner().getZ(); z <= m_regSizeInVoxels.getUpperCorner().getZ() + 1; z++) { @@ -79,10 +84,10 @@ namespace PolyVox uint32_t v2 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), material)); uint32_t v3 = m_meshCurrent->addVertex(PositionMaterial(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), material));*/ - uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material); - uint32_t v1 = addVertex(regX - 0.5f, regY - 0.5f, regZ + 0.5f, material); - uint32_t v2 = addVertex(regX - 0.5f, regY + 0.5f, regZ - 0.5f, material); - uint32_t v3 = addVertex(regX - 0.5f, regY + 0.5f, regZ + 0.5f, material); + uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v1 = addVertex(regX - 0.5f, regY - 0.5f, regZ + 0.5f, material, m_currentSliceVertices); + uint32_t v2 = addVertex(regX - 0.5f, regY + 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v3 = addVertex(regX - 0.5f, regY + 0.5f, regZ + 0.5f, material, m_currentSliceVertices); if(currentVoxelIsSolid > negXVoxelIsSolid) { @@ -103,10 +108,10 @@ namespace PolyVox { int material = std::max(currentVoxel.getMaterial(),negYVoxel.getMaterial()); - uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material); - uint32_t v1 = addVertex(regX - 0.5f, regY - 0.5f, regZ + 0.5f, material); - uint32_t v2 = addVertex(regX + 0.5f, regY - 0.5f, regZ - 0.5f, material); - uint32_t v3 = addVertex(regX + 0.5f, regY - 0.5f, regZ + 0.5f, material); + uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v1 = addVertex(regX - 0.5f, regY - 0.5f, regZ + 0.5f, material, m_currentSliceVertices); + uint32_t v2 = addVertex(regX + 0.5f, regY - 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v3 = addVertex(regX + 0.5f, regY - 0.5f, regZ + 0.5f, material, m_currentSliceVertices); if(currentVoxelIsSolid > negYVoxelIsSolid) { @@ -127,10 +132,10 @@ namespace PolyVox { int material = std::max(currentVoxel.getMaterial(), negZVoxel.getMaterial()); - uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material); - uint32_t v1 = addVertex(regX - 0.5f, regY + 0.5f, regZ - 0.5f, material); - uint32_t v2 = addVertex(regX + 0.5f, regY - 0.5f, regZ - 0.5f, material); - uint32_t v3 = addVertex(regX + 0.5f, regY + 0.5f, regZ - 0.5f, material); + uint32_t v0 = addVertex(regX - 0.5f, regY - 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v1 = addVertex(regX - 0.5f, regY + 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v2 = addVertex(regX + 0.5f, regY - 0.5f, regZ - 0.5f, material, m_previousSliceVertices); + uint32_t v3 = addVertex(regX + 0.5f, regY + 0.5f, regZ - 0.5f, material, m_previousSliceVertices); if(currentVoxelIsSolid > negZVoxelIsSolid) { @@ -145,6 +150,9 @@ namespace PolyVox } } } + + m_previousSliceVertices.swap(m_currentSliceVertices); + memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() * sizeof(IndexAndMaterial)); } m_meshCurrent->m_Region = m_regSizeInVoxels; @@ -157,15 +165,15 @@ namespace PolyVox } template - int32_t CubicSurfaceExtractor::addVertex(float fX, float fY, float fZ, uint8_t uMaterialIn) + int32_t CubicSurfaceExtractor::addVertex(float fX, float fY, float fZ, uint8_t uMaterialIn, Array<3, IndexAndMaterial>& existingVertices) { uint16_t uX = static_cast(fX + 0.75f); uint16_t uY = static_cast(fY + 0.75f); uint16_t uZ = static_cast(fZ + 0.75f); - for(int ct = 0; ct < 16; ct++) + for(int ct = 0; ct < MaxQuadsSharingVertex; ct++) { - IndexAndMaterial& rEntry = m_vertices[uX][uY][uZ][ct]; + IndexAndMaterial& rEntry = existingVertices[uX][uY][ct]; int32_t iIndex = static_cast(rEntry.iIndex); uint8_t uMaterial = static_cast(rEntry.uMaterial);