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 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"

View File

@ -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)
@ -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);
}
}

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;
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;

View File

@ -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);
}
}

View File

@ -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
{