Mostly refactoring and tidying up the code.

This commit is contained in:
David Williams 2008-05-23 20:59:27 +00:00
parent 3a8453b370
commit a657f4d4d0
6 changed files with 247 additions and 148 deletions

View File

@ -47,10 +47,12 @@ namespace PolyVox
void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue); void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue);
void fill(VoxelType tValue);
private: private:
boost::uint8_t m_uSideLengthPower; boost::uint8_t m_uSideLengthPower;
boost::uint16_t m_uSideLength; boost::uint16_t m_uSideLength;
VoxelType* m_tData; VoxelType* m_tData;
}; };
} }

View File

@ -106,11 +106,19 @@ namespace PolyVox
assert(uZPos < m_uSideLength); assert(uZPos < m_uSideLength);
m_tData m_tData
[ [
uXPos + uXPos +
uYPos * m_uSideLength + uYPos * m_uSideLength +
uZPos * m_uSideLength * m_uSideLength uZPos * m_uSideLength * m_uSideLength
] = tValue; ] = tValue;
}
#pragma endregion
#pragma region Other
template <typename VoxelType>
void Block<VoxelType>::fill(VoxelType tValue)
{
memset(m_tData, tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
} }
#pragma endregion #pragma endregion
} }

View File

@ -26,6 +26,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "PolyVoxForwardDeclarations.h" #include "PolyVoxForwardDeclarations.h"
#include "boost/cstdint.hpp" #include "boost/cstdint.hpp"
#include <map>
#pragma endregion #pragma endregion
namespace PolyVox namespace PolyVox
@ -43,26 +45,39 @@ namespace PolyVox
Volume& operator=(const Volume& rhs); Volume& operator=(const Volume& rhs);
boost::uint16_t getSideLength(void); boost::uint16_t getSideLength(void) const;
VoxelType getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const; VoxelType getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const;
VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const;
void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue);
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
bool containsPoint(Vector3DFloat pos, float boundary) const; bool containsPoint(Vector3DFloat pos, float boundary) const;
bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const; bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const;
void idle(boost::uint32_t uAmount);
void lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner);
void unlock(void);
private: private:
Block<VoxelType>** mBlocks; bool isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos);
Block<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const;
Block<VoxelType>** m_pBlocks;
bool* m_pIsShared;
bool* m_pIsPotentiallySharable;
VoxelType* m_pHomogenousValue;
mutable std::map<VoxelType, Block<VoxelType>*> m_pHomogenousBlocks;
boost::uint32_t m_uNoOfBlocksInVolume; boost::uint32_t m_uNoOfBlocksInVolume;
boost::uint16_t m_uSideLengthInBlocks; boost::uint16_t m_uSideLengthInBlocks;
boost::uint8_t m_uSideLengthPower; boost::uint8_t m_uSideLengthPower;
boost::uint16_t m_uSideLength; boost::uint16_t m_uSideLength;
boost::uint16_t m_uBlockSideLengthPower; boost::uint8_t m_uBlockSideLengthPower;
boost::uint16_t m_uBlockSideLength; boost::uint16_t m_uBlockSideLength;
Vector3DUint16 m_v3dLastLockedLowerCorner;
Vector3DUint16 m_v3dLastLockedUpperCorner;
bool m_bIsLocked;
}; };
//Some handy typedefs //Some handy typedefs

View File

