diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h index a87b92a5..5bc112a6 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h @@ -56,12 +56,18 @@ namespace PolyVox { enum WrapMode { - Clamp = 0, - Border = 1 + None = 0, + Clamp = 1, + Border = 2, + DontCheck = 3 }; } typedef WrapModes::WrapMode WrapMode; + // Required for a trick to implement specialization of template member + // functions in template classes. See http://stackoverflow.com/a/4951057 + template struct WrapModeType{}; + template class BaseVolume { diff --git a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl index 79329a7f..22e476a9 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LowPassFilter.inl @@ -192,8 +192,8 @@ namespace PolyVox { for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) { - AccumulationType previousSum = static_cast(satVolume.getVoxel(x,y-1,z, BoundsChecks::BorderPos)); - AccumulationType currentSum = static_cast(satVolume.getVoxel(x,y,z, BoundsChecks::BorderPos)); + AccumulationType previousSum = static_cast(satVolume.getVoxel(x,y-1,z, WrapModes::Border)); + AccumulationType currentSum = static_cast(satVolume.getVoxel(x,y,z, WrapModes::Border)); satVolume.setVoxelAt(x,y,z,previousSum + currentSum); } @@ -206,8 +206,8 @@ namespace PolyVox { for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) { - AccumulationType previousSum = static_cast(satVolume.getVoxel(x,y,z-1, BoundsChecks::BorderPos)); - AccumulationType currentSum = static_cast(satVolume.getVoxel(x,y,z, BoundsChecks::BorderPos)); + AccumulationType previousSum = static_cast(satVolume.getVoxel(x,y,z-1, WrapModes::Border)); + AccumulationType currentSum = static_cast(satVolume.getVoxel(x,y,z, WrapModes::Border)); satVolume.setVoxelAt(x,y,z,previousSum + currentSum); } @@ -234,14 +234,14 @@ namespace PolyVox int32_t satUpperY = iSrcY + border; int32_t satUpperZ = iSrcZ + border; - AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ, BoundsChecks::BorderPos); - AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ, BoundsChecks::BorderPos); - AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ, BoundsChecks::BorderPos); - AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ, BoundsChecks::BorderPos); - AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ, BoundsChecks::BorderPos); - AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ, BoundsChecks::BorderPos); - AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ, BoundsChecks::BorderPos); - AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ, BoundsChecks::BorderPos); + AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ, WrapModes::Border); + AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ, WrapModes::Border); + AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ, WrapModes::Border); + AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ, WrapModes::Border); + AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ, WrapModes::Border); + AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ, WrapModes::Border); + AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ, WrapModes::Border); + AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ, WrapModes::Border); AccumulationType sum = h+c-d-g-f-a+b+e; uint32_t sideLength = border * 2 + 1; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index 14091c92..9da7c5d1 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -116,21 +116,21 @@ namespace PolyVox ~RawVolume(); /// Gets a voxel at the position given by x,y,z coordinates - template + template VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const; /// Gets a voxel at the position given by x,y,z coordinates - VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck = BoundsChecks::Full, VoxelType tBorder = VoxelType()) const; + VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::None, VoxelType tBorder = VoxelType()) const; /// Gets a voxel at the position given by a 3D vector - VoxelType getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck = BoundsChecks::Full, VoxelType tBorder = VoxelType()) const; + VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::None, VoxelType tBorder = VoxelType()) const; /// Gets a voxel at the position given by x,y,z coordinates VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const; /// Gets a voxel at the position given by a 3D vector VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const; /// Gets a voxel at the position given by x,y,z coordinates - VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const; + //VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const; /// Gets a voxel at the position given by a 3D vector - VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const; + //VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const; /// Sets the voxel at the position given by x,y,z coordinates void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full); @@ -154,12 +154,12 @@ namespace PolyVox private: void initialise(const Region& regValidRegion); - template - VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const; - VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const; - VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const; - VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const; - VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const; + template + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const; //The block data VoxelType* m_pData; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl index fa323173..5397732f 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl @@ -83,11 +83,11 @@ namespace PolyVox /// \return The voxel value //////////////////////////////////////////////////////////////////////////////// template - template + template VoxelType RawVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const { // Simply call through to the real implementation - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } //////////////////////////////////////////////////////////////////////////////// @@ -100,29 +100,29 @@ namespace PolyVox /// \return The voxel value //////////////////////////////////////////////////////////////////////////////// template - VoxelType RawVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck, VoxelType tBorder) const + VoxelType RawVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const { // If bounds checking is enabled then we validate the // bounds, and throw an exception if they are violated. - if(eBoundsCheck == BoundsChecks::Full) + if(eWrapMode == WrapModes::None) { // Call through to the real implementation - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } - else if(eBoundsCheck == BoundsChecks::None) + else if(eWrapMode == WrapModes::Clamp) { // Call through to the real implementation - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } - else if(eBoundsCheck == BoundsChecks::ClampPos) + else if(eWrapMode == WrapModes::Border) { // Call through to the real implementation - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } else { // Call through to the real implementation - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } } @@ -134,9 +134,9 @@ namespace PolyVox /// is inside the volume's enclosing region then you can skip this check to gain some performance. //////////////////////////////////////////////////////////////////////////////// template - VoxelType RawVolume::getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck, VoxelType tBorder) const + VoxelType RawVolume::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const { - return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eBoundsCheck, tBorder); + return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder); } //////////////////////////////////////////////////////////////////////////////// @@ -184,7 +184,7 @@ namespace PolyVox /// \param uZPos The \c z position of the voxel /// \return The voxel value //////////////////////////////////////////////////////////////////////////////// - template + /*template VoxelType RawVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const { switch(eWrapMode) @@ -232,7 +232,7 @@ namespace PolyVox VoxelType RawVolume::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const { return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder); - } + }*/ //////////////////////////////////////////////////////////////////////////////// /// \param uXPos the \c x position of the voxel @@ -366,25 +366,52 @@ namespace PolyVox } template - template - VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const { POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!"); } template - VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const { if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false) { POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); } - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); } template - VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const + { + //Perform clamping + uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX()); + uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY()); + uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ()); + uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX()); + uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY()); + uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ()); + + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); + } + + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const + { + if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) + { + return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, WrapModeType()); // No bounds checks as we've just validated the position. + } + else + { + return tBorder; //FIXME - Should return border value. + } + } + + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, WrapModeType) const { const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner(); int32_t iLocalXPos = uXPos - v3dLowerCorner.getX(); @@ -398,32 +425,5 @@ namespace PolyVox iLocalZPos * this->getWidth() * this->getHeight() ]; } - - template - VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const - { - //Perform clamping - uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX()); - uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY()); - uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ()); - uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX()); - uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY()); - uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ()); - - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); - } - - template - VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType) const - { - if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) - { - return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType()); // No bounds checks as we've just validated the position. - } - else - { - return tBorder; //FIXME - Should return border value. - } - } }