More work on compression.

This commit is contained in:
David Williams 2011-02-07 21:34:57 +00:00
parent f13e9161f8
commit 23a56ed000
4 changed files with 47 additions and 35 deletions

View File

@ -421,7 +421,7 @@ int main(int argc, char *argv[])
openGLWidget.show(); openGLWidget.show();
//Create an empty volume and then place a sphere in it //Create an empty volume and then place a sphere in it
Volume<MaterialDensityPair44> volData(1024, 1024, 1024); Volume<MaterialDensityPair44> volData(128, 128, 128);
//createSphereInVolume(volData, 30); //createSphereInVolume(volData, 30);
createPerlinVolume(volData); createPerlinVolume(volData);
@ -439,12 +439,12 @@ int main(int argc, char *argv[])
}*/ }*/
//Extract the surface //Extract the surface
/*SurfaceMesh<PositionMaterialNormal> mesh; SurfaceMesh<PositionMaterialNormal> mesh;
CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute(); surfaceExtractor.execute();
//Pass the surface to the OpenGL window //Pass the surface to the OpenGL window
openGLWidget.setSurfaceMeshToRender(mesh);*/ openGLWidget.setSurfaceMeshToRender(mesh);
//Run the message pump. //Run the message pump.
return app.exec(); return app.exec();

View File

@ -63,7 +63,7 @@ namespace PolyVox
bool m_bIsCompressed; bool m_bIsCompressed;
uint64_t m_uTimestamp; uint64_t m_uTimestamp;
std::vector<uint32_t> runlengths; std::vector<uint8_t> runlengths;
std::vector<VoxelType> values; std::vector<VoxelType> values;
}; };
} }

View File

@ -27,6 +27,7 @@ freely, subject to the following restrictions:
#include <cassert> #include <cassert>
#include <cstring> //For memcpy #include <cstring> //For memcpy
#include <limits>
#include <stdexcept> //for std::invalid_argument #include <stdexcept> //for std::invalid_argument
namespace PolyVox namespace PolyVox
@ -199,41 +200,37 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void Block<VoxelType>::compress(void) void Block<VoxelType>::compress(void)
{ {
VoxelType current;
uint32_t runLength = 0;
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
bool firstTime = true;
//uint32_t runlengthCounter = 0;
runlengths.clear(); runlengths.clear();
values.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); VoxelType value = m_tUncompressedData[ct];
if(firstTime) if((value == current) && (runLength < (std::numeric_limits<uint8_t>::max)()))
{ {
current = value; runLength++;
runLength = 1;
firstTime = false;
} }
else else
{ {
if(value == current) runlengths.push_back(runLength);
{ values.push_back(current);
runLength++; current = value;
} runLength = 1;
else }
{
//stream.write(reinterpret_cast<char*>(&current), sizeof(current));
//stream.write(reinterpret_cast<char*>(&runLength), sizeof(runLength));
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<uint8_t>(runlengths).swap(runlengths);
//std::vector<VoxelType>(values).swap(values);
delete[] m_tUncompressedData; delete[] m_tUncompressedData;
m_tUncompressedData = 0; m_tUncompressedData = 0;
@ -245,17 +242,32 @@ namespace PolyVox
{ {
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
VoxelType* pUncompressedData = m_tUncompressedData; 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]; memset(pUncompressedData, *((int*)(&values[ct])), runlengths[ct]);
++pUncompressedData; 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; m_bIsCompressed = false;
} }

View File

@ -388,7 +388,7 @@ namespace PolyVox
return block; return block;
} }
const uint32_t MaxUncompressedBlocks = 1000; const uint32_t MaxUncompressedBlocks = 10;
if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks) if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks)
{ {
Block<VoxelType>* pLeastRecentlyUsedBlock = 0; Block<VoxelType>* pLeastRecentlyUsedBlock = 0;