Work on volume iterators.

This commit is contained in:
David Williams 2008-05-23 22:41:02 +00:00
parent 180981293a
commit 634a6fc883
5 changed files with 77 additions and 118 deletions

View File

@ -35,7 +35,7 @@ namespace PolyVox
//Check the block size is sensible. This corresponds to a side length of 256 voxels
if(uSideLengthPower > 8)
{
throw std::invalid_argument("Block side length must be less than or equal to eight");
throw std::invalid_argument("Block side length power must be less than or equal to eight");
}
//Compute the side length

View File

@ -51,13 +51,11 @@ namespace PolyVox
bool containsPoint(Vector3DFloat pos, float boundary) const;
bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const;
VolumeIterator<VoxelType> firstVoxel(void);
void idle(boost::uint32_t uAmount);
void lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner);
void unlock(void);
VolumeIterator<VoxelType> lastVoxel(void);
private:
bool isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos);
Block<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const;
Block<VoxelType>** m_pBlocks;
@ -74,10 +72,6 @@ namespace PolyVox
boost::uint8_t m_uBlockSideLengthPower;
boost::uint16_t m_uBlockSideLength;
Vector3DUint16 m_v3dLastLockedLowerCorner;
Vector3DUint16 m_v3dLastLockedUpperCorner;
bool m_bIsLocked;
};
//Some handy typedefs

View File

@ -36,7 +36,7 @@ namespace PolyVox
//Check the volume size is sensible. This corresponds to a side length of 65536 voxels
if(uSideLengthPower > 16)
{
throw std::invalid_argument("Block side length must be less than or equal to 65536");
throw std::invalid_argument("Volume side length power must be less than or equal to 16");
}
//Compute the volume side length
@ -183,74 +183,25 @@ namespace PolyVox
&& (pos.z() >= boundary);
}
template <typename VoxelType>
VolumeIterator<VoxelType> Volume<VoxelType>::firstVoxel(void)
{
VolumeIterator<VoxelType> iter(*this);
iter.setPosition(0,0,0);
return iter;
}
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)
VolumeIterator<VoxelType> Volume<VoxelType>::lastVoxel(void)
{
//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;
VolumeIterator<VoxelType> iter(*this);
iter.setPosition(m_uSideLength-1,m_uSideLength-1,m_uSideLength-1);
return iter;
}
#pragma endregion
@ -269,21 +220,4 @@ namespace PolyVox
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
}

View File

@ -38,6 +38,10 @@ namespace PolyVox
~VolumeIterator();
bool operator==(const VolumeIterator& rhs);
bool operator<(const VolumeIterator& rhs);
bool operator>(const VolumeIterator& rhs);
bool operator<=(const VolumeIterator& rhs);
bool operator>=(const VolumeIterator& rhs);
float getAveragedVoxel(boost::uint16_t size) const;
boost::uint16_t getPosX(void) const;
@ -83,6 +87,7 @@ namespace PolyVox
VoxelType peekVoxel1px1py1pz(void) const;
private:
//The current volume
Volume<VoxelType>& mVolume;

View File

@ -31,31 +31,6 @@ namespace PolyVox
template <typename VoxelType>
VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume)
:mVolume(volume)
,mXRegionFirst(0)
,mYRegionFirst(0)
,mZRegionFirst(0)
,mXRegionLast(volume.getSideLength()-1)
,mYRegionLast(volume.getSideLength()-1)
,mZRegionLast(volume.getSideLength()-1)
,mXRegionFirstBlock(0)
,mYRegionFirstBlock(0)
,mZRegionFirstBlock(0)
,mXRegionLastBlock(volume.m_uSideLengthInBlocks-1)
,mYRegionLastBlock(volume.m_uSideLengthInBlocks-1)
,mZRegionLastBlock(volume.m_uSideLengthInBlocks-1)
,mXPosInVolume(0)
,mYPosInVolume(0)
,mZPosInVolume(0)
,mXBlock(0)
,mYBlock(0)
,mZBlock(0)
,mXPosInBlock(0)
,mYPosInBlock(0)
,mZPosInBlock(0)
,mIsValidForRegion(true)
,mCurrentVoxel(volume.m_pBlocks[0]->m_tData)
,mVoxelIndexInBlock(0)
,mBlockIndexInVolume(0)
{
}
@ -71,11 +46,60 @@ namespace PolyVox
{
//We could just check whether the two mCurrentVoxel pointers are equal, but this may not
//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
//So we really check whether the positions are the same.
//NOTE: With all iterator comparisons it is the users job to ensure they at least point
//to the same volume. Otherwise they are not comparible.
assert(&mVolume == &rhs.mVolume);
return
(
mVolume.
);*/
(mXPosInVolume == rhs.mXPosInVolume) &&
(mYPosInVolume == rhs.mYPosInVolume) &&
(mZPosInVolume == rhs.mZPosInVolume)
);
}
template <typename VoxelType>
bool VolumeIterator<VoxelType>::operator<(const VolumeIterator<VoxelType>& rhs)
{
assert(&mVolume == &rhs.mVolume);
if(mZPosInVolume < rhs.mZPosInVolume)
return true;
if(mZPosInVolume > rhs.mZPosInVolume)
return false;
if(mYPosInVolume < rhs.mYPosInVolume)
return true;
if(mYPosInVolume > rhs.mYPosInVolume)
return false;
if(mXPosInVolume < rhs.mXPosInVolume)
return true;
if(mXPosInVolume > rhs.mXPosInVolume)
return false;
return false;
}
template <typename VoxelType>
bool VolumeIterator<VoxelType>::operator>(const VolumeIterator<VoxelType>& rhs)
{
assert(&mVolume == &rhs.mVolume);
return (rhs < *this);
}
template <typename VoxelType>
bool VolumeIterator<VoxelType>::operator<=(const VolumeIterator<VoxelType>& rhs)
{
assert(&mVolume == &rhs.mVolume);
return (rhs > *this);
}
template <typename VoxelType>
bool VolumeIterator<VoxelType>::operator>=(const VolumeIterator<VoxelType>& rhs)
{
assert(&mVolume == &rhs.mVolume);
return (rhs < *this);
}
#pragma endregion
@ -210,6 +234,8 @@ namespace PolyVox
}
else
{
//There is a chance that setting this voxel makes the block homogenous and therefore shareable.
mVolume.m_pIsPotentiallySharable[uBlockIndex] = true;
*mCurrentVoxel = tValue;
}
}