Implemented cache of uncompressed blocks.
This commit is contained in:
parent
21490c5228
commit
7be083a243
@ -41,6 +41,7 @@ void OpenGLWidget::setSurfaceMeshToRender(const PolyVox::SurfaceMesh<PositionMat
|
|||||||
|
|
||||||
m_uBeginIndex = 0;
|
m_uBeginIndex = 0;
|
||||||
m_uEndIndex = vecIndices.size();
|
m_uEndIndex = vecIndices.size();
|
||||||
|
noOfIndices = surfaceMesh.getNoOfIndices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLWidget::initializeGL()
|
void OpenGLWidget::initializeGL()
|
||||||
|
@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
|||||||
|
|
||||||
PROJECT(PolyVox)
|
PROJECT(PolyVox)
|
||||||
|
|
||||||
add_subdirectory(bindings)
|
#add_subdirectory(bindings)
|
||||||
add_subdirectory(PolyVoxCore)
|
add_subdirectory(PolyVoxCore)
|
||||||
add_subdirectory(PolyVoxUtil)
|
add_subdirectory(PolyVoxUtil)
|
||||||
|
|
||||||
|
@ -51,10 +51,16 @@ namespace PolyVox
|
|||||||
void resize(uint16_t uSideLength);
|
void resize(uint16_t uSideLength);
|
||||||
uint32_t sizeInChars(void);
|
uint32_t sizeInChars(void);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
|
void compress(void);
|
||||||
|
void uncompress(void);
|
||||||
|
|
||||||
uint16_t m_uSideLength;
|
uint16_t m_uSideLength;
|
||||||
uint8_t m_uSideLengthPower;
|
uint8_t m_uSideLengthPower;
|
||||||
VoxelType* m_tData;
|
VoxelType* m_tCompressedData;
|
||||||
|
VoxelType* m_tUncompressedData;
|
||||||
|
bool m_bIsCompressed;
|
||||||
|
uint32_t m_uTimestamp;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,10 @@ namespace PolyVox
|
|||||||
Block<VoxelType>::Block(uint16_t uSideLength)
|
Block<VoxelType>::Block(uint16_t uSideLength)
|
||||||
:m_uSideLength(0)
|
:m_uSideLength(0)
|
||||||
,m_uSideLengthPower(0)
|
,m_uSideLengthPower(0)
|
||||||
,m_tData(0)
|
,m_tCompressedData(0)
|
||||||
|
,m_tUncompressedData(0)
|
||||||
|
,m_bIsCompressed(true)
|
||||||
|
,m_uTimestamp(0)
|
||||||
{
|
{
|
||||||
if(uSideLength != 0)
|
if(uSideLength != 0)
|
||||||
{
|
{
|
||||||
@ -52,8 +55,8 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
Block<VoxelType>::~Block()
|
Block<VoxelType>::~Block()
|
||||||
{
|
{
|
||||||
delete[] m_tData;
|
delete[] m_tCompressedData;
|
||||||
m_tData = 0;
|
m_tCompressedData = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -66,12 +69,12 @@ namespace PolyVox
|
|||||||
|
|
||||||
//If this fails an exception will be thrown. Memory is not
|
//If this fails an exception will be thrown. Memory is not
|
||||||
//allocated and there is nothing else in this class to clean up
|
//allocated and there is nothing else in this class to clean up
|
||||||
m_tData = new VoxelType[rhs.m_uSideLength * rhs.m_uSideLength * rhs.m_uSideLength];
|
m_tCompressedData = new VoxelType[rhs.m_uSideLength * rhs.m_uSideLength * rhs.m_uSideLength];
|
||||||
|
|
||||||
//Copy the data
|
//Copy the data
|
||||||
m_uSideLength = rhs.m_uSideLength;
|
m_uSideLength = rhs.m_uSideLength;
|
||||||
m_uSideLengthPower = rhs.m_uSideLengthPower;
|
m_uSideLengthPower = rhs.m_uSideLengthPower;
|
||||||
memcpy(m_tData, rhs.m_tData, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
|
memcpy(m_tCompressedData, rhs.m_tCompressedData, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -89,7 +92,9 @@ namespace PolyVox
|
|||||||
assert(uYPos < m_uSideLength);
|
assert(uYPos < m_uSideLength);
|
||||||
assert(uZPos < m_uSideLength);
|
assert(uZPos < m_uSideLength);
|
||||||
|
|
||||||
return m_tData
|
assert(m_tUncompressedData);
|
||||||
|
|
||||||
|
return m_tUncompressedData
|
||||||
[
|
[
|
||||||
uXPos +
|
uXPos +
|
||||||
uYPos * m_uSideLength +
|
uYPos * m_uSideLength +
|
||||||
@ -110,7 +115,9 @@ namespace PolyVox
|
|||||||
assert(uYPos < m_uSideLength);
|
assert(uYPos < m_uSideLength);
|
||||||
assert(uZPos < m_uSideLength);
|
assert(uZPos < m_uSideLength);
|
||||||
|
|
||||||
m_tData
|
assert(m_tUncompressedData);
|
||||||
|
|
||||||
|
m_tUncompressedData
|
||||||
[
|
[
|
||||||
uXPos +
|
uXPos +
|
||||||
uYPos * m_uSideLength +
|
uYPos * m_uSideLength +
|
||||||
@ -130,9 +137,11 @@ namespace PolyVox
|
|||||||
//The memset *may* be faster than the std::fill(), but it doesn't compile nicely
|
//The memset *may* be faster than the std::fill(), but it doesn't compile nicely
|
||||||
//in 64-bit mode as casting the pointer to an int causes a loss of precision.
|
//in 64-bit mode as casting the pointer to an int causes a loss of precision.
|
||||||
|
|
||||||
//memset(m_tData, (int)tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
|
assert(m_tUncompressedData);
|
||||||
|
|
||||||
|
//memset(m_tCompressedData, (int)tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
|
||||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
std::fill(m_tData, m_tData + uNoOfVoxels, tValue);
|
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -152,12 +161,12 @@ namespace PolyVox
|
|||||||
m_uSideLengthPower = logBase2(uSideLength);
|
m_uSideLengthPower = logBase2(uSideLength);
|
||||||
|
|
||||||
//Delete the old data
|
//Delete the old data
|
||||||
delete[] m_tData;
|
delete[] m_tCompressedData;
|
||||||
m_tData = 0;
|
m_tCompressedData = 0;
|
||||||
|
|
||||||
//If this fails an exception will be thrown. Memory is not
|
//If this fails an exception will be thrown. Memory is not
|
||||||
//allocated and there is nothing else in this class to clean up
|
//allocated and there is nothing else in this class to clean up
|
||||||
m_tData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
m_tCompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -165,7 +174,7 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
uint32_t uSizeInChars = sizeof(Block<VoxelType>);
|
uint32_t uSizeInChars = sizeof(Block<VoxelType>);
|
||||||
|
|
||||||
if(m_tData != 0)
|
if(m_tCompressedData != 0)
|
||||||
{
|
{
|
||||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
uSizeInChars += uNoOfVoxels * sizeof(VoxelType);
|
uSizeInChars += uNoOfVoxels * sizeof(VoxelType);
|
||||||
@ -173,4 +182,21 @@ namespace PolyVox
|
|||||||
|
|
||||||
return uSizeInChars;
|
return uSizeInChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename VoxelType>
|
||||||
|
void Block<VoxelType>::compress(void)
|
||||||
|
{
|
||||||
|
memcpy(m_tCompressedData, m_tUncompressedData, sizeof(VoxelType) * m_uSideLength * m_uSideLength * m_uSideLength);
|
||||||
|
delete[] m_tUncompressedData;
|
||||||
|
m_tUncompressedData = 0;
|
||||||
|
m_bIsCompressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VoxelType>
|
||||||
|
void Block<VoxelType>::uncompress(void)
|
||||||
|
{
|
||||||
|
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||||
|
memcpy(m_tUncompressedData, m_tCompressedData, sizeof(VoxelType) * m_uSideLength * m_uSideLength * m_uSideLength);
|
||||||
|
m_bIsCompressed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -155,8 +156,12 @@ namespace PolyVox
|
|||||||
void resize(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32);
|
void resize(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Block<VoxelType>* getUncompressedBlock(Block<VoxelType>* block) const;
|
||||||
|
|
||||||
Block<VoxelType> m_pBorderBlock;
|
Block<VoxelType> m_pBorderBlock;
|
||||||
std::vector< Block<VoxelType> > m_pBlocks;
|
std::vector< Block<VoxelType> > m_pBlocks;
|
||||||
|
//mutable Block<VoxelType>* m_pUncompressedBlock;
|
||||||
|
mutable std::set<Block<VoxelType>*> m_pUncompressedBlocks;
|
||||||
|
|
||||||
uint32_t m_uNoOfBlocksInVolume;
|
uint32_t m_uNoOfBlocksInVolume;
|
||||||
|
|
||||||
@ -174,6 +179,7 @@ namespace PolyVox
|
|||||||
uint16_t m_uLongestSideLength;
|
uint16_t m_uLongestSideLength;
|
||||||
uint16_t m_uShortestSideLength;
|
uint16_t m_uShortestSideLength;
|
||||||
float m_fDiagonalLength;
|
float m_fDiagonalLength;
|
||||||
|
mutable uint32_t m_uTimestamper;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Some handy typedefs
|
//Some handy typedefs
|
||||||
|
@ -48,6 +48,7 @@ namespace PolyVox
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
Volume<VoxelType>::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength)
|
Volume<VoxelType>::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength)
|
||||||
|
:m_uTimestamper(0)
|
||||||
{
|
{
|
||||||
//Create a volume of the right size.
|
//Create a volume of the right size.
|
||||||
resize(uWidth, uHeight, uDepth, uBlockSideLength);
|
resize(uWidth, uHeight, uDepth, uBlockSideLength);
|
||||||
@ -69,7 +70,8 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType Volume<VoxelType>::getBorderValue(void) const
|
VoxelType Volume<VoxelType>::getBorderValue(void) const
|
||||||
{
|
{
|
||||||
return m_pBorderBlock.getVoxelAt(0,0,0);
|
Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(const_cast<Block<VoxelType>*>(&m_pBorderBlock));
|
||||||
|
return pUncompressedBorderBlock->getVoxelAt(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -176,7 +178,9 @@ namespace PolyVox
|
|||||||
blockZ * m_uWidthInBlocks * m_uHeightInBlocks
|
blockZ * m_uWidthInBlocks * m_uHeightInBlocks
|
||||||
];
|
];
|
||||||
|
|
||||||
return block.getVoxelAt(xOffset,yOffset,zOffset);
|
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(const_cast<Block<VoxelType>*>(&block));
|
||||||
|
|
||||||
|
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -200,7 +204,8 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Volume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
void Volume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
||||||
{
|
{
|
||||||
return m_pBorderBlock.fill(tBorder);
|
Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(&m_pBorderBlock);
|
||||||
|
return pUncompressedBorderBlock->fill(tBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -232,7 +237,9 @@ namespace PolyVox
|
|||||||
|
|
||||||
Block<VoxelType>& block = m_pBlocks[uBlockIndex];
|
Block<VoxelType>& block = m_pBlocks[uBlockIndex];
|
||||||
|
|
||||||
block.setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(&block);
|
||||||
|
|
||||||
|
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
||||||
|
|
||||||
//Return true to indicate that we modified a voxel.
|
//Return true to indicate that we modified a voxel.
|
||||||
return true;
|
return true;
|
||||||
@ -328,11 +335,80 @@ namespace PolyVox
|
|||||||
|
|
||||||
//Create the border block
|
//Create the border block
|
||||||
m_pBorderBlock.resize(uBlockSideLength);
|
m_pBorderBlock.resize(uBlockSideLength);
|
||||||
m_pBorderBlock.fill(VoxelType());
|
Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(&m_pBorderBlock);
|
||||||
|
pUncompressedBorderBlock->fill(VoxelType());
|
||||||
|
|
||||||
//Other properties we might find useful later
|
//Other properties we might find useful later
|
||||||
m_uLongestSideLength = (std::max)((std::max)(m_uWidth,m_uHeight),m_uDepth);
|
m_uLongestSideLength = (std::max)((std::max)(m_uWidth,m_uHeight),m_uDepth);
|
||||||
m_uShortestSideLength = (std::min)((std::min)(m_uWidth,m_uHeight),m_uDepth);
|
m_uShortestSideLength = (std::min)((std::min)(m_uWidth,m_uHeight),m_uDepth);
|
||||||
m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth));
|
m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*template <typename VoxelType>
|
||||||
|
Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const
|
||||||
|
{
|
||||||
|
if(block == m_pUncompressedBlock)
|
||||||
|
{
|
||||||
|
return m_pUncompressedBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_pUncompressedBlock)
|
||||||
|
{
|
||||||
|
m_pUncompressedBlock->compress();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pUncompressedBlock = block;
|
||||||
|
m_pUncompressedBlock->uncompress();
|
||||||
|
|
||||||
|
return m_pUncompressedBlock;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*template <typename VoxelType>
|
||||||
|
Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const
|
||||||
|
{
|
||||||
|
std::set<Block<VoxelType>*>::iterator iterBlock = m_pUncompressedBlocks.find(block);
|
||||||
|
if(iterBlock != m_pUncompressedBlocks.end())
|
||||||
|
{
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
block->uncompress();
|
||||||
|
m_pUncompressedBlocks.insert(block);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
template <typename VoxelType>
|
||||||
|
Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const
|
||||||
|
{
|
||||||
|
block->m_uTimestamp = ++m_uTimestamper;
|
||||||
|
|
||||||
|
if(block->m_bIsCompressed == false)
|
||||||
|
{
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t MaxUncompressedBlocks = 4;
|
||||||
|
if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks)
|
||||||
|
{
|
||||||
|
Block<VoxelType>* pLeastRecentlyUsedBlock;
|
||||||
|
uint32_t uLeastRecentTimestamp = 100000000;
|
||||||
|
for(std::set<Block<VoxelType>*>::iterator iter = m_pUncompressedBlocks.begin(); iter != m_pUncompressedBlocks.end(); iter++)
|
||||||
|
{
|
||||||
|
if((*iter)->m_uTimestamp < uLeastRecentTimestamp)
|
||||||
|
{
|
||||||
|
uLeastRecentTimestamp = (*iter)->m_uTimestamp;
|
||||||
|
pLeastRecentlyUsedBlock = *iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pLeastRecentlyUsedBlock->compress();
|
||||||
|
m_pUncompressedBlocks.erase(pLeastRecentlyUsedBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
block->uncompress();
|
||||||
|
m_pUncompressedBlocks.insert(block);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,11 +155,14 @@ namespace PolyVox
|
|||||||
uZBlock * mVolume->m_uWidthInBlocks * mVolume->m_uHeightInBlocks;
|
uZBlock * mVolume->m_uWidthInBlocks * mVolume->m_uHeightInBlocks;
|
||||||
const Block<VoxelType>& currentBlock = mVolume->m_pBlocks[uBlockIndexInVolume];
|
const Block<VoxelType>& currentBlock = mVolume->m_pBlocks[uBlockIndexInVolume];
|
||||||
|
|
||||||
mCurrentVoxel = currentBlock.m_tData + uVoxelIndexInBlock;
|
Block<VoxelType>* pUncompressedCurrentBlock = mVolume->getUncompressedBlock(const_cast<Block<VoxelType>*>(¤tBlock));
|
||||||
|
|
||||||
|
mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mCurrentVoxel = mVolume->m_pBorderBlock.m_tData + uVoxelIndexInBlock;
|
Block<VoxelType>* pUncompressedBorderBlock = mVolume->getUncompressedBlock(&(mVolume->m_pBorderBlock));
|
||||||
|
mCurrentVoxel = pUncompressedBorderBlock->m_tUncompressedData + uVoxelIndexInBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user