From 0cfb9f51961324d533d52deeb04a3e3da2198729 Mon Sep 17 00:00:00 2001 From: David Williams Date: Tue, 16 Jul 2013 14:42:43 +0200 Subject: [PATCH] Splitting 'Block into CompressedBlock and UncompressedBlock. --- .../include/PolyVoxCore/Impl/Block.h | 20 ++++ .../include/PolyVoxCore/Impl/Block.inl | 99 +++++++++++++++++-- .../include/PolyVoxCore/LargeVolume.h | 6 +- .../include/PolyVoxCore/LargeVolume.inl | 46 +++------ .../PolyVoxCore/LargeVolumeSampler.inl | 4 +- 5 files changed, 127 insertions(+), 48 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.h index f9ce6f3c..edd3a893 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.h @@ -52,6 +52,26 @@ namespace PolyVox uint32_t m_uCompressedDataLength; uint32_t timestamp; }; + + template + class UncompressedBlock + { + public: + UncompressedBlock(uint16_t uSideLength); + ~UncompressedBlock(); + + uint16_t getSideLength(void) const; + VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const; + VoxelType getVoxel(const Vector3DUint16& v3dPos) const; + + void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue); + void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); + + VoxelType* m_tUncompressedData; + uint16_t m_uSideLength; + uint8_t m_uSideLengthPower; + bool m_bIsUncompressedDataModified; + }; } #include "PolyVoxCore/Impl/Block.inl" diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.inl b/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.inl index 8f54c9a3..19f50146 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Block.inl @@ -9,16 +9,16 @@ Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. - 3. This notice may not be removed or altered from any source - distribution. +3. This notice may not be removed or altered from any source +distribution. *******************************************************************************/ #include "PolyVoxCore/Impl/ErrorHandling.h" @@ -35,6 +35,8 @@ freely, subject to the following restrictions: namespace PolyVox { + //////////////////////////////////////////////////////////////////////////////// + template CompressedBlock::CompressedBlock(uint16_t uSideLength, Compressor* pCompressor) :m_pCompressedData(0) @@ -63,7 +65,7 @@ namespace PolyVox POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL"); return m_pCompressedData; } - + template uint32_t CompressedBlock::getCompressedDataLength(void) const { @@ -92,4 +94,83 @@ namespace PolyVox uint32_t uSizeInBytes = sizeof(CompressedBlock) + m_uCompressedDataLength; return uSizeInBytes; } + + //////////////////////////////////////////////////////////////////////////////// + + template + UncompressedBlock::UncompressedBlock(uint16_t uSideLength) + :m_tUncompressedData(0) + ,m_uSideLength(0) + ,m_uSideLengthPower(0) + ,m_bIsUncompressedDataModified(true) + { + // Compute the side length + m_uSideLength = uSideLength; + m_uSideLengthPower = logBase2(uSideLength); + + // Allocate the data + const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; + m_tUncompressedData = new VoxelType[uNoOfVoxels]; + } + + template + UncompressedBlock::~UncompressedBlock() + { + delete m_tUncompressedData; + m_tUncompressedData = 0; + } + + template + uint16_t UncompressedBlock::getSideLength(void) const + { + return m_uSideLength; + } + + template + VoxelType UncompressedBlock::getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const + { + // This is internal code not directly called by the user. For efficiency we assert rather than throwing. + POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels."); + + return m_tUncompressedData + [ + uXPos + + uYPos * m_uSideLength + + uZPos * m_uSideLength * m_uSideLength + ]; + } + + template + VoxelType UncompressedBlock::getVoxel(const Vector3DUint16& v3dPos) const + { + return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); + } + + template + void UncompressedBlock::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue) + { + // This is internal code not directly called by the user. For efficiency we assert rather than throwing. + POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block"); + POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels."); + + m_tUncompressedData + [ + uXPos + + uYPos * m_uSideLength + + uZPos * m_uSideLength * m_uSideLength + ] = tValue; + + m_bIsUncompressedDataModified = true; + } + + template + void UncompressedBlock::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) + { + setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); + } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index c4d3c777..65e9dec4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -330,16 +330,16 @@ namespace PolyVox VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType, VoxelType tBorder) const; CompressedBlock* getCompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; - VoxelType* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; + UncompressedBlock* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; void eraseBlock(typename std::map, BlockPositionCompare>::iterator itBlock) const; // The block data - mutable std::map m_pUncompressedBlockCache; + mutable std::map*, BlockPositionCompare> m_pUncompressedBlockCache; mutable std::map, BlockPositionCompare> m_pBlocks; mutable uint32_t m_uTimestamper; mutable Vector3DInt32 m_v3dLastAccessedBlockPos; - mutable VoxelType* m_pLastAccessedBlock; + mutable UncompressedBlock* m_pLastAccessedBlock; uint32_t m_uMaxNumberOfUncompressedBlocks; uint32_t m_uCompressedBlockMemoryLimitInBytes; diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index ff72cde0..3357f60c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -223,14 +223,9 @@ namespace PolyVox const uint16_t yOffset = static_cast(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t zOffset = static_cast(uZPos - (blockZ << m_uBlockSideLengthPower)); - VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); + const UncompressedBlock* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); - return pUncompressedBlock - [ - xOffset + - yOffset * m_uBlockSideLength + - zOffset * m_uBlockSideLength * m_uBlockSideLength - ]; + return pUncompressedBlock->getVoxel(xOffset, yOffset, zOffset); } else { @@ -317,14 +312,8 @@ namespace PolyVox const uint16_t yOffset = static_cast(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t zOffset = static_cast(uZPos - (blockZ << m_uBlockSideLengthPower)); - VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); - - pUncompressedBlock - [ - xOffset + - yOffset * m_uBlockSideLength + - zOffset * m_uBlockSideLength * m_uBlockSideLength - ] = tValue; + UncompressedBlock* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); + pUncompressedBlock->setVoxelAt(xOffset, yOffset, zOffset); } //////////////////////////////////////////////////////////////////////////////// @@ -360,14 +349,9 @@ namespace PolyVox const uint16_t yOffset = static_cast(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t zOffset = static_cast(uZPos - (blockZ << m_uBlockSideLengthPower)); - VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); + UncompressedBlock* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); - pUncompressedBlock - [ - xOffset + - yOffset * m_uBlockSideLength + - zOffset * m_uBlockSideLength * m_uBlockSideLength - ] = tValue; + pUncompressedBlock->setVoxelAt(xOffset, yOffset, zOffset, tValue); //Return true to indicate that we modified a voxel. return true; @@ -634,7 +618,7 @@ namespace PolyVox } template - VoxelType* LargeVolume::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const + UncompressedBlock* LargeVolume::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const { Vector3DInt32 v3dBlockPos(uBlockX, uBlockY, uBlockZ); @@ -651,14 +635,14 @@ namespace PolyVox CompressedBlock* block = getCompressedBlock(uBlockX, uBlockY, uBlockZ); - typename std::map::iterator itUncompressedBlock = m_pUncompressedBlockCache.find(v3dBlockPos); + typename std::map*, BlockPositionCompare>::iterator itUncompressedBlock = m_pUncompressedBlockCache.find(v3dBlockPos); // check whether the block is already loaded if(itUncompressedBlock == m_pUncompressedBlockCache.end()) { - VoxelType* pUncompressedBlock = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength]; + UncompressedBlock* pUncompressedBlock = new UncompressedBlock(m_uBlockSideLength); void* pSrcData = reinterpret_cast(block->m_pCompressedData); - void* pDstData = reinterpret_cast(pUncompressedBlock); + void* pDstData = reinterpret_cast(pUncompressedBlock->m_tUncompressedData); uint32_t uSrcLength = block->m_uCompressedDataLength; uint32_t uDstLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); @@ -816,14 +800,8 @@ namespace PolyVox const uint16_t yOffset = static_cast(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t zOffset = static_cast(uZPos - (blockZ << m_uBlockSideLengthPower)); - VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); - - return pUncompressedBlock - [ - xOffset + - yOffset * m_uBlockSideLength + - zOffset * m_uBlockSideLength * m_uBlockSideLength - ]; + UncompressedBlock* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); + return pUncompressedBlock->getVoxel(xOffset, yOffset, zOffset); } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl index d90ea5f4..8bbad0f4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolumeSampler.inl @@ -119,9 +119,9 @@ namespace PolyVox uYPosInBlock * this->mVolume->m_uBlockSideLength + uZPosInBlock * this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength; - VoxelType* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock); + UncompressedBlock* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock); - mCurrentVoxel = pUncompressedCurrentBlock + uVoxelIndexInBlock; + mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock; } else {