From 634a6fc8834cc327718b59a0fa09ff7b7953a90b Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 23 May 2008 22:41:02 +0000 Subject: [PATCH] Work on volume iterators. --- include/Block.inl | 2 +- include/Volume.h | 10 +--- include/Volume.inl | 94 ++++++-------------------------------- include/VolumeIterator.h | 5 ++ include/VolumeIterator.inl | 84 ++++++++++++++++++++++------------ 5 files changed, 77 insertions(+), 118 deletions(-) diff --git a/include/Block.inl b/include/Block.inl index 545f2263..04269908 100644 --- a/include/Block.inl +++ b/include/Block.inl @@ -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 diff --git a/include/Volume.h b/include/Volume.h index e85ac65c..27b962f6 100644 --- a/include/Volume.h +++ b/include/Volume.h @@ -51,13 +51,11 @@ namespace PolyVox bool containsPoint(Vector3DFloat pos, float boundary) const; bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const; + VolumeIterator firstVoxel(void); void idle(boost::uint32_t uAmount); - void lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner); - void unlock(void); + VolumeIterator lastVoxel(void); private: - bool isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos); - Block* getHomogenousBlock(VoxelType tHomogenousValue) const; Block** 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 diff --git a/include/Volume.inl b/include/Volume.inl index d78d9ac8..df1e9f60 100644 --- a/include/Volume.inl +++ b/include/Volume.inl @@ -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 + VolumeIterator Volume::firstVoxel(void) + { + VolumeIterator iter(*this); + iter.setPosition(0,0,0); + return iter; + } + template void Volume::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 - void Volume::lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner) + VolumeIterator Volume::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 - void Volume::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 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 - bool Volume::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 } diff --git a/include/VolumeIterator.h b/include/VolumeIterator.h index 97822f31..b2c9aeab 100644 --- a/include/VolumeIterator.h +++ b/include/VolumeIterator.h @@ -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& mVolume; diff --git a/include/VolumeIterator.inl b/include/VolumeIterator.inl index e6e2ea26..56324fcd 100644 --- a/include/VolumeIterator.inl +++ b/include/VolumeIterator.inl @@ -31,31 +31,6 @@ namespace PolyVox template VolumeIterator::VolumeIterator(Volume& 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 + bool VolumeIterator::operator<(const VolumeIterator& 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 + bool VolumeIterator::operator>(const VolumeIterator& rhs) + { + assert(&mVolume == &rhs.mVolume); + return (rhs < *this); + } + + template + bool VolumeIterator::operator<=(const VolumeIterator& rhs) + { + assert(&mVolume == &rhs.mVolume); + return (rhs > *this); + } + + template + bool VolumeIterator::operator>=(const VolumeIterator& 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; } }