Work on volume iterators.
This commit is contained in:
parent
180981293a
commit
634a6fc883
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user