Added ability to disable volume compression.

This commit is contained in:
David Williams 2011-03-20 18:56:30 +00:00
parent 350d4a6a87
commit 708b142702
2 changed files with 46 additions and 24 deletions

View File

@ -143,7 +143,7 @@ namespace PolyVox
const Region& regValid, const Region& regValid,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
bool bStreamingEnabled = false, bool bPagingEnabled = false,
uint16_t uBlockSideLength = 32 uint16_t uBlockSideLength = 32
); );
/// Constructor /// Constructor
@ -152,7 +152,7 @@ namespace PolyVox
int32_t uWidth, int32_t uHeight, int32_t uDepth, int32_t uWidth, int32_t uHeight, int32_t uDepth,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
bool bStreamingEnabled = false, bool bPagingEnabled = false,
uint16_t uBlockSideLength = 32 uint16_t uBlockSideLength = 32
); );
/// Destructor /// Destructor
@ -179,6 +179,7 @@ namespace PolyVox
/// Gets a voxel by 3D vector position /// Gets a voxel by 3D vector position
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const; VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
void setCompressionEnabled(bool bCompressionEnabled);
/// Sets the number of blocks for which uncompressed data is stored. /// Sets the number of blocks for which uncompressed data is stored.
void setMaxNumberOfUncompressedBlocks(uint16_t uMaxNumberOfUncompressedBlocks); void setMaxNumberOfUncompressedBlocks(uint16_t uMaxNumberOfUncompressedBlocks);
/// Sets the number of blocks which can be in memory before unload is called /// Sets the number of blocks which can be in memory before unload is called
@ -246,7 +247,8 @@ private:
int32_t m_uShortestSideLength; int32_t m_uShortestSideLength;
float m_fDiagonalLength; float m_fDiagonalLength;
bool m_bStreamingEnabled; bool m_bCompressionEnabled;
bool m_bPagingEnabled;
}; };
} }

View File