@ -31,7 +31,7 @@ namespace PolyVox
#pragma region Constructors/Destructors #pragma region Constructors/Destructors
template <typename VoxelType> template <typename VoxelType>
Volume<VoxelType>::Volume(boost::uint8_t uSideLengthPower, boost::uint8_t uBlockSideLengthPower) Volume<VoxelType>::Volume(boost::uint8_t uSideLengthPower, boost::uint8_t uBlockSideLengthPower)
:mBlocks(0) :m_pBlocks(0)
{ {
//Check the volume size is sensible. This corresponds to a side length of 65536 voxels //Check the volume size is sensible. This corresponds to a side length of 65536 voxels
if(uSideLengthPower > 16) if(uSideLengthPower > 16)
@ -53,15 +53,17 @@ namespace PolyVox
//Compute number of blocks in the volume //Compute number of blocks in the volume
m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks; m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
mBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume]; //Create the blocks
m_pBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume];
m_pIsShared = new bool[m_uNoOfBlocksInVolume];
m_pIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume];
m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume];
for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
{ {
mBlocks[i] = 0; m_pBlocks[i] = getHomogenousBlock(0); //new Block<VoxelType>(uBlockSideLengthPower);
} m_pIsShared[i] = true;
m_pIsPotentiallySharable[i] = false;
for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) m_pHomogenousValue[i] = 0;
{
mBlocks[i] = new Block<VoxelType>(uBlockSideLengthPower);
} }
} }
@ -76,7 +78,7 @@ namespace PolyVox
{ {
for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
{ {
delete mBlocks[i]; delete m_pBlocks[i];
} }
} }
#pragma endregion #pragma endregion
@ -93,21 +95,21 @@ namespace PolyVox
/*for(uint16_t i = 0; i < POLYVOX_NO_OF_BLOCKS_IN_VOLUME; ++i) /*for(uint16_t i = 0; i < POLYVOX_NO_OF_BLOCKS_IN_VOLUME; ++i)
{ {
//FIXME - Add checking... //FIXME - Add checking...
mBlocks[i] = SharedPtr<Block>(new Block); m_pBlocks[i] = SharedPtr<Block>(new Block);
}*/ }*/
for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
{ {
//I think this is OK... If a block is in the homogeneous array it's ref count will be greater //I think this is OK... If a block is in the homogeneous array it's ref count will be greater
//than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array. //than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array.
/*if(rhs.mBlocks[i].unique()) /*if(rhs.m_pBlocks[i].unique())
{ {
mBlocks[i] = SharedPtr<Block>(new Block(*(rhs.mBlocks[i]))); m_pBlocks[i] = SharedPtr<Block>(new Block(*(rhs.m_pBlocks[i])));
} }
else else
{*/ {*/
//we have a block in the homogeneous array - just copy the pointer. //we have a block in the homogeneous array - just copy the pointer.
mBlocks[i] = rhs.mBlocks[i]; m_pBlocks[i] = rhs.m_pBlocks[i];
//} //}
} }
@ -117,7 +119,7 @@ namespace PolyVox
#pragma region Getters #pragma region Getters
template <typename VoxelType> template <typename VoxelType>
boost::uint16_t Volume<VoxelType>::getSideLength(void) boost::uint16_t Volume<VoxelType>::getSideLength(void) const
{ {
return m_uSideLength; return m_uSideLength;
} }
@ -125,9 +127,9 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType Volume<VoxelType>::getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const VoxelType Volume<VoxelType>::getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const
{ {
assert(uXPos < mVolume.getSideLength()); assert(uXPos < getSideLength());
assert(uYPos < mVolume.getSideLength()); assert(uYPos < getSideLength());
assert(uZPos < mVolume.getSideLength()); assert(uZPos < getSideLength());
const uint16_t blockX = uXPos >> m_uBlockSideLengthPower; const uint16_t blockX = uXPos >> m_uBlockSideLengthPower;
const uint16_t blockY = uYPos >> m_uBlockSideLengthPower; const uint16_t blockY = uYPos >> m_uBlockSideLengthPower;
@ -137,7 +139,7 @@ namespace PolyVox
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower); const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower); const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
const Block<VoxelType>* block = mBlocks const Block<VoxelType>* block = m_pBlocks
[ [
blockX + blockX +
blockY * m_uSideLengthInBlocks + blockY * m_uSideLengthInBlocks +
@ -156,44 +158,7 @@ namespace PolyVox
return getVoxelAt(v3dPos.x(), v3dPos.y(), v3dPos.z()); return getVoxelAt(v3dPos.x(), v3dPos.y(), v3dPos.z());
} }
#pragma endregion #pragma endregion
#pragma region Setters
template <typename VoxelType>
void Volume<VoxelType>::setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue)
{
assert(uXPos < mVolume.getSideLength());
assert(uYPos < mVolume.getSideLength());
assert(uZPos < mVolume.getSideLength());
const uint16_t blockX = uXPos >> m_uBlockSideLengthPower;
const uint16_t blockY = uYPos >> m_uBlockSideLengthPower;
const uint16_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
const Block<VoxelType>* block = mBlocks
[
blockX +
blockY * m_uSideLengthInBlocks +
blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks
];
return block->setVoxelAt(xOffset,yOffset,zOffset, tValue);
}
template <typename VoxelType>
void Volume<VoxelType>::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue)
{
assert(v3dPos.x() < m_uSideLength);
assert(v3dPos.y() < m_uSideLength);
assert(v3dPos.z() < m_uSideLength);
setVoxelAt(v3dPos.x(), v3dPos.y(), v3dPos.z(), tValue);
}
#pragma endregion
#pragma region Other #pragma region Other
template <typename VoxelType> template <typename VoxelType>
@ -217,5 +182,108 @@ namespace PolyVox
&& (pos.y() >= boundary) && (pos.y() >= boundary)
&& (pos.z() >= boundary); && (pos.z() >= boundary);
} }
template <typename VoxelType>
void Volume<VoxelType>::idle(boost::uint32_t uAmount)
{
//Check the volume isn't locked
if(m_bIsLocked)
{
throw std::logic_error("Cannot perform idle tasks on a locked volume");
}
}
template <typename VoxelType>
void Volume<VoxelType>::lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner)
{
//Check the volume isn't already locked
if(m_bIsLocked)
{
throw std::logic_error("Cannot lock an already locked volume");
}
//Find the block corresponding to the lower corner
Vector3DUint16 v3dBlockLowerCorner
(
v3dLowerCorner.x() >> m_uBlockSideLengthPower,
v3dLowerCorner.y() >> m_uBlockSideLengthPower,
v3dLowerCorner.z() >> m_uBlockSideLengthPower
);
//Find the block corresponding to the upper corner
Vector3DUint16 v3dBlockUpperCorner
(
v3dUpperCorner.x() >> m_uBlockSideLengthPower,
v3dUpperCorner.y() >> m_uBlockSideLengthPower,
v3dUpperCorner.z() >> m_uBlockSideLengthPower
);
//Set all covered blocks to be potentially sharable
for(boost::uint16_t z = v3dBlockLowerCorner.z(); z <= v3dBlockUpperCorner.z(); ++z)
{
for(boost::uint16_t y = v3dBlockLowerCorner.y(); y <= v3dBlockUpperCorner.y(); ++y)
{
for(boost::uint16_t x = v3dBlockLowerCorner.x(); x <= v3dBlockUpperCorner.x(); ++x)
{
const boost::uint32_t uBlockIndex =
blockX +
blockY * m_uSideLengthInBlocks +
blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
m_pIsPotentiallySharable[uBlockIndex] = true;
}
}
}
//Store the values so that we can verify voxels are locked before writing to them
m_v3dLastLockedLowerCorner = v3dLowerCorner;
m_v3dLastLockedUpperCorner = v3dUpperCorner;
m_bIsLocked = true;
}
template <typename VoxelType>
void Volume<VoxelType>::unlock(void)
{
//Check the volume isn't already locked.
if(!m_bIsLocked)
{
throw std::logic_error("Cannot unlock an already unlocked volume");
}
//Unlock it
m_bIsLocked = false;
}
#pragma endregion
#pragma region Private Implementation
template <typename VoxelType>
Block<VoxelType>* Volume<VoxelType>::getHomogenousBlock(VoxelType tHomogenousValue) const
{
std::map<VoxelType, Block<VoxelType>*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue);
if(iterResult == m_pHomogenousBlocks.end())
{
Block<VoxelType>* pBlock = new Block<VoxelType>(m_uBlockSideLengthPower);
pBlock->fill(tHomogenousValue);
m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock));
return pBlock;
}
return iterResult->second;
}
#pragma endregion
#pragma region Private Implementation
template <typename VoxelType>
bool Volume<VoxelType>::isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos)
{
return
(
(uXPos >= m_v3dLastLockedLowerCorner.x()) &&
(uYPos >= m_v3dLastLockedLowerCorner.y()) &&
(uZPos >= m_v3dLastLockedLowerCorner.z()) &&
(uXPos <= m_v3dLastLockedUpperCorner.x()) &&
(uYPos <= m_v3dLastLockedUpperCorner.y()) &&
(uZPos <= m_v3dLastLockedUpperCorner.z()) &&
(m_bIsLocked)
);
}
#pragma endregion #pragma endregion
} }

