From 3cc2e4383f6918b152fa0f6c6f3437543d1d12b3 Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 18 Mar 2011 23:54:11 +0000 Subject: [PATCH] Some refactoring of the volume. --- .../include/PolyVoxForwardDeclarations.h | 3 - .../PolyVoxCore/include/PolyVoxImpl/Block.h | 3 - .../PolyVoxCore/include/PolyVoxImpl/Block.inl | 2 - library/PolyVoxCore/include/Volume.h | 28 +++---- library/PolyVoxCore/include/Volume.inl | 77 +++++++++---------- 5 files changed, 51 insertions(+), 62 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxForwardDeclarations.h index ec112630..a97af60b 100644 --- a/library/PolyVoxCore/include/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxForwardDeclarations.h @@ -64,9 +64,6 @@ namespace PolyVox //---------- Volume ---------- template class Volume; - typedef Volume FloatVolume; - typedef Volume UInt8Volume; - typedef Volume UInt16Volume; //--------------------------------- //---------- Mesh ---------- diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.h b/library/PolyVoxCore/include/PolyVoxImpl/Block.h index 5503252b..ca166e7c 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.h @@ -70,9 +70,6 @@ namespace PolyVox uint8_t m_uSideLengthPower; bool m_bIsCompressed; bool m_bIsUncompressedDataModified; - uint32_t m_uTimestamp; - uint32_t m_uUncompressedIndex; - }; } diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl index 62d4c4c6..27bdd064 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl @@ -39,8 +39,6 @@ namespace PolyVox ,m_tUncompressedData(NULL) ,m_bIsCompressed(true) ,m_bIsUncompressedDataModified(true) - ,m_uTimestamp(0) - ,m_uUncompressedIndex((std::numeric_limits::max)()) { if(uSideLength != 0) { diff --git a/library/PolyVoxCore/include/Volume.h b/library/PolyVoxCore/include/Volume.h index c3e72979..a9f07f18 100644 --- a/library/PolyVoxCore/include/Volume.h +++ b/library/PolyVoxCore/include/Volume.h @@ -116,11 +116,19 @@ namespace PolyVox // Make the ConstVolumeProxy a friend friend class ConstVolumeProxy; - struct UncompressedBlock + struct LoadedBlock { - Vector3DInt32 v3dBlockIndex; - VoxelType* data; + public: + LoadedBlock(uint16_t uSideLength = 0) + :block(uSideLength) + ,uncompressedData(0) + ,timestamp(0) + { + } + Block block; + VoxelType* uncompressedData; + uint32_t timestamp; }; public: @@ -182,22 +190,21 @@ namespace PolyVox polyvox_function&, const Region&)> dataOverflowHandler; private: Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; - void eraseBlock(typename std::map >::iterator itBlock) const; + void eraseBlock(typename std::map::iterator itBlock) const; /// this function can be called by dataRequiredHandler without causing any weird effects bool setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const; //The block data - mutable std::map > m_pBlocks; + mutable std::map m_pBlocks; //The cache of uncompressed blocks. The uncompressed block data and the timestamps are stored here rather //than in the Block class. This is so that in the future each VolumeIterator might to maintain its own cache //of blocks. However, this could mean the same block data is uncompressed and modified in more than one //location in memory... could be messy with threading. - mutable std::vector< UncompressedBlock > m_vecUncompressedBlockCache; - mutable std::vector m_pUncompressedTimestamps; + mutable std::vector< LoadedBlock* > m_vecUncompressedBlockCache; mutable uint32_t m_uTimestamper; mutable Vector3DInt32 m_v3dLastAccessedBlockPos; - mutable Block* m_pLastAccessedBlock; + mutable LoadedBlock* m_pLastAccessedBlock; uint32_t m_uMaxUncompressedBlockCacheSize; uint32_t m_uMaxBlocksLoaded; @@ -220,11 +227,6 @@ namespace PolyVox int32_t m_uShortestSideLength; float m_fDiagonalLength; }; - - //Some handy typedefs - typedef Volume FloatVolume; - typedef Volume UInt8Volume; - typedef Volume UInt16Volume; } #include "Volume.inl" diff --git a/library/PolyVoxCore/include/Volume.inl b/library/PolyVoxCore/include/Volume.inl index 0754f4c1..91f5f38f 100644 --- a/library/PolyVoxCore/include/Volume.inl +++ b/library/PolyVoxCore/include/Volume.inl @@ -99,7 +99,7 @@ namespace PolyVox template Volume::~Volume() { - typename std::map >::iterator i; + typename std::map::iterator i; for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i = m_pBlocks.begin()) { eraseBlock(i); } @@ -255,11 +255,14 @@ namespace PolyVox if(uMaxBlocks < m_pBlocks.size()) { std::cout << uMaxBlocks << ", " << m_pBlocks.size() << ", " << m_pBlocks.size() - uMaxBlocks << std::endl; // we need to unload some blocks - for(int j = 0; j < m_pBlocks.size() - uMaxBlocks; j++) { - typename std::map >::iterator i; - typename std::map >::iterator itUnloadBlock = m_pBlocks.begin(); - for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) { - if(i->second.m_uTimestamp < itUnloadBlock->second.m_uTimestamp) { + for(int j = 0; j < m_pBlocks.size() - uMaxBlocks; j++) + { + typename std::map::iterator i; + typename std::map::iterator itUnloadBlock = m_pBlocks.begin(); + for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) + { + if(i->second.timestamp < itUnloadBlock->second.timestamp) + { itUnloadBlock = i; } } @@ -324,8 +327,8 @@ namespace PolyVox { for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++) { - m_pBlocks[m_vecUncompressedBlockCache[ct].v3dBlockIndex].compress(); - delete[] m_vecUncompressedBlockCache[ct].data; + m_vecUncompressedBlockCache[ct]->block.compress(); + delete[] m_vecUncompressedBlockCache[ct]->uncompressedData; } m_vecUncompressedBlockCache.clear(); } @@ -375,7 +378,6 @@ namespace PolyVox //Clear the previous data m_pBlocks.clear(); - m_pUncompressedTimestamps.clear(); //Compute the block side length m_uBlockSideLength = uBlockSideLength; @@ -383,9 +385,6 @@ namespace PolyVox //Clear the previous data m_pBlocks.clear(); - m_pUncompressedTimestamps.clear(); - - m_pUncompressedTimestamps.resize(m_uMaxUncompressedBlockCacheSize, 0); //Create the border block m_pUncompressedBorderData = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength]; @@ -398,7 +397,7 @@ namespace PolyVox } template - void Volume::eraseBlock(typename std::map >::iterator itBlock) const + void Volume::eraseBlock(typename std::map::iterator itBlock) const { if(dataOverflowHandler) { @@ -449,10 +448,10 @@ namespace PolyVox //This check should also provide a significant speed boost as usually it is true. if((v3dBlockPos == m_v3dLastAccessedBlockPos) && (m_pLastAccessedBlock != 0)) { - return m_pLastAccessedBlock; + return &(m_pLastAccessedBlock->block); } - typename std::map >::iterator itBlock = m_pBlocks.find(v3dBlockPos); + typename std::map::iterator itBlock = m_pBlocks.find(v3dBlockPos); // check whether the block is already loaded if(itBlock == m_pBlocks.end()) { @@ -461,11 +460,11 @@ namespace PolyVox if(m_pBlocks.size() == m_uMaxBlocksLoaded) { // find the least recently used block - typename std::map >::iterator i; - typename std::map >::iterator itUnloadBlock = m_pBlocks.begin(); + typename std::map::iterator i; + typename std::map::iterator itUnloadBlock = m_pBlocks.begin(); for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) { - if(i->second.m_uTimestamp < itUnloadBlock->second.m_uTimestamp) + if(i->second.timestamp < itUnloadBlock->second.timestamp) { itUnloadBlock = i; } @@ -476,7 +475,7 @@ namespace PolyVox Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1); // create the new block - Block newBlock(m_uBlockSideLength); + LoadedBlock newBlock(m_uBlockSideLength); itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first; // fill it with data (well currently fill it with nothingness) @@ -494,16 +493,15 @@ namespace PolyVox m_v3dLastAccessedBlockPos = v3dBlockPos; //Get the block - Block* block = &(itBlock->second); + LoadedBlock* block = &(itBlock->second); m_uTimestamper++; - block->m_uTimestamp = m_uTimestamper; + block->timestamp = m_uTimestamper; - if(block->m_bIsCompressed == false) + if(block->block.m_bIsCompressed == false) { - m_pUncompressedTimestamps[block->m_uUncompressedIndex] = m_uTimestamper; m_pLastAccessedBlock = block; - return block; + return &(block->block); } //Currently we find the oldest block by iterating over the whole array. Of course we could store the blocks sorted by @@ -517,31 +515,27 @@ namespace PolyVox uint32_t uLeastRecentTimestamp = (std::numeric_limits::max)(); // you said not int64 ;) for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++) { - if(m_pUncompressedTimestamps[ct] < uLeastRecentTimestamp) + if(m_vecUncompressedBlockCache[ct]->timestamp < uLeastRecentTimestamp) { - uLeastRecentTimestamp = m_pUncompressedTimestamps[ct]; + uLeastRecentTimestamp = m_vecUncompressedBlockCache[ct]->timestamp; leastRecentlyUsedBlockIndex = ct; } } uUncompressedBlockIndex = leastRecentlyUsedBlockIndex; - m_pBlocks[m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex].v3dBlockIndex].compress(); - m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex].v3dBlockIndex = v3dBlockPos; + m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress(); + m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->uncompressedData = 0; } else { - UncompressedBlock uncompressedBlock; - //uncompressedBlock.block = block; - uncompressedBlock.v3dBlockIndex = v3dBlockPos; - uncompressedBlock.data = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength]; - m_vecUncompressedBlockCache.push_back(uncompressedBlock); + block->uncompressedData = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength]; + m_vecUncompressedBlockCache.push_back(block); uUncompressedBlockIndex = m_vecUncompressedBlockCache.size() - 1; } - block->m_uUncompressedIndex = uUncompressedBlockIndex; - block->uncompress(m_vecUncompressedBlockCache[uUncompressedBlockIndex].data); + block->block.uncompress(block->uncompressedData); m_pLastAccessedBlock = block; - return block; + return &(block->block); } template @@ -558,15 +552,16 @@ namespace PolyVox uint32_t uSizeInBytes = sizeof(Volume); //Memory used by the blocks - typename std::map >::iterator i; - for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) { - i->second.calculateSizeInBytes(); + typename std::map::iterator i; + for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++) + { + //Inaccurate - account for rest of loaded block. + uSizeInBytes += i->second.block.calculateSizeInBytes(); } //Memory used by the block cache. - uSizeInBytes += m_vecUncompressedBlockCache.capacity() * sizeof(UncompressedBlock); + uSizeInBytes += m_vecUncompressedBlockCache.capacity() * sizeof(LoadedBlock); uSizeInBytes += m_vecUncompressedBlockCache.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); - uSizeInBytes += m_pUncompressedTimestamps.capacity() * sizeof(uint32_t); //Memory used by border data. if(m_pUncompressedBorderData)