Splitting 'Block into CompressedBlock and UncompressedBlock.

This commit is contained in:
David Williams 2013-07-16 14:42:43 +02:00
parent a00574351f
commit 0cfb9f5196
5 changed files with 127 additions and 48 deletions

View File

@ -52,6 +52,26 @@ namespace PolyVox
uint32_t m_uCompressedDataLength; uint32_t m_uCompressedDataLength;
uint32_t timestamp; 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" #include "PolyVoxCore/Impl/Block.inl"

View File

@ -35,6 +35,8 @@ freely, subject to the following restrictions:
namespace PolyVox namespace PolyVox
{ {
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> template <typename VoxelType>
CompressedBlock<VoxelType>::CompressedBlock(uint16_t uSideLength, Compressor* pCompressor) CompressedBlock<VoxelType>::CompressedBlock(uint16_t uSideLength, Compressor* pCompressor)
:m_pCompressedData(0) :m_pCompressedData(0)
@ -92,4 +94,83 @@ namespace PolyVox
uint32_t uSizeInBytes = sizeof(CompressedBlock<VoxelType>) + m_uCompressedDataLength; uint32_t uSizeInBytes = sizeof(CompressedBlock<VoxelType>) + m_uCompressedDataLength;
return uSizeInBytes; 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);
}
} }

View File

@ -330,16 +330,16 @@ namespace PolyVox
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const; 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; 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; void eraseBlock(typename std::map<Vector3DInt32, CompressedBlock<VoxelType>, BlockPositionCompare>::iterator itBlock) const;
// The block data // 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 std::map<Vector3DInt32, CompressedBlock<VoxelType>, BlockPositionCompare> m_pBlocks;
mutable uint32_t m_uTimestamper; mutable uint32_t m_uTimestamper;
mutable Vector3DInt32 m_v3dLastAccessedBlockPos; mutable Vector3DInt32 m_v3dLastAccessedBlockPos;
mutable VoxelType* m_pLastAccessedBlock; mutable UncompressedBlock<VoxelType>* m_pLastAccessedBlock;
uint32_t m_uMaxNumberOfUncompressedBlocks; uint32_t m_uMaxNumberOfUncompressedBlocks;
uint32_t m_uCompressedBlockMemoryLimitInBytes; uint32_t m_uCompressedBlockMemoryLimitInBytes;

View File

@ -223,14 +223,9 @@ namespace PolyVox
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << 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 return pUncompressedBlock->getVoxel(xOffset, yOffset, zOffset);
[
xOffset +
yOffset * m_uBlockSideLength +
zOffset * m_uBlockSideLength * m_uBlockSideLength
];
} }
else else
{ {
@ -317,14 +312,8 @@ namespace PolyVox
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << 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->setVoxelAt(xOffset, yOffset, zOffset);
pUncompressedBlock
[
xOffset +
yOffset * m_uBlockSideLength +
zOffset * m_uBlockSideLength * m_uBlockSideLength
] = tValue;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -360,14 +349,9 @@ namespace PolyVox
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower)); const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << 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 pUncompressedBlock->setVoxelAt(xOffset, yOffset, zOffset, tValue);
[
xOffset +
yOffset * m_uBlockSideLength +
zOffset * m_uBlockSideLength * m_uBlockSideLength
] = tValue;
//Return true to indicate that we modified a voxel. //Return true to indicate that we modified a voxel.
return true; return true;
@ -634,7 +618,7 @@ namespace PolyVox
} }
template <typename VoxelType> 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); Vector3DInt32 v3dBlockPos(uBlockX, uBlockY, uBlockZ);
@ -651,14 +635,14 @@ namespace PolyVox
CompressedBlock<VoxelType>* block = getCompressedBlock(uBlockX, uBlockY, uBlockZ); 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 // check whether the block is already loaded
if(itUncompressedBlock == m_pUncompressedBlockCache.end()) 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* 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 uSrcLength = block->m_uCompressedDataLength;
uint32_t uDstLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); 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 yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << 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);
return pUncompressedBlock->getVoxel(xOffset, yOffset, zOffset);
return pUncompressedBlock
[
xOffset +
yOffset * m_uBlockSideLength +
zOffset * m_uBlockSideLength * m_uBlockSideLength
];
} }
} }

View File

@ -119,9 +119,9 @@ namespace PolyVox
uYPosInBlock * this->mVolume->m_uBlockSideLength + uYPosInBlock * this->mVolume->m_uBlockSideLength +
uZPosInBlock * this->mVolume->m_uBlockSideLength * 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 else
{ {