View File

@ -22,11 +22,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __VolumeIterator_H__ #ifndef __VolumeIterator_H__
#define __VolumeIterator_H__ #define __VolumeIterator_H__
#include "boost/cstdint.hpp" #pragma region Headers
#include "PolyVoxForwardDeclarations.h" #include "PolyVoxForwardDeclarations.h"
#include "TypeDef.h"
#include "Vector.h" #include "boost/cstdint.hpp"
#pragma endregion
namespace PolyVox namespace PolyVox
{ {
@ -35,24 +35,22 @@ namespace PolyVox
{ {
public: public:
VolumeIterator(Volume<VoxelType>& volume); VolumeIterator(Volume<VoxelType>& volume);
~VolumeIterator(); ~VolumeIterator();
void setVoxel(VoxelType value); bool operator==(const VolumeIterator& rhs);
VoxelType getVoxel(void);
float getAveragedVoxel(boost::uint16_t size) const; float getAveragedVoxel(boost::uint16_t size) const;
boost::uint16_t getPosX(void) const; boost::uint16_t getPosX(void) const;
boost::uint16_t getPosY(void) const; boost::uint16_t getPosY(void) const;
boost::uint16_t getPosZ(void) const; boost::uint16_t getPosZ(void) const;
VoxelType getVoxel(void) const;
void setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos); void setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos);
void setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast); void setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast);
void moveForwardInRegion(void); void setVoxel(VoxelType tValue);
bool isValidForRegion(void); bool isValidForRegion(void) const;
void moveForwardInRegion(void);
VoxelType peekVoxel1nx1ny1nz(void) const; VoxelType peekVoxel1nx1ny1nz(void) const;
VoxelType peekVoxel1nx1ny0pz(void) const; VoxelType peekVoxel1nx1ny0pz(void) const;
@ -85,9 +83,6 @@ namespace PolyVox
VoxelType peekVoxel1px1py1pz(void) const; VoxelType peekVoxel1px1py1pz(void) const;
private: private:
//VoxelType getVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition) const;
//The current volume //The current volume
Volume<VoxelType>& mVolume; Volume<VoxelType>& mVolume;

