diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index fcd3e6e5..07bafcff 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -29,6 +29,7 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Region.h" #include "PolyVoxCore/Vector.h" +#include #include #include //For abort() #include @@ -55,13 +56,21 @@ namespace PolyVox class Sampler : public BaseVolume::template Sampler< RawVolume > //This line works on GCC #endif { - static const uint8_t Current = 0x01; - static const uint8_t PositiveX = 0x02; - static const uint8_t NegativeX = 0x04; - static const uint8_t PositiveY = 0x08; - static const uint8_t NegativeY = 0x10; - static const uint8_t PositiveZ = 0x20; - static const uint8_t NegativeZ = 0x40; + static const uint8_t CurrentShift = 0; + static const uint8_t PositiveXShift = 1; + static const uint8_t NegativeXShift = 2; + static const uint8_t PositiveYShift = 3; + static const uint8_t NegativeYShift = 4; + static const uint8_t PositiveZShift = 5; + static const uint8_t NegativeZShift = 6; + + static const uint8_t Current = 1 << CurrentShift; + static const uint8_t PositiveX = 1 << PositiveXShift; + static const uint8_t NegativeX = 1 << NegativeXShift; + static const uint8_t PositiveY = 1 << PositiveYShift; + static const uint8_t NegativeY = 1 << NegativeYShift; + static const uint8_t PositiveZ = 1 << PositiveZShift; + static const uint8_t NegativeZ = 1 << NegativeZShift; public: Sampler(RawVolume* volume); @@ -113,13 +122,13 @@ namespace PolyVox private: VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const; - bool checkValidFlags(uint8_t uFlagsToCheck) const; + bool checkValidFlags(std::bitset<7> uFlagsToCheck) const; void updateValidFlagsState(void); //Other current position information VoxelType* mCurrentVoxel; - uint8_t m_uValidFlags; + std::bitset<7> m_uValidFlags; }; #endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl index 6d8a38b0..39f7c0f0 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl @@ -98,8 +98,26 @@ namespace PolyVox this->mXPosInVolume++; ++mCurrentVoxel; - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | PositiveX)) + { + // We've just checked that the old 'Current' and old 'PositiveX' are both valid. That means we are not + // leaving the volume, and we know we haven't moved along the other two axes. The new 'NegativeX' takes + // on the value of the old 'Current', and the new 'Current' takes in the value of the old 'PositiveX'. + // Because we know these are both set we can set both 'NegativeX' and 'Current' to true. + m_uValidFlags |= (NegativeX | Current); + + // PositiveX is more tricky because it's a new voxel we haven't seen yet. It could be outside the volume, + // but only in the 'X' direction because that's the way we are moving + m_uValidFlags[PositiveXShift] = this->mXPosInVolume < this->mVolume->getEnclosingRegion().getUpperX(); + } + else + { + // We're moving from a position which was outside the volume. Note that moving in 'X' can still cause + // the validity of Y and Z to change as we could start grazing along a face of the volume. It's safest + // just to compute all the flags fully. + updateValidFlagsState(); + } } template @@ -108,8 +126,18 @@ namespace PolyVox this->mYPosInVolume++; mCurrentVoxel += this->mVolume->getWidth(); - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | PositiveY)) + { + // See comments in movePositiveX(). + m_uValidFlags |= (NegativeY | Current); + m_uValidFlags[PositiveYShift] = this->mYPosInVolume < this->mVolume->getEnclosingRegion().getUpperY(); + } + else + { + // See comments in movePositiveX(). + updateValidFlagsState(); + } } template @@ -118,8 +146,18 @@ namespace PolyVox this->mZPosInVolume++; mCurrentVoxel += this->mVolume->getWidth() * this->mVolume->getHeight(); - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | PositiveZ)) + { + // See comments in movePositiveX(). + m_uValidFlags |= (NegativeZ | Current); + m_uValidFlags[PositiveZShift] = this->mZPosInVolume < this->mVolume->getEnclosingRegion().getUpperZ(); + } + else + { + // See comments in movePositiveX(). + updateValidFlagsState(); + } } template @@ -128,8 +166,18 @@ namespace PolyVox this->mXPosInVolume--; --mCurrentVoxel; - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | NegativeX)) + { + // See comments in movePositiveX(). + m_uValidFlags |= (PositiveX | Current); + m_uValidFlags[NegativeXShift] = this->mXPosInVolume > this->mVolume->getEnclosingRegion().getLowerX(); + } + else + { + // See comments in movePositiveX(). + updateValidFlagsState(); + } } template @@ -138,8 +186,18 @@ namespace PolyVox this->mYPosInVolume--; mCurrentVoxel -= this->mVolume->getWidth(); - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | NegativeY)) + { + // See comments in movePositiveX(). + m_uValidFlags |= (PositiveY | Current); + m_uValidFlags[NegativeYShift] = this->mYPosInVolume > this->mVolume->getEnclosingRegion().getLowerY(); + } + else + { + // See comments in movePositiveX(). + updateValidFlagsState(); + } } template @@ -148,8 +206,18 @@ namespace PolyVox this->mZPosInVolume--; mCurrentVoxel -= this->mVolume->getWidth() * this->mVolume->getHeight(); - //FIXME - Can be faster by just 'shifting' the flags. - updateValidFlagsState(); + // Update the valid position flags + if(checkValidFlags(Current | NegativeZ)) + { + // See comments in movePositiveX(). + m_uValidFlags |= (PositiveZ | Current); + m_uValidFlags[NegativeZShift] = this->mZPosInVolume > this->mVolume->getEnclosingRegion().getLowerZ(); + } + else + { + // See comments in movePositiveX(). + updateValidFlagsState(); + } } template @@ -465,7 +533,7 @@ namespace PolyVox } template - inline bool RawVolume::Sampler::checkValidFlags(uint8_t uFlagsToCheck) const + inline bool RawVolume::Sampler::checkValidFlags(std::bitset<7> uFlagsToCheck) const { return (m_uValidFlags & uFlagsToCheck) == uFlagsToCheck; }