Tidying up block classes.

This commit is contained in:
David Williams 2013-07-16 16:50:04 +02:00
parent b5d930062b
commit dea7e6a4e9
4 changed files with 40 additions and 23 deletions

View File

@ -47,13 +47,19 @@ namespace PolyVox
} }
protected: protected:
// This is updated by the LargeVolume and used to discard the least recently used blocks.
uint32_t m_uBlockLastAccessed; uint32_t m_uBlockLastAccessed;
// This is so we can tell whether a uncompressed block has to be recompressed and whether
// a compressed block has to be paged back to disk, or whether they can just be discarded.
bool m_bDataModified; bool m_bDataModified;
}; };
template <typename VoxelType> template <typename VoxelType>
class CompressedBlock : public Block<VoxelType> class CompressedBlock : public Block<VoxelType>
{ {
friend LargeVolume<VoxelType>;
public: public:
CompressedBlock(); CompressedBlock();
~CompressedBlock(); ~CompressedBlock();
@ -63,9 +69,11 @@ namespace PolyVox
void setData(const uint8_t* const pData, uint32_t uDataSizeInBytes); void setData(const uint8_t* const pData, uint32_t uDataSizeInBytes);
private:
// Made this private to avoid any confusion with getDataSizeInBytes().
// Users shouldn't really need this for CompressedBlock anyway.
uint32_t calculateSizeInBytes(void); uint32_t calculateSizeInBytes(void);
private:
uint8_t* m_pData; uint8_t* m_pData;
uint32_t m_uDataSizeInBytes; uint32_t m_uDataSizeInBytes;
}; };
@ -73,18 +81,24 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
class UncompressedBlock : public Block<VoxelType> class UncompressedBlock : public Block<VoxelType>
{ {
friend LargeVolume<VoxelType>;
public: public:
UncompressedBlock(uint16_t uSideLength); UncompressedBlock(uint16_t uSideLength);
~UncompressedBlock(); ~UncompressedBlock();
uint16_t getSideLength(void) const;
VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const; VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
VoxelType getVoxel(const Vector3DUint16& v3dPos) const; VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue); void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
VoxelType* m_tUncompressedData; private:
// Made this private for consistancy with CompressedBlock.
// Users shouldn't really need this for UncompressedBlock anyway.
uint32_t calculateSizeInBytes(void);
VoxelType* m_tData;
uint16_t m_uSideLength; uint16_t m_uSideLength;
uint8_t m_uSideLengthPower; uint8_t m_uSideLengthPower;
}; };

View File

@ -86,8 +86,7 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
uint32_t CompressedBlock<VoxelType>::calculateSizeInBytes(void) uint32_t CompressedBlock<VoxelType>::calculateSizeInBytes(void)
{ {
// Returns the size of this class plus the size of the compressed data. It // Returns the size of this class plus the size of the compressed data.
// doesn't include the uncompressed data cache as that is owned by the volume.
uint32_t uSizeInBytes = sizeof(CompressedBlock<VoxelType>) + m_uDataSizeInBytes; uint32_t uSizeInBytes = sizeof(CompressedBlock<VoxelType>) + m_uDataSizeInBytes;
return uSizeInBytes; return uSizeInBytes;
} }
@ -96,7 +95,7 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
UncompressedBlock<VoxelType>::UncompressedBlock(uint16_t uSideLength) UncompressedBlock<VoxelType>::UncompressedBlock(uint16_t uSideLength)
:m_tUncompressedData(0) :m_tData(0)
,m_uSideLength(0) ,m_uSideLength(0)
,m_uSideLengthPower(0) ,m_uSideLengthPower(0)
{ {
@ -106,32 +105,27 @@ namespace PolyVox
// Allocate the data // Allocate the data
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
m_tUncompressedData = new VoxelType[uNoOfVoxels]; m_tData = new VoxelType[uNoOfVoxels];
} }
template <typename VoxelType> template <typename VoxelType>
UncompressedBlock<VoxelType>::~UncompressedBlock() UncompressedBlock<VoxelType>::~UncompressedBlock()
{ {
delete m_tUncompressedData; delete m_tData;
m_tUncompressedData = 0; m_tData = 0;
}
template <typename VoxelType>
uint16_t UncompressedBlock<VoxelType>::getSideLength(void) const
{
return m_uSideLength;
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType UncompressedBlock<VoxelType>::getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const 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. // This code is not usually expected to be called by the user, with the exception of when implementing paging
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block"); 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(uYPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uZPos < 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."); POLYVOX_ASSERT(m_tData, "No uncompressed data - block must be decompressed before accessing voxels.");
return m_tUncompressedData return m_tData
[ [
uXPos + uXPos +
uYPos * m_uSideLength + uYPos * m_uSideLength +
@ -148,13 +142,14 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void UncompressedBlock<VoxelType>::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue) 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. // This code is not usually expected to be called by the user, with the exception of when implementing paging
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block"); 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(uYPos < m_uSideLength, "Supplied position is outside of the block");
POLYVOX_ASSERT(uZPos < 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."); POLYVOX_ASSERT(m_tData, "No uncompressed data - block must be decompressed before accessing voxels.");
m_tUncompressedData m_tData
[ [
uXPos + uXPos +
uYPos * m_uSideLength + uYPos * m_uSideLength +
@ -169,4 +164,12 @@ namespace PolyVox
{ {
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
} }
template <typename VoxelType>
uint32_t UncompressedBlock<VoxelType>::calculateSizeInBytes(void)
{
// Returns the size of this class plus the size of the uncompressed data.
uint32_t uSizeInBytes = sizeof(UncompressedBlock<VoxelType>) + (m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
return uSizeInBytes;
}
} }

View File

@ -642,7 +642,7 @@ namespace PolyVox
UncompressedBlock<VoxelType>* pUncompressedBlock = new UncompressedBlock<VoxelType>(m_uBlockSideLength); UncompressedBlock<VoxelType>* pUncompressedBlock = new UncompressedBlock<VoxelType>(m_uBlockSideLength);
const void* pSrcData = reinterpret_cast<const void*>(block->getData()); const void* pSrcData = reinterpret_cast<const void*>(block->getData());
void* pDstData = reinterpret_cast<void*>(pUncompressedBlock->m_tUncompressedData); void* pDstData = reinterpret_cast<void*>(pUncompressedBlock->m_tData);
uint32_t uSrcLength = block->getDataSizeInBytes(); uint32_t uSrcLength = block->getDataSizeInBytes();
uint32_t uDstLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); uint32_t uDstLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);

View File

@ -121,7 +121,7 @@ namespace PolyVox
UncompressedBlock<VoxelType>* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock); UncompressedBlock<VoxelType>* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock);
mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock; mCurrentVoxel = pUncompressedCurrentBlock->m_tData + uVoxelIndexInBlock;
} }
else else
{ {