View File

@ -19,13 +19,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/ ******************************************************************************/
#pragma endregion #pragma endregion
#pragma region Headers
#include "Block.h" #include "Block.h"
#include "Vector.h"
#include "Volume.h" #include "Volume.h"
#pragma endregion
using namespace boost;
namespace PolyVox namespace PolyVox
{ {
#pragma region Constructors/Destructors
template <typename VoxelType> template <typename VoxelType>
VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume) VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume)
:mVolume(volume) :mVolume(volume)
@ -51,8 +53,7 @@ namespace PolyVox
,mYPosInBlock(0) ,mYPosInBlock(0)
,mZPosInBlock(0) ,mZPosInBlock(0)
,mIsValidForRegion(true) ,mIsValidForRegion(true)
,mCurrentVoxel(volume.mBlocks[0]->m_tData) ,mCurrentVoxel(volume.m_pBlocks[0]->m_tData)
//,mCurrentBlock(volume->mBlocks[0])
,mVoxelIndexInBlock(0) ,mVoxelIndexInBlock(0)
,mBlockIndexInVolume(0) ,mBlockIndexInVolume(0)
{ {
@ -61,58 +62,26 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VolumeIterator<VoxelType>::~VolumeIterator() VolumeIterator<VoxelType>::~VolumeIterator()
{ {
}
template <typename VoxelType>
void VolumeIterator<VoxelType>::setVoxel(VoxelType value)
{
Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume];
/*if(!currentBlock.unique())
{
Block* copy(new Block(*currentBlock));
currentBlock = copy;
mCurrentVoxel = currentBlock->mData + mVoxelIndexInBlock;
}*/
*mCurrentVoxel = value;
} }
#pragma endregion
#pragma region Operators
template <typename VoxelType> template <typename VoxelType>
VoxelType VolumeIterator<VoxelType>::getVoxel(void) bool VolumeIterator<VoxelType>::operator==(const VolumeIterator<VoxelType>& rhs)
{ {
//return getVoxelAt(mXPosInVolume,mYPosInVolume,mZPosInVolume); //We could just check whether the two mCurrentVoxel pointers are equal, but this may not
return *mCurrentVoxel; //be safe in the future if we decide to allow blocks to be shared between volumes
//So we really check whether the volumes and positions are the same
/*return
(
mVolume.
);*/
} }
#pragma endregion
/*template <typename VoxelType> #pragma region Getters
VoxelType VolumeIterator<VoxelType>::getVoxelAt(const uint16_t xPosition, const uint16_t yPosition, const uint16_t zPosition) const
{
assert(xPosition < mVolume.getSideLength());
assert(yPosition < mVolume.getSideLength());
assert(zPosition < mVolume.getSideLength());
const uint16_t blockX = xPosition >> mVolume.m_uBlockSideLengthPower;
const uint16_t blockY = yPosition >> mVolume.m_uBlockSideLengthPower;
const uint16_t blockZ = zPosition >> mVolume.m_uBlockSideLengthPower;
const uint16_t xOffset = xPosition - (blockX << mVolume.m_uBlockSideLengthPower);
const uint16_t yOffset = yPosition - (blockY << mVolume.m_uBlockSideLengthPower);
const uint16_t zOffset = zPosition - (blockZ << mVolume.m_uBlockSideLengthPower);
const Block<VoxelType>* block = mVolume.mBlocks
[
blockX +
blockY * mVolume.m_uSideLengthInBlocks +
blockZ * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks
];
return block->getVoxelAt(xOffset,yOffset,zOffset);
}*/
template <typename VoxelType> template <typename VoxelType>
float VolumeIterator<VoxelType>::getAveragedVoxel(uint16_t size) const float VolumeIterator<VoxelType>::getAveragedVoxel(boost::uint16_t size) const
{ {
assert(mXPosInVolume >= size); assert(mXPosInVolume >= size);
assert(mYPosInVolume >= size); assert(mYPosInVolume >= size);
@ -144,25 +113,33 @@ namespace PolyVox
} }
template <typename VoxelType> template <typename VoxelType>
uint16_t VolumeIterator<VoxelType>::getPosX(void) const boost::uint16_t VolumeIterator<VoxelType>::getPosX(void) const
{ {
return mXPosInVolume; return mXPosInVolume;
} }
template <typename VoxelType> template <typename VoxelType>
uint16_t VolumeIterator<VoxelType>::getPosY(void) const boost::uint16_t VolumeIterator<VoxelType>::getPosY(void) const
{ {
return mYPosInVolume; return mYPosInVolume;
} }
template <typename VoxelType> template <typename VoxelType>
uint16_t VolumeIterator<VoxelType>::getPosZ(void) const boost::uint16_t VolumeIterator<VoxelType>::getPosZ(void) const
{ {
return mZPosInVolume; return mZPosInVolume;
} }
template <typename VoxelType> template <typename VoxelType>
void VolumeIterator<VoxelType>::setPosition(uint16_t xPos, uint16_t yPos, uint16_t zPos) VoxelType VolumeIterator<VoxelType>::getVoxel(void) const
{
return *mCurrentVoxel;
}
#pragma endregion
#pragma region Setters
template <typename VoxelType>
void VolumeIterator<VoxelType>::setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos)
{ {
mXPosInVolume = xPos; mXPosInVolume = xPos;
mYPosInVolume = yPos; mYPosInVolume = yPos;
@ -179,7 +156,7 @@ namespace PolyVox
mBlockIndexInVolume = mXBlock + mBlockIndexInVolume = mXBlock +
mYBlock * mVolume.m_uSideLengthInBlocks + mYBlock * mVolume.m_uSideLengthInBlocks +
mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks;
Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume];
mVoxelIndexInBlock = mXPosInBlock + mVoxelIndexInBlock = mXPosInBlock +
mYPosInBlock * mVolume.m_uBlockSideLength + mYPosInBlock * mVolume.m_uBlockSideLength +
@ -189,7 +166,7 @@ namespace PolyVox
} }
template <typename VoxelType> template <typename VoxelType>
void VolumeIterator<VoxelType>::setValidRegion(uint16_t xFirst, uint16_t yFirst, uint16_t zFirst, uint16_t xLast, uint16_t yLast, uint16_t zLast) void VolumeIterator<VoxelType>::setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast)
{ {
mXRegionFirst = xFirst; mXRegionFirst = xFirst;
mYRegionFirst = yFirst; mYRegionFirst = yFirst;
@ -208,6 +185,43 @@ namespace PolyVox
mZRegionLastBlock = mZRegionLast >> mVolume.m_uBlockSideLengthPower; mZRegionLastBlock = mZRegionLast >> mVolume.m_uBlockSideLengthPower;
} }
template <typename VoxelType>
void VolumeIterator<VoxelType>::setVoxel(VoxelType tValue)
{
assert(mVolume.isVoxelLocked(mXPosInVolume,mYPosInVolume,mZPosInVolume));
const boost::uint32_t uBlockIndex =
mXBlock +
mYBlock * mVolume.m_uSideLengthInBlocks +
mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks;
const bool bIsShared = mVolume.m_pIsShared[uBlockIndex];
const VoxelType tHomogenousValue = mVolume.m_pHomogenousValue[uBlockIndex];
if(bIsShared)
{
if(tHomogenousValue != tValue)
{
mVolume.m_pBlocks[uBlockIndex] = new Block<VoxelType>(mVolume.m_uBlockSideLengthPower);
mVolume.m_pIsShared[uBlockIndex] = false;
mVolume.m_pBlocks[uBlockIndex]->fill(tHomogenousValue);
mCurrentVoxel = mVolume.m_pBlocks[uBlockIndex]->m_tData + mVoxelIndexInBlock;
*mCurrentVoxel = tValue;
}
}
else
{
*mCurrentVoxel = tValue;
}
}
#pragma endregion
#pragma region Other
template <typename VoxelType>
bool VolumeIterator<VoxelType>::isValidForRegion(void) const
{
return mIsValidForRegion;
}
template <typename VoxelType> template <typename VoxelType>
void VolumeIterator<VoxelType>::moveForwardInRegion(void) void VolumeIterator<VoxelType>::moveForwardInRegion(void)
{ {
@ -221,7 +235,7 @@ namespace PolyVox
mVoxelIndexInBlock = mXPosInBlock + mVoxelIndexInBlock = mXPosInBlock +
mYPosInBlock * mVolume.m_uBlockSideLength + mYPosInBlock * mVolume.m_uBlockSideLength +
mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength;
Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume];
mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock;
mYPosInBlock++; mYPosInBlock++;
@ -234,7 +248,7 @@ namespace PolyVox
mVoxelIndexInBlock = mXPosInBlock + mVoxelIndexInBlock = mXPosInBlock +
mYPosInBlock * mVolume.m_uBlockSideLength + mYPosInBlock * mVolume.m_uBlockSideLength +
mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength;
Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume];
mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock;
mZPosInBlock++; mZPosInBlock++;
@ -273,8 +287,8 @@ namespace PolyVox
} }
} }
Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume];
//mCurrentBlock = mVolume->mBlocks[mBlockIndexInVolume]; //mCurrentBlock = mVolume->m_pBlocks[mBlockIndexInVolume];
mXPosInVolume = (std::max)(mXRegionFirst,uint16_t(mXBlock * mVolume.m_uBlockSideLength)); mXPosInVolume = (std::max)(mXRegionFirst,uint16_t(mXBlock * mVolume.m_uBlockSideLength));
mYPosInVolume = (std::max)(mYRegionFirst,uint16_t(mYBlock * mVolume.m_uBlockSideLength)); mYPosInVolume = (std::max)(mYRegionFirst,uint16_t(mYBlock * mVolume.m_uBlockSideLength));
@ -293,13 +307,9 @@ namespace PolyVox
} }
} }
} }
#pragma endregion
template <typename VoxelType> #pragma region Peekers
bool VolumeIterator<VoxelType>::isValidForRegion(void)
{
return mIsValidForRegion;
}
template <typename VoxelType> template <typename VoxelType>
VoxelType VolumeIterator<VoxelType>::peekVoxel1nx1ny1nz(void) const VoxelType VolumeIterator<VoxelType>::peekVoxel1nx1ny1nz(void) const
{ {
@ -569,4 +579,5 @@ namespace PolyVox
} }
return mVolume.getVoxelAt(mXPosInVolume+1,mYPosInVolume+1,mZPosInVolume+1); return mVolume.getVoxelAt(mXPosInVolume+1,mYPosInVolume+1,mZPosInVolume+1);
} }
#pragma endregion
} }