From 23a56ed00082d24b6293e37e9dbdbedd233ab8bd Mon Sep 17 00:00:00 2001 From: David Williams Date: Mon, 7 Feb 2011 21:34:57 +0000 Subject: [PATCH] More work on compression. --- examples/Basic/main.cpp | 6 +- .../PolyVoxCore/include/PolyVoxImpl/Block.h | 2 +- .../PolyVoxCore/include/PolyVoxImpl/Block.inl | 72 +++++++++++-------- library/PolyVoxCore/include/Volume.inl | 2 +- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index f591d8ed..2318d55c 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -421,7 +421,7 @@ int main(int argc, char *argv[]) openGLWidget.show(); //Create an empty volume and then place a sphere in it - Volume volData(1024, 1024, 1024); + Volume volData(128, 128, 128); //createSphereInVolume(volData, 30); createPerlinVolume(volData); @@ -439,12 +439,12 @@ int main(int argc, char *argv[]) }*/ //Extract the surface - /*SurfaceMesh mesh; + SurfaceMesh mesh; CubicSurfaceExtractorWithNormals surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); surfaceExtractor.execute(); //Pass the surface to the OpenGL window - openGLWidget.setSurfaceMeshToRender(mesh);*/ + openGLWidget.setSurfaceMeshToRender(mesh); //Run the message pump. return app.exec(); diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.h b/library/PolyVoxCore/include/PolyVoxImpl/Block.h index 90df1e76..18d536d7 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.h @@ -63,7 +63,7 @@ namespace PolyVox bool m_bIsCompressed; uint64_t m_uTimestamp; - std::vector runlengths; + std::vector runlengths; std::vector values; }; } diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl index 27f6c862..5ccb1d14 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl @@ -27,6 +27,7 @@ freely, subject to the following restrictions: #include #include //For memcpy +#include #include //for std::invalid_argument namespace PolyVox @@ -199,41 +200,37 @@ namespace PolyVox template void Block::compress(void) { - VoxelType current; - uint32_t runLength = 0; uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; - bool firstTime = true; - //uint32_t runlengthCounter = 0; runlengths.clear(); values.clear(); - for(uint32_t ct = 0; ct < uNoOfVoxels; ++ct) + VoxelType current = m_tUncompressedData[0]; + uint8_t runLength = 1; + + for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct) { - VoxelType value = *(m_tUncompressedData + ct); - if(firstTime) + VoxelType value = m_tUncompressedData[ct]; + if((value == current) && (runLength < (std::numeric_limits::max)())) { - current = value; - runLength = 1; - firstTime = false; + runLength++; } else { - if(value == current) - { - runLength++; - } - else - { - //stream.write(reinterpret_cast(¤t), sizeof(current)); - //stream.write(reinterpret_cast(&runLength), sizeof(runLength)); - runlengths.push_back(runLength); - values.push_back(current); - current = value; - runLength = 1; - } - } + runlengths.push_back(runLength); + values.push_back(current); + current = value; + runLength = 1; + } } + runlengths.push_back(runLength); + values.push_back(current); + + //Shrink the vectors to their contents (seems slow?): + //http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector + //C++0x may have a shrink_to_fit() function? + //std::vector(runlengths).swap(runlengths); + //std::vector(values).swap(values); delete[] m_tUncompressedData; m_tUncompressedData = 0; @@ -245,17 +242,32 @@ namespace PolyVox { m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; - VoxelType* pUncompressedData = m_tUncompressedData; - for(uint32_t ct = 0; ct < runlengths.size(); ++ct) + + //memset should provide the fastest way of expanding the data, but it works + //on unsigned chars so is only possible if our voxel type is the right size. + //Nore that memset takes an int type, but sonverts it to unsiogned char: + //http://www.cplusplus.com/reference/clibrary/cstring/memset/ + if(sizeof(VoxelType) == sizeof(unsigned char)) { - for(uint32_t i = 0; i < runlengths[ct]; ++i) + for(uint32_t ct = 0; ct < runlengths.size(); ++ct) { - *pUncompressedData = values[ct]; - ++pUncompressedData; + memset(pUncompressedData, *((int*)(&values[ct])), runlengths[ct]); + pUncompressedData += runlengths[ct]; + } + } + //Otherwise we fall back on a loop. + else + { + for(uint32_t ct = 0; ct < runlengths.size(); ++ct) + { + for(uint32_t i = 0; i < runlengths[ct]; ++i) + { + *pUncompressedData = values[ct]; + ++pUncompressedData; + } } } - m_bIsCompressed = false; } diff --git a/library/PolyVoxCore/include/Volume.inl b/library/PolyVoxCore/include/Volume.inl index c5905e48..db515b8b 100644 --- a/library/PolyVoxCore/include/Volume.inl +++ b/library/PolyVoxCore/include/Volume.inl @@ -388,7 +388,7 @@ namespace PolyVox return block; } - const uint32_t MaxUncompressedBlocks = 1000; + const uint32_t MaxUncompressedBlocks = 10; if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks) { Block* pLeastRecentlyUsedBlock = 0;