Splitting 'Block into CompressedBlock and UncompressedBlock.
This commit is contained in:
parent
a00574351f
commit
0cfb9f5196
@ -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"
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user