@ -58,7 +58,7 @@ namespace PolyVox
{ {
m_funcDataRequiredHandler = dataRequiredHandler; m_funcDataRequiredHandler = dataRequiredHandler;
m_funcDataOverflowHandler = dataOverflowHandler; m_funcDataOverflowHandler = dataOverflowHandler;
m_bStreamingEnabled = true; m_bPagingEnabled = true;
//Create a volume of the right size. //Create a volume of the right size.
resize(Region::MaxRegion,uBlockSideLength); resize(Region::MaxRegion,uBlockSideLength);
} }
@ -81,13 +81,13 @@ namespace PolyVox
int32_t uWidth, int32_t uHeight, int32_t uDepth, int32_t uWidth, int32_t uHeight, int32_t uDepth,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
bool bStreamingEnabled, bool bPagingEnabled,
uint16_t uBlockSideLength uint16_t uBlockSideLength
) )
{ {
m_funcDataRequiredHandler = dataRequiredHandler; m_funcDataRequiredHandler = dataRequiredHandler;
m_funcDataOverflowHandler = dataOverflowHandler; m_funcDataOverflowHandler = dataOverflowHandler;
m_bStreamingEnabled = bStreamingEnabled; m_bPagingEnabled = bPagingEnabled;
Region regValid(Vector3DInt32(0,0,0), Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1)); Region regValid(Vector3DInt32(0,0,0), Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1));
resize(Region(Vector3DInt32(0,0,0), Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1)), uBlockSideLength); resize(Region(Vector3DInt32(0,0,0), Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1)), uBlockSideLength);
@ -111,13 +111,13 @@ namespace PolyVox
const Region& regValid, const Region& regValid,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler, polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
bool bStreamingEnabled, bool bPagingEnabled,
uint16_t uBlockSideLength uint16_t uBlockSideLength
) )
{ {
m_funcDataRequiredHandler = dataRequiredHandler; m_funcDataRequiredHandler = dataRequiredHandler;
m_funcDataOverflowHandler = dataOverflowHandler; m_funcDataOverflowHandler = dataOverflowHandler;
m_bStreamingEnabled = bStreamingEnabled; m_bPagingEnabled = bPagingEnabled;
//Create a volume of the right size. //Create a volume of the right size.
resize(regValid,uBlockSideLength); resize(regValid,uBlockSideLength);
@ -261,6 +261,26 @@ namespace PolyVox
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
} }
template <typename VoxelType>
void Volume<VoxelType>::setCompressionEnabled(bool bCompressionEnabled)
{
//Early out - nothing to do
if(m_bCompressionEnabled == bCompressionEnabled)
{
return;
}
m_bCompressionEnabled = bCompressionEnabled;
if(m_bCompressionEnabled)
{
//If compression has been enabled then we need to start honouring the max number of
//uncompressed blocks. Because compression has been disabled for a while we might have
//gone above that limit. Easiest solution is just to clear the cache and start again.
clearBlockCache();
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// Increasing the size of the block cache will increase memory but may improve performance. /// Increasing the size of the block cache will increase memory but may improve performance.
/// You may want to set this to a large value (e.g. 1024) when you are first loading your /// You may want to set this to a large value (e.g. 1024) when you are first loading your
@ -398,8 +418,9 @@ namespace PolyVox
m_uBlockSideLength = uBlockSideLength; m_uBlockSideLength = uBlockSideLength;
m_pUncompressedBorderData = 0; m_pUncompressedBorderData = 0;
m_uMaxNumberOfBlocksInMemory = 1024; m_uMaxNumberOfBlocksInMemory = 1024;
m_v3dLastAccessedBlockPos = Vector3DInt32((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)()); //An invalid index m_v3dLastAccessedBlockPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedBlock pointer will be null;
m_pLastAccessedBlock = 0; m_pLastAccessedBlock = 0;
m_bCompressionEnabled = true;
m_regValidRegion = regValidRegion; m_regValidRegion = regValidRegion;
@ -491,7 +512,7 @@ namespace PolyVox
//The block is not in the map, so we will have to create a new block and add it. //The block is not in the map, so we will have to create a new block and add it.
//Before we do so, we might want to dump some existing data to make space. We //Before we do so, we might want to dump some existing data to make space. We
//Only do this if paging is enabled. //Only do this if paging is enabled.
if(m_bStreamingEnabled) if(m_bPagingEnabled)
{ {
// check wether another block needs to be unloaded before this one can be loaded // check wether another block needs to be unloaded before this one can be loaded
if(m_pBlocks.size() == m_uMaxNumberOfBlocksInMemory) if(m_pBlocks.size() == m_uMaxNumberOfBlocksInMemory)
@ -516,7 +537,7 @@ namespace PolyVox
//We have created the new block. If paging is enabled it should be used to //We have created the new block. If paging is enabled it should be used to
//fill in the required data. Otherwise it is just left in the default state. //fill in the required data. Otherwise it is just left in the default state.
if(m_bStreamingEnabled) if(m_bPagingEnabled)
{ {
if(m_funcDataRequiredHandler) if(m_funcDataRequiredHandler)
{ {
@ -544,15 +565,15 @@ namespace PolyVox
return m_pLastAccessedBlock; return m_pLastAccessedBlock;
} }
//If we are allowed to compress then check whether we need to
if((m_bCompressionEnabled) && (m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks))
{
int32_t leastRecentlyUsedBlockIndex = -1;
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)();
//Currently we find the oldest block by iterating over the whole array. Of course we could store the blocks sorted by //Currently we find the oldest block by iterating over the whole array. Of course we could store the blocks sorted by
//timestamp (set, priority_queue, etc) but then we'll need to move them around as the timestamp changes. Can come back //timestamp (set, priority_queue, etc) but then we'll need to move them around as the timestamp changes. Can come back
//to this if it proves to be a bottleneck (compraed to the cost of actually doing the compression/decompression). //to this if it proves to be a bottleneck (compraed to the cost of actually doing the compression/decompression).
uint32_t uUncompressedBlockIndex = (std::numeric_limits<uint32_t>::max)();
assert(m_vecUncompressedBlockCache.size() <= m_uMaxNumberOfUncompressedBlocks);
if(m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks)
{
int32_t leastRecentlyUsedBlockIndex = -1;
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)(); // you said not int64 ;)
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++) for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
{ {
if(m_vecUncompressedBlockCache[ct]->timestamp < uLeastRecentTimestamp) if(m_vecUncompressedBlockCache[ct]->timestamp < uLeastRecentTimestamp)
@ -562,20 +583,19 @@ namespace PolyVox
} }
} }
uUncompressedBlockIndex = leastRecentlyUsedBlockIndex; //Compress the least recently used block.
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress(); m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress();
//We don't actually remove any elements from this vector, we
//simply change the pointer to point at the new uncompressed bloack.
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex] = &loadedBlock; m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex] = &loadedBlock;
//m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.m_tUncompressedData = 0;
} }
else else
{ {
//loadedBlock.block.m_tUncompressedData = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength];
m_vecUncompressedBlockCache.push_back(&loadedBlock); m_vecUncompressedBlockCache.push_back(&loadedBlock);
uUncompressedBlockIndex = m_vecUncompressedBlockCache.size() - 1;
} }
loadedBlock.block.uncompress(); loadedBlock.block.uncompress();
//m_vecUncompressedBlockCache.push_back(&loadedBlock);
m_pLastAccessedBlock = &(loadedBlock.block); m_pLastAccessedBlock = &(loadedBlock.block);
assert(m_pLastAccessedBlock->m_tUncompressedData); assert(m_pLastAccessedBlock->m_tUncompressedData);