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