From 7276b872c42cc7672cc020b50d76f3b03eb44647 Mon Sep 17 00:00:00 2001 From: Daviw Williams Date: Wed, 12 Jun 2013 15:03:34 +0200 Subject: [PATCH] More work replacing getVoxelAt with getVoxel. --- .../include/PolyVoxCore/BaseVolume.h | 17 ++-- .../include/PolyVoxCore/BaseVolume.inl | 78 ++++++++++++------- .../include/PolyVoxCore/BaseVolumeSampler.inl | 46 ++++------- tests/TestVolumeSubclass.cpp | 78 +++++++++++++++++++ 4 files changed, 152 insertions(+), 67 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h index 5bc112a6..13a04c76 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h @@ -168,18 +168,23 @@ namespace PolyVox int32_t getShortestSideLength(void) const; /// Gets the length of the diagonal in voxels float getDiagonalLength(void) 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) const; + template + VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const; /// Gets a voxel at the position given by a 3D vector - VoxelType getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck = BoundsChecks::Full) const; + template + VoxelType getVoxel(const Vector3DInt32& v3dPos, 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, WrapMode eWrapMode = WrapModes::None, VoxelType tBorder = VoxelType()) const; + /// Gets a voxel at the position given by a 3D vector + 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; - /// Gets a voxel at the position given by a 3D vector - VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const; /// Sets the value used for voxels which are outside the volume void setBorderValue(const VoxelType& tBorder); diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl index c9fc1fcb..6de44062 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl @@ -154,26 +154,70 @@ namespace PolyVox } //////////////////////////////////////////////////////////////////////////////// + /// This version of the function requires the wrap mode to be specified as a + /// template parameter, which can provide better performance. /// \param uXPos The \c x position of the voxel /// \param uYPos The \c y position of the voxel /// \param uZPos The \c z position of the voxel + /// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume. + /// \param tBorder The border value to use if the wrap mode is set to 'Border'. /// \return The voxel value //////////////////////////////////////////////////////////////////////////////// template - VoxelType BaseVolume::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, BoundsCheck /*eBoundsCheck*/) const + template + VoxelType BaseVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const { - POLYVOX_THROW(not_implemented, "You should never call the base class version of this function."); + POLYVOX_ASSERT(false, "You should never call the base class version of this function."); return VoxelType(); } //////////////////////////////////////////////////////////////////////////////// - /// \param v3dPos The 3D position of the voxel + /// This version of the function requires the wrap mode to be specified as a + /// template parameter, which can provide better performance. + /// \param uXPos The \c x position of the voxel + /// \param uYPos The \c y position of the voxel + /// \param uZPos The \c z position of the voxel + /// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume. + /// \param tBorder The border value to use if the wrap mode is set to 'Border'. /// \return The voxel value //////////////////////////////////////////////////////////////////////////////// template - VoxelType BaseVolume::getVoxel(const Vector3DInt32& /*v3dPos*/, BoundsCheck /*eBoundsCheck*/) const + template + VoxelType BaseVolume::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const { - POLYVOX_THROW(not_implemented, "You should never call the base class version of this function."); + POLYVOX_ASSERT(false, "You should never call the base class version of this function."); + return VoxelType(); + } + + //////////////////////////////////////////////////////////////////////////////// + /// This version of the function is provided so that the wrap mode does not need + /// to be specified as a template parameter, as it may be confusing to some users. + /// \param uXPos The \c x position of the voxel + /// \param uYPos The \c y position of the voxel + /// \param uZPos The \c z position of the voxel + /// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume. + /// \param tBorder The border value to use if the wrap mode is set to 'Border'. + /// \return The voxel value + //////////////////////////////////////////////////////////////////////////////// + template + VoxelType BaseVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const + { + POLYVOX_ASSERT(false, "You should never call the base class version of this function."); + return VoxelType(); + } + + //////////////////////////////////////////////////////////////////////////////// + /// This version of the function is provided so that the wrap mode does not need + /// to be specified as a template parameter, as it may be confusing to some users. + /// \param v3dPos The 3D position of the voxel + /// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume. + /// \param tBorder The border value to use if the wrap mode is set to 'Border'. + /// \return The voxel value + //////////////////////////////////////////////////////////////////////////////// + template + VoxelType BaseVolume::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const + { + POLYVOX_ASSERT(false, "You should never call the base class version of this function."); return VoxelType(); } @@ -207,30 +251,6 @@ namespace PolyVox return VoxelType(); } - //////////////////////////////////////////////////////////////////////////////// - /// \param uXPos The \c x position of the voxel - /// \param uYPos The \c y position of the voxel - /// \param uZPos The \c z position of the voxel - /// \return The voxel value - //////////////////////////////////////////////////////////////////////////////// - template - VoxelType BaseVolume::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const - { - POLYVOX_THROW(not_implemented, "You should never call the base class version of this function."); - return VoxelType(); - } - - //////////////////////////////////////////////////////////////////////////////// - /// \param v3dPos The 3D position of the voxel - /// \return The voxel value - //////////////////////////////////////////////////////////////////////////////// - template - VoxelType BaseVolume::getVoxel(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const - { - POLYVOX_THROW(not_implemented, "You should never call the base class version of this function."); - return VoxelType(); - } - //////////////////////////////////////////////////////////////////////////////// /// \param tBorder The value to use for voxels outside the volume. //////////////////////////////////////////////////////////////////////////////// diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl index 8301315e..eaf3b29d 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl @@ -57,7 +57,7 @@ namespace PolyVox template VoxelType BaseVolume::Sampler::getVoxel(void) const { - return mVolume->getVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume); + return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume); } template @@ -347,38 +347,20 @@ namespace PolyVox template VoxelType BaseVolume::Sampler::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const { - if(mVolume->getEnclosingRegion().containsPoint(uXPos, uYPos, uZPos)) + switch(m_eWrapMode) { - return mVolume->getVoxelAt(uXPos, uYPos, uZPos); - } - else - { - switch(m_eWrapMode) - { - case WrapModes::Clamp: - { - const Vector3DInt32& lowerCorner = mVolume->m_regValidRegion.getLowerCorner(); - const Vector3DInt32& upperCorner = mVolume->m_regValidRegion.getUpperCorner(); - - int32_t iClampedX = clamp(uXPos, lowerCorner.getX(), upperCorner.getX()); - int32_t iClampedY = clamp(uYPos, lowerCorner.getY(), upperCorner.getY()); - int32_t iClampedZ = clamp(uZPos, lowerCorner.getZ(), upperCorner.getZ()); - - return mVolume->getVoxelAt(iClampedX, iClampedY, iClampedZ); - //No need to break as we've returned - } - case WrapModes::Border: - { - return m_tBorder; - //No need to break as we've returned - } - default: - { - //Should never happen. However, this assert appears to hurt performance (logging prevents inlining?). - POLYVOX_ASSERT(false, "Wrap mode parameter has an unrecognised value."); - return VoxelType(); - } - } + case WrapModes::None: + return mVolume->getVoxel(uXPos, uYPos, uZPos, m_tBorder); + case WrapModes::Clamp: + return mVolume->getVoxel(uXPos, uYPos, uZPos, m_tBorder); + case WrapModes::Border: + return mVolume->getVoxel(uXPos, uYPos, uZPos, m_tBorder); + case WrapModes::DontCheck: + return mVolume->getVoxel(uXPos, uYPos, uZPos, m_tBorder); + default: + // Should never happen + POLYVOX_ASSERT(false, "Invalid wrap mode"); + return VoxelType(); } } } diff --git a/tests/TestVolumeSubclass.cpp b/tests/TestVolumeSubclass.cpp index e70afb92..275dd3b1 100644 --- a/tests/TestVolumeSubclass.cpp +++ b/tests/TestVolumeSubclass.cpp @@ -68,6 +68,84 @@ public: /// Destructor ~VolumeSubclass() {}; + /// Gets a voxel at the position given by x,y,z coordinates + template + VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const + { + switch(eWrapMode) + { + case WrapModes::None: + { + if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false) + { + POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); + } + + return mVolumeData[uXPos][uYPos][uZPos]; + } + case WrapModes::Clamp: + { + //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 mVolumeData[uXPos][uYPos][uZPos]; + } + case WrapModes::Border: + { + if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) + { + return mVolumeData[uXPos][uYPos][uZPos]; + } + else + { + return tBorder; + } + } + case WrapModes::DontCheck: + { + return mVolumeData[uXPos][uYPos][uZPos]; + } + } + } + + /// Gets a voxel at the position given by a 3D vector + template + VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const + { + // Simply call through to the real implementation + return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder); + } + + /// 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 = WrapModes::None, VoxelType tBorder = VoxelType()) const + { + switch(eWrapMode) + { + case WrapModes::None: + return getVoxel(uXPos, uYPos, uZPos, WrapModes::None, tBorder); + case WrapModes::Clamp: + return getVoxel(uXPos, uYPos, uZPos, WrapModes::Clamp, tBorder); + case WrapModes::Border: + return getVoxel(uXPos, uYPos, uZPos, WrapModes::Border, tBorder); + case WrapModes::DontCheck: + return getVoxel(uXPos, uYPos, uZPos, WrapModes::DontCheck, tBorder); + default: + // Should never happen + POLYVOX_ASSERT(false, "Invalid wrap mode"); + return VoxelType(); + } + } + + /// Gets a voxel at the position given by a 3D vector + VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::None, VoxelType tBorder = VoxelType()) const + { + return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder); + } + /// Gets the value used for voxels which are outside the volume VoxelType getBorderValue(void) const { return 0; } /// Gets a voxel at the position given by x,y,z coordinates