Properly implemented Volume::tidyUpMemory().
This commit is contained in:
parent
df68b1fe7a
commit
8f0ca490df
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user