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
|
//Check the block size is sensible. This corresponds to a side length of 256 voxels
|
||||||
if(uSideLengthPower > 8)
|
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
|
//Compute the side length
|
||||||
|
@ -51,13 +51,11 @@ namespace PolyVox
|
|||||||
|
|
||||||
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;
|
||||||
|
VolumeIterator<VoxelType> firstVoxel(void);
|
||||||
void idle(boost::uint32_t uAmount);
|
void idle(boost::uint32_t uAmount);
|
||||||
void lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner);
|
VolumeIterator<VoxelType> lastVoxel(void);
|
||||||
void unlock(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos);
|
|
||||||
|
|
||||||
Block<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const;
|
Block<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const;
|
||||||
|
|
||||||
Block<VoxelType>** m_pBlocks;
|
Block<VoxelType>** m_pBlocks;
|
||||||
@ -74,10 +72,6 @@ namespace PolyVox
|
|||||||
|
|
||||||
boost::uint8_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
|
||||||
|
@ -36,7 +36,7 @@ namespace PolyVox
|
|||||||
//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)
|
||||||
{
|
{
|
||||||
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
|
//Compute the volume side length
|
||||||
@ -183,74 +183,25 @@ namespace PolyVox
|
|||||||
&& (pos.z() >= boundary);
|
&& (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>
|
template <typename VoxelType>
|
||||||
void Volume<VoxelType>::idle(boost::uint32_t uAmount)
|
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>
|
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
|
VolumeIterator<VoxelType> iter(*this);
|
||||||
if(m_bIsLocked)
|
iter.setPosition(m_uSideLength-1,m_uSideLength-1,m_uSideLength-1);
|
||||||
{
|
return iter;
|
||||||
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 endregion
|
||||||
|
|
||||||
@ -269,21 +220,4 @@ namespace PolyVox
|
|||||||
return iterResult->second;
|
return iterResult->second;
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#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();
|
~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);
|
||||||
|
bool operator>=(const VolumeIterator& rhs);
|
||||||
|
|
||||||
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;
|
||||||
@ -83,6 +87,7 @@ namespace PolyVox
|
|||||||
VoxelType peekVoxel1px1py1pz(void) const;
|
VoxelType peekVoxel1px1py1pz(void) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//The current volume
|
//The current volume
|
||||||
Volume<VoxelType>& mVolume;
|
Volume<VoxelType>& mVolume;
|
||||||
|
|
||||||
|
@ -31,31 +31,6 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume)
|
VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume)
|
||||||
:mVolume(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
|
//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
|
//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
|
//So we really check whether the positions are the same.
|
||||||
/*return
|
//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
|
#pragma endregion
|
||||||
|
|
||||||
@ -210,6 +234,8 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//There is a chance that setting this voxel makes the block homogenous and therefore shareable.
|
||||||
|
mVolume.m_pIsPotentiallySharable[uBlockIndex] = true;
|
||||||
*mCurrentVoxel = tValue;
|
*mCurrentVoxel = tValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user