Properly implemented Volume::tidyUpMemory().

This commit is contained in:
David Williams 2009-04-15 20:50:41 +00:00
parent df68b1fe7a
commit 8f0ca490df
3 changed files with 44 additions and 21 deletions

View File

@ -66,7 +66,7 @@ int main(int argc, char *argv[])
createCubeInVolume(volData, Vector3DUint16(midPos+1, minPos, midPos+1), Vector3DUint16(maxPos, midPos-1, maxPos), 0);
createCubeInVolume(volData, Vector3DUint16(minPos, midPos+1, midPos+1), Vector3DUint16(midPos-1, maxPos, maxPos), 0);
volData.idle(0);
volData.tidyUpMemory(0);
QApplication app(argc, argv);

View File

@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "PolyVoxImpl/CPlusPlusZeroXSupport.h"
#include <limits>
#include <map>
#include <vector>
@ -56,7 +57,7 @@ namespace PolyVox
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
void idle(uint32_t uAmount);
void tidyUpMemory(uint32_t uNoOfBlocksToProcess = numeric_limits<uint32_t>::max);
bool isRegionHomogenous(const Region& region);
private:
@ -80,6 +81,8 @@ namespace PolyVox
uint8_t m_uBlockSideLengthPower;
uint16_t m_uBlockSideLength;
uint32_t m_uCurrentBlockForTidying;
};
//Required for the static member

View File

@ -38,6 +38,7 @@ namespace PolyVox
template <typename VoxelType>
Volume<VoxelType>::Volume(uint16_t uSideLength, uint16_t uBlockSideLength)
:m_pBlocks(0)
,m_uCurrentBlockForTidying(0)
{
//Debug mode validation
assert(isPowerOf2(uSideLength));
@ -201,37 +202,56 @@ namespace PolyVox
#pragma region Other
template <typename VoxelType>
void Volume<VoxelType>::idle(uint32_t uAmount)
void Volume<VoxelType>::tidyUpMemory(uint32_t uNoOfBlocksToProcess)
{
for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
{
if(m_vecBlockIsPotentiallyHomogenous[i])
{
if(m_pBlocks[i].m_pBlockData->isHomogeneous())
{
VoxelType homogeneousValue = m_pBlocks[i].m_pBlockData->getVoxelAt(0,0,0);
//Track the number of blocks we have processed.
uint32_t m_uNoOfProcessedBlocks = 0;
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(homogeneousValue);
//We will loop around, and finish if we get back to our start position
uint32_t uFinishBlock = m_uCurrentBlockForTidying;
//Increment the current block, looping around if necessary
++m_uCurrentBlockForTidying;
m_uCurrentBlockForTidying %= m_uNoOfBlocksInVolume;
//While we have not reached the user specified limit and there are more blocks to process...
while((m_uNoOfProcessedBlocks < uNoOfBlocksToProcess) && (m_uCurrentBlockForTidying != uFinishBlock))
{
//We only do any work if the block is flagged as potentially homogeneous.
if(m_vecBlockIsPotentiallyHomogenous[m_uCurrentBlockForTidying])
{
//Check if it's really homogeneous (this can be slow).
if(m_pBlocks[m_uCurrentBlockForTidying].m_pBlockData->isHomogeneous())
{
//If so, replace is with a block from out homogeneous collection.
VoxelType homogeneousValue = m_pBlocks[m_uCurrentBlockForTidying].m_pBlockData->getVoxelAt(0,0,0);
m_pBlocks[m_uCurrentBlockForTidying].m_pBlockData = getHomogenousBlockData(homogeneousValue);
}
//Either way, we have now determined whether the block was sharable. So it's not *potentially* sharable.
m_vecBlockIsPotentiallyHomogenous[i] = false;
m_vecBlockIsPotentiallyHomogenous[m_uCurrentBlockForTidying] = false;
//We've processed a block. This is inside the 'if' because the path outside the 'if' is trivially fast.
++m_uNoOfProcessedBlocks;
}
//Increment the current block, looping around if necessary
++m_uCurrentBlockForTidying;
m_uCurrentBlockForTidying %= m_uNoOfBlocksInVolume;
}
//FIXME - Better way to do this? Maybe using for_each()?
std::list< std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator > itersToDelete;
for(std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator iter = m_pHomogenousBlockData.begin(); iter != m_pHomogenousBlockData.end(); ++iter)
//Identify and remove any homogeneous blocks which are not actually in use.
std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator iter = m_pHomogenousBlockData.begin();
while(iter != m_pHomogenousBlockData.end())
{
if(iter->second.unique())
{
itersToDelete.push_back(iter);
m_pHomogenousBlockData.erase(iter++); //Increments the iterator and returns the previous position to be erased.
}
else
{
++iter; //Just increments the iterator.
}
}
for(std::list< std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator >::iterator listIter = itersToDelete.begin(); listIter != itersToDelete.end(); ++listIter)
{
m_pHomogenousBlockData.erase(*listIter);
}
}