Splitting 'Block into CompressedBlock and UncompressedBlock.
This commit is contained in:
		| @@ -52,6 +52,26 @@ namespace PolyVox | ||||
| 		uint32_t m_uCompressedDataLength; | ||||
| 		uint32_t timestamp; | ||||
| 	}; | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
|     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" | ||||
|   | ||||
| @@ -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 <typename VoxelType> | ||||
| 	CompressedBlock<VoxelType>::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 <typename VoxelType> | ||||
| 	uint32_t CompressedBlock<VoxelType>::getCompressedDataLength(void) const | ||||
| 	{ | ||||
| @@ -92,4 +94,83 @@ namespace PolyVox | ||||
| 		uint32_t uSizeInBytes = sizeof(CompressedBlock<VoxelType>) + m_uCompressedDataLength; | ||||
| 		return  uSizeInBytes; | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	UncompressedBlock<VoxelType>::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 <typename VoxelType> | ||||
| 	UncompressedBlock<VoxelType>::~UncompressedBlock() | ||||
| 	{ | ||||
| 		delete m_tUncompressedData; | ||||
| 		m_tUncompressedData = 0; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	uint16_t UncompressedBlock<VoxelType>::getSideLength(void) const | ||||
| 	{ | ||||
| 		return m_uSideLength; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType UncompressedBlock<VoxelType>::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 <typename VoxelType> | ||||
| 	VoxelType UncompressedBlock<VoxelType>::getVoxel(const Vector3DUint16& v3dPos) const | ||||
| 	{ | ||||
| 		return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	void UncompressedBlock<VoxelType>::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 <typename VoxelType> | ||||
|     void UncompressedBlock<VoxelType>::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) | ||||
|     { | ||||
| 		setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -330,16 +330,16 @@ namespace PolyVox | ||||
| 		VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const; | ||||
| 	 | ||||
| 		CompressedBlock<VoxelType>* getCompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; | ||||
| 		VoxelType* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; | ||||
| 		UncompressedBlock<VoxelType>* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; | ||||
| 		void eraseBlock(typename std::map<Vector3DInt32, CompressedBlock<VoxelType>, BlockPositionCompare>::iterator itBlock) const; | ||||
|  | ||||
| 		// The block data | ||||
| 		mutable std::map<Vector3DInt32, VoxelType*, BlockPositionCompare> m_pUncompressedBlockCache; | ||||
| 		mutable std::map<Vector3DInt32, UncompressedBlock<VoxelType>*, BlockPositionCompare> m_pUncompressedBlockCache; | ||||
| 		mutable std::map<Vector3DInt32, CompressedBlock<VoxelType>, BlockPositionCompare> m_pBlocks; | ||||
|  | ||||
| 		mutable uint32_t m_uTimestamper; | ||||
| 		mutable Vector3DInt32 m_v3dLastAccessedBlockPos; | ||||
| 		mutable VoxelType* m_pLastAccessedBlock; | ||||
| 		mutable UncompressedBlock<VoxelType>* m_pLastAccessedBlock; | ||||
| 		uint32_t m_uMaxNumberOfUncompressedBlocks; | ||||
|  | ||||
| 		uint32_t m_uCompressedBlockMemoryLimitInBytes; | ||||
|   | ||||
| @@ -223,14 +223,9 @@ namespace PolyVox | ||||
| 			const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); | ||||
| 			const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower)); | ||||
|  | ||||
| 			VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
| 			const UncompressedBlock<VoxelType>* 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<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); | ||||
| 		const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower)); | ||||
|  | ||||
| 		VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
|  | ||||
| 		pUncompressedBlock | ||||
| 		[ | ||||
| 			xOffset +  | ||||
| 			yOffset * m_uBlockSideLength +  | ||||
| 			zOffset * m_uBlockSideLength * m_uBlockSideLength | ||||
| 		] = tValue; | ||||
| 		UncompressedBlock<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
| 		pUncompressedBlock->setVoxelAt(xOffset, yOffset, zOffset); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -360,14 +349,9 @@ namespace PolyVox | ||||
| 		const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); | ||||
| 		const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower)); | ||||
|  | ||||
| 		VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
| 		UncompressedBlock<VoxelType>* 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 <typename VoxelType> | ||||
| 	VoxelType* LargeVolume<VoxelType>::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const | ||||
| 	UncompressedBlock<VoxelType>* LargeVolume<VoxelType>::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const | ||||
| 	{ | ||||
| 		Vector3DInt32 v3dBlockPos(uBlockX, uBlockY, uBlockZ); | ||||
|  | ||||
| @@ -651,14 +635,14 @@ namespace PolyVox | ||||
| 		CompressedBlock<VoxelType>* block = getCompressedBlock(uBlockX, uBlockY, uBlockZ); | ||||
|  | ||||
|  | ||||
| 		typename std::map<Vector3DInt32, VoxelType*, BlockPositionCompare>::iterator itUncompressedBlock = m_pUncompressedBlockCache.find(v3dBlockPos); | ||||
| 		typename std::map<Vector3DInt32, UncompressedBlock<VoxelType>*, 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<VoxelType>* pUncompressedBlock = new UncompressedBlock<VoxelType>(m_uBlockSideLength); | ||||
|  | ||||
| 			void* pSrcData = reinterpret_cast<void*>(block->m_pCompressedData); | ||||
| 			void* pDstData = reinterpret_cast<void*>(pUncompressedBlock); | ||||
| 			void* pDstData = reinterpret_cast<void*>(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<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); | ||||
| 		const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower)); | ||||
|  | ||||
| 		VoxelType* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
|  | ||||
| 		return pUncompressedBlock | ||||
| 		[ | ||||
| 			xOffset +  | ||||
| 			yOffset * m_uBlockSideLength +  | ||||
| 			zOffset * m_uBlockSideLength * m_uBlockSideLength | ||||
| 		]; | ||||
| 		UncompressedBlock<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ); | ||||
| 		return pUncompressedBlock->getVoxel(xOffset, yOffset, zOffset); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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<VoxelType>* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock); | ||||
|  | ||||
| 			mCurrentVoxel = pUncompressedCurrentBlock + uVoxelIndexInBlock; | ||||
| 			mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user