Merge branch 'feature/bounds-checks' into develop

This commit is contained in:
Daviw Williams 2013-06-13 17:04:55 +02:00
commit c91b10ce73
28 changed files with 935 additions and 462 deletions

View File

@ -184,7 +184,7 @@ void createSphereInVolume(LargeVolume<MaterialDensityPair44>& volData, Vector3DF
uint8_t uDensity = MaterialDensityPair44::getMaxDensity();
//Get the old voxel
MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z);
MaterialDensityPair44 voxel = volData.getVoxel(x,y,z);
//Modify the density
voxel.setDensity(uDensity);

View File

@ -55,15 +55,8 @@ void createSphereInVolume(SimpleVolume<uint8_t>& volData, float fRadius)
if(fDistToCenter <= fRadius)
{
//Our new density value
//uint8_t uDensity = Density8::getmaxDensity()();
uint8_t uDensity = std::numeric_limits<uint8_t>::max();
//Get the old voxel
//uint8_t voxel = volData.getVoxelAt(x,y,z);
//Modify the density
//voxel.setDensity(uDensity);
//Wrte the voxel value into the volume
volData.setVoxelAt(x, y, z, uDensity);
}

View File

@ -36,16 +36,23 @@ namespace PolyVox
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// More details to come...
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace WrapModes
{
enum WrapMode
{
Clamp = 0,
Border = 1
Validate = 0,
Clamp = 1,
Border = 2,
AssumeValid = 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 <WrapMode W> struct WrapModeType{};
template <typename _VoxelType>
class BaseVolume
{
@ -109,7 +116,7 @@ namespace PolyVox
inline VoxelType peekVoxel1px1py1pz(void) const;
protected:
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
DerivedVolumeType* mVolume;
@ -146,22 +153,31 @@ 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 <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
template <WrapMode eWrapMode>
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) const;
template <WrapMode eWrapMode>
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
/// Sets the value used for voxels which are outside the volume
void setBorderValue(const VoxelType& tBorder);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by a 3D vector
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at the position given by a 3D vector
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);

View File

@ -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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
template <WrapMode eWrapMode>
VoxelType BaseVolume<VoxelType>::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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
template <WrapMode eWrapMode>
VoxelType BaseVolume<VoxelType>::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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::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();
}
@ -201,30 +245,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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(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 <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(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.
////////////////////////////////////////////////////////////////////////////////
@ -234,6 +254,28 @@ namespace PolyVox
m_tBorderValue = tBorder;
}
////////////////////////////////////////////////////////////////////////////////
/// \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 tValue the value to which the voxel will be set
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void BaseVolume<VoxelType>::setVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
{
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
}
////////////////////////////////////////////////////////////////////////////////
/// \param v3dPos the 3D position of the voxel
/// \param tValue the value to which the voxel will be set
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void BaseVolume<VoxelType>::setVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
{
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
}
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel

View File

@ -57,7 +57,7 @@ namespace PolyVox
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxel(void) const
{
return mVolume->getVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume);
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume, WrapModes::Validate); // FIXME - Use templatised version instead but watch for Linux compile errors.
}
template <typename VoxelType>
@ -154,63 +154,63 @@ namespace PolyVox
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1nz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny0pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1nz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py0pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume );
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1nz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py0pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1pz(void) const
{
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
}
//////////////////////////////////////////////////////////////////////////
@ -219,63 +219,63 @@ namespace PolyVox
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1nz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny0pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1nz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py0pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume );
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1nz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py0pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1pz(void) const
{
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume + 1);
}
//////////////////////////////////////////////////////////////////////////
@ -284,100 +284,83 @@ namespace PolyVox
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1nz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny0pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1nz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py0pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume );
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1nz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py0pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume );
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume );
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1pz(void) const
{
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
}
template <typename VoxelType>
template <typename DerivedVolumeType>
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
if(mVolume->getEnclosingRegion().containsPoint(uXPos, uYPos, uZPos))
{
return mVolume->getVoxelAt(uXPos, uYPos, uZPos);
}
else
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
switch(m_eWrapMode)
{
case WrapModes::Validate:
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Validate, m_tBorder);
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
}
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Clamp, m_tBorder);
case WrapModes::Border:
{
return m_tBorder;
//No need to break as we've returned
}
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Border, m_tBorder);
case WrapModes::AssumeValid:
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::AssumeValid, m_tBorder);
default:
{
//Should never happen
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
}
}
// Should never happen
POLYVOX_ASSERT(false, "Invalid wrap mode");
return VoxelType();
}
}
}

View File

@ -39,14 +39,14 @@ namespace PolyVox
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
return m_pVolume.getVoxel<WrapModes::AssumeValid>(uXPos, uYPos, uZPos);
}
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
return getVoxelAt<WrapModes::AssumeValid>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const

View File

@ -53,7 +53,7 @@ namespace PolyVox
uint32_t material = 0;
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x+1,y,z,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x+1,y,z,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), static_cast<float>(material)));
@ -63,7 +63,7 @@ namespace PolyVox
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x+1,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x+1,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), static_cast<float>(material)));
@ -74,7 +74,7 @@ namespace PolyVox
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y+1,z,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y+1,z,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), static_cast<float>(material)));
@ -84,7 +84,7 @@ namespace PolyVox
m_meshCurrent->addTriangleCubic(v0,v1,v2);
m_meshCurrent->addTriangleCubic(v1,v3,v2);
}
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y+1,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y+1,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), static_cast<float>(material)));
@ -95,7 +95,7 @@ namespace PolyVox
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z+1,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z+1,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), static_cast<float>(material)));
@ -105,7 +105,7 @@ namespace PolyVox
m_meshCurrent->addTriangleCubic(v0,v2,v1);
m_meshCurrent->addTriangleCubic(v1,v2,v3);
}
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z+1,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z+1,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
{
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), static_cast<float>(material)));
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), static_cast<float>(material)));

View File

@ -52,14 +52,14 @@ namespace PolyVox
const int32_t z = volIter.getPosition().getZ();
//FIXME - bitwise way of doing this?
typename VolumeType::VoxelType voxel1nx = volIter.getVoxelAt(x-2, y ,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1px = volIter.getVoxelAt(x-2, y ,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1nx = volIter.getVoxel(x-2, y ,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1px = volIter.getVoxel(x-2, y ,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1ny = volIter.getVoxelAt(x , y-2,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1py = volIter.getVoxelAt(x , y-2,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1ny = volIter.getVoxel(x , y-2,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1py = volIter.getVoxel(x , y-2,z ) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1nz = volIter.getVoxelAt(x , y ,z-2) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1pz = volIter.getVoxelAt(x , y ,z-2) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1nz = volIter.getVoxel(x , y ,z-2) > 0 ? 1: 0;
typename VolumeType::VoxelType voxel1pz = volIter.getVoxel(x , y ,z-2) > 0 ? 1: 0;
return Vector3DFloat
(

View File

@ -52,8 +52,8 @@ namespace PolyVox
Block(uint16_t uSideLength = 0);
uint16_t getSideLength(void) const;
VoxelType getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const;
VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);

View File

@ -58,7 +58,7 @@ namespace PolyVox
}
template <typename VoxelType>
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
VoxelType Block<VoxelType>::getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
{
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
@ -75,9 +75,9 @@ namespace PolyVox
}
template <typename VoxelType>
VoxelType Block<VoxelType>::getVoxelAt(const Vector3DUint16& v3dPos) const
VoxelType Block<VoxelType>::getVoxel(const Vector3DUint16& v3dPos) const
{
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
template <typename VoxelType>

View File

@ -258,6 +258,12 @@ namespace PolyVox
#define POLYVOX_THROW(type, message) \
PolyVox::logError() << (message); \
throw type((message))
// Some fast functions (getVoxel(), etc) use exceptions for error handling but don't want the overhead of logging.
// This overhead is present even if no exception is thrown, probably because the presence of the logging code prevents
// some inlining. Therefore we provide this macro which doesn't log for such specialised circumstances.
#define POLYVOX_THROW_DONT_LOG(type, message) \
throw type((message))
#else
namespace PolyVox
{
@ -271,6 +277,13 @@ namespace PolyVox
PolyVox::logError() << (message); \
type except = (type)((message)); \
getThrowHandler()((except), __FILE__, __LINE__)
// Some fast functions (getVoxel(), etc) use exceptions for error handling but don't want the overhead of logging.
// This overhead is present even if no exception is thrown, probably because the presence of the logging code prevents
// some inlining. Therefore we provide this macro which doesn't log for such specialised circumstances.
#define POLYVOX_THROW_DONT_LOG(type, message) \
type except = (type)((message)); \
getThrowHandler()((except), __FILE__, __LINE__)
#endif
namespace PolyVox

View File

@ -266,23 +266,31 @@ namespace PolyVox
~LargeVolume();
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
template <WrapMode eWrapMode>
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) const;
template <WrapMode eWrapMode>
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
/// Sets the number of blocks for which uncompressed data is stored
void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks);
/// Sets the number of blocks which can be in memory before the paging system starts unloading them
void setMaxNumberOfBlocksInMemory(uint32_t uMaxNumberOfBlocksInMemory);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by a 3D vector
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at the position given by a 3D vector
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
@ -326,6 +334,14 @@ namespace PolyVox
};
void initialise(const Region& regValidRegion, uint16_t uBlockSideLength);
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
template <WrapMode eWrapMode>
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
/// gets called when a new region is allocated and needs to be filled
/// NOTE: accessing ANY voxels outside this region during the process of this function
/// is absolutely unsafe

View File

@ -116,38 +116,83 @@ 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 <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
template <WrapMode eWrapMode>
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
// Simply call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// \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 <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
template <WrapMode eWrapMode>
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
// Simply call through to the real implementation
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// 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 <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
{
switch(eWrapMode)
{
case WrapModes::Validate:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
case WrapModes::Clamp:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
case WrapModes::Border:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
case WrapModes::AssumeValid:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
default:
// Should never happen
POLYVOX_ASSERT(false, "Invalid wrap mode");
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 <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
}
////////////////////////////////////////////////////////////////////////////////
@ -171,7 +216,7 @@ namespace PolyVox
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
return pUncompressedBlock->getVoxel(xOffset,yOffset,zOffset);
}
else
{
@ -189,61 +234,6 @@ namespace PolyVox
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
////////////////////////////////////////////////////////////////////////////////
/// \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 <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
{
switch(eWrapMode)
{
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());
//Get the voxel value
return getVoxel(uXPos, uYPos, uZPos);
//No need to break as we've returned
}
case WrapModes::Border:
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{
return getVoxel(uXPos, uYPos, uZPos);
}
else
{
return tBorder;
}
//No need to break as we've returned
}
default:
{
//Should never happen
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// \param v3dPos The 3D position of the voxel
/// \return The voxel value
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
{
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// Increasing the size of the block cache will increase memory but may improve performance.
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
@ -272,6 +262,56 @@ namespace PolyVox
m_uMaxNumberOfBlocksInMemory = uMaxNumberOfBlocksInMemory;
}
////////////////////////////////////////////////////////////////////////////////
/// \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 tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void LargeVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
{
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
{
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
}
// This validation is skipped if the wrap mode is 'DontCheck'
if(eWrapMode == WrapModes::Validate)
{
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
{
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
}
}
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
}
////////////////////////////////////////////////////////////////////////////////
/// \param v3dPos the 3D position of the voxel
/// \param tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void LargeVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
{
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
}
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel
@ -705,5 +745,66 @@ namespace PolyVox
return uSizeInBytes;
}
template <typename VoxelType>
template <WrapMode eWrapMode>
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
{
// This function should never be called because one of the specialisations should always match.
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
}
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
else
{
return tBorder;
}
}
template <typename VoxelType>
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
{
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
return pUncompressedBlock->getVoxel(xOffset,yOffset,zOffset);
}
}

View File

@ -88,7 +88,7 @@ namespace PolyVox
}
else
{
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
}
}
@ -286,7 +286,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -296,7 +296,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -306,7 +306,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -316,7 +316,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -326,7 +326,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -336,7 +336,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -346,7 +346,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -356,7 +356,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -366,7 +366,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -378,7 +378,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -388,7 +388,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -398,7 +398,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -408,7 +408,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -418,7 +418,7 @@ namespace PolyVox
{
return *mCurrentVoxel;
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -428,7 +428,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -438,7 +438,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -448,7 +448,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -458,7 +458,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -470,7 +470,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -480,7 +480,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -490,7 +490,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -500,7 +500,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -510,7 +510,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -520,7 +520,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -530,7 +530,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -540,7 +540,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -550,7 +550,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
}

View File

@ -192,8 +192,8 @@ namespace PolyVox
{
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y-1,z));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z));
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z, WrapModes::Border));
AccumulationType currentSum = static_cast<AccumulationType>(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<AccumulationType>(satVolume.getVoxelAt(x,y,z-1));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z));
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1, WrapModes::Border));
AccumulationType currentSum = static_cast<AccumulationType>(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.getVoxelAt(satLowerX,satLowerY,satLowerZ);
AccumulationType b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ);
AccumulationType c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ);
AccumulationType d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ);
AccumulationType e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ);
AccumulationType f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ);
AccumulationType g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ);
AccumulationType h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ);
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;

View File

@ -116,18 +116,26 @@ namespace PolyVox
~RawVolume();
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
template <WrapMode eWrapMode>
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) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> 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 <tt>x,y,z</tt> coordinates
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
template <WrapMode eWrapMode>
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
/// Gets a voxel at the position given by a 3D vector
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by a 3D vector
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at the position given by a 3D vector
@ -146,6 +154,14 @@ namespace PolyVox
private:
void initialise(const Region& regValidRegion);
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
template <WrapMode eWrapMode>
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
//The block data
VoxelType* m_pData;
};

View File

@ -74,38 +74,83 @@ 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 <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
template <WrapMode eWrapMode>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
return m_pData
[
iLocalXPos +
iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight()
];
// Simply call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// \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 <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
template <WrapMode eWrapMode>
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
// Simply call through to the real implementation
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// 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 <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
{
switch(eWrapMode)
{
case WrapModes::Validate:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
case WrapModes::Clamp:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
case WrapModes::Border:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
case WrapModes::AssumeValid:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
default:
// Should never happen
POLYVOX_ASSERT(false, "Invalid wrap mode");
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 <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
}
////////////////////////////////////////////////////////////////////////////////
@ -148,58 +193,53 @@ namespace PolyVox
}
////////////////////////////////////////////////////////////////////////////////
/// \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
/// \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 tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
void RawVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
{
switch(eWrapMode)
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
{
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());
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
}
//Get the voxel value
return getVoxel(uXPos, uYPos, uZPos);
//No need to break as we've returned
}
case WrapModes::Border:
// This validation is skipped if the wrap mode is 'DontCheck'
if(eWrapMode == WrapModes::Validate)
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
{
return getVoxel(uXPos, uYPos, uZPos);
}
else
{
return tBorder;
}
//No need to break as we've returned
}
default:
{
//Should never happen
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
}
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
}
}
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
m_pData
[
iLocalXPos +
iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight()
] = tValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \param v3dPos The 3D position of the voxel
/// \return The voxel value
/// \param v3dPos the 3D position of the voxel
/// \param tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
void RawVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
{
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
}
////////////////////////////////////////////////////////////////////////////////
@ -285,5 +325,66 @@ namespace PolyVox
return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType);
}
template <typename VoxelType>
template <WrapMode eWrapMode>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
{
// This function should never be called because one of the specialisations should always match.
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
else
{
return tBorder;
}
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
{
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
return m_pData
[
iLocalXPos +
iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight()
];
}
}

View File

@ -51,7 +51,7 @@ namespace PolyVox
}
else
{
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
}
}
@ -229,7 +229,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -239,7 +239,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -249,7 +249,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -259,7 +259,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -269,7 +269,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -279,7 +279,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -289,7 +289,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -299,7 +299,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -309,7 +309,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -321,7 +321,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -331,7 +331,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -341,7 +341,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -351,7 +351,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -361,7 +361,7 @@ namespace PolyVox
{
return *mCurrentVoxel;
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -371,7 +371,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -381,7 +381,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -391,7 +391,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -401,7 +401,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -413,7 +413,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -423,7 +423,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -433,7 +433,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -443,7 +443,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -453,7 +453,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -463,7 +463,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -473,7 +473,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -483,7 +483,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->getWidth());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -493,7 +493,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
}

View File

@ -149,6 +149,9 @@ namespace PolyVox
/// Tests whether the given position is contained in the 'z' range of this Region.
bool containsPointInZ(int32_t pos, uint8_t boundary = 0) const;
/// Tests whether the given Region is contained in this Region.
bool containsRegion(const Region& reg, uint8_t boundary = 0) const;
/// Enlarges the Region so that it contains the specified position.
void accumulate(int32_t iX, int32_t iY, int32_t iZ);
/// Enlarges the Region so that it contains the specified position.

View File

@ -155,18 +155,26 @@ namespace PolyVox
~SimpleVolume();
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
template <WrapMode eWrapMode>
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) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> 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 <tt>x,y,z</tt> coordinates
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
template <WrapMode eWrapMode>
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
/// Gets a voxel at the position given by a 3D vector
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by a 3D vector
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at the position given by a 3D vector
@ -185,6 +193,14 @@ namespace PolyVox
private:
void initialise(const Region& regValidRegion, uint16_t uBlockSideLength);
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
template <WrapMode eWrapMode>
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const;
//The block data

View File

@ -74,38 +74,83 @@ 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 <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
template <WrapMode eWrapMode>
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
{
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
// Simply call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// \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 <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
template <WrapMode eWrapMode>
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
// Simply call through to the real implementation
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// 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 <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
{
switch(eWrapMode)
{
case WrapModes::Validate:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
case WrapModes::Clamp:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
case WrapModes::Border:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
case WrapModes::AssumeValid:
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
default:
// Should never happen
POLYVOX_ASSERT(false, "Invalid wrap mode");
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 <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
}
////////////////////////////////////////////////////////////////////////////////
@ -148,58 +193,53 @@ namespace PolyVox
}
////////////////////////////////////////////////////////////////////////////////
/// \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
/// \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 tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
void SimpleVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
{
switch(eWrapMode)
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
{
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());
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
}
//Get the voxel value
return getVoxel(uXPos, uYPos, uZPos);
//No need to break as we've returned
}
case WrapModes::Border:
// This validation is skipped if the wrap mode is 'DontCheck'
if(eWrapMode == WrapModes::Validate)
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
{
return getVoxel(uXPos, uYPos, uZPos);
}
else
{
return tBorder;
}
//No need to break as we've returned
}
default:
{
//Should never happen
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
}
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
}
}
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
}
////////////////////////////////////////////////////////////////////////////////
/// \param v3dPos The 3D position of the voxel
/// \return The voxel value
/// \param v3dPos the 3D position of the voxel
/// \param tValue the value to which the voxel will be set
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
void SimpleVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
{
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
}
////////////////////////////////////////////////////////////////////////////////
@ -336,5 +376,66 @@ namespace PolyVox
return uSizeInBytes;
}
template <typename VoxelType>
template <WrapMode eWrapMode>
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
{
// This function should never be called because one of the specialisations should always match.
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
}
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
}
else
{
return tBorder;
}
}
template <typename VoxelType>
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
{
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
}
}

View File

@ -94,7 +94,7 @@ namespace PolyVox
}
else
{
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
}
}
@ -305,7 +305,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -315,7 +315,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -325,7 +325,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -335,7 +335,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -345,7 +345,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -355,7 +355,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -365,7 +365,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -375,7 +375,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -385,7 +385,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -397,7 +397,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -407,7 +407,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -417,7 +417,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -427,7 +427,7 @@ namespace PolyVox
{
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -437,7 +437,7 @@ namespace PolyVox
{
return *mCurrentVoxel;
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -447,7 +447,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -457,7 +457,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -467,7 +467,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -477,7 +477,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
//////////////////////////////////////////////////////////////////////////
@ -489,7 +489,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -499,7 +499,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -509,7 +509,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -519,7 +519,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -529,7 +529,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -539,7 +539,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -549,7 +549,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -559,7 +559,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
}
template <typename VoxelType>
@ -569,7 +569,7 @@ namespace PolyVox
{
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
}
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
}
}

View File

@ -72,7 +72,7 @@ namespace PolyVox
{
for(int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++,dx++)
{
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxelAt(sx,sy,sz);
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz, WrapModes::AssumeValid); // FIXME use templatised version of getVoxel(), but watch out for Linux compile issues.
const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel);
m_pVolDst->setVoxelAt(dx,dy,dz,tDstVoxel);
}

View File

@ -301,6 +301,23 @@ namespace PolyVox
&& (pos >= m_iLowerZ + boundary);
}
/**
* The boundary value can be used to ensure a region is only considered to be inside
* another Region if it is that far in in all directions. Also, the test is inclusive such
* that a region is considered to be inside of itself.
* \param reg The region to test.
* \param boundary The desired boundary value.
*/
bool Region::containsRegion(const Region& reg, uint8_t boundary) const
{
return (reg.m_iUpperX <= m_iUpperX - boundary)
&& (reg.m_iUpperY <= m_iUpperY - boundary)
&& (reg.m_iUpperZ <= m_iUpperZ - boundary)
&& (reg.m_iLowerX >= m_iLowerX + boundary)
&& (reg.m_iLowerY >= m_iLowerY + boundary)
&& (reg.m_iLowerZ >= m_iLowerZ + boundary);
}
/**
* After calling this functions, the extents of this Region are given by the intersection
* of this Region and the one it was cropped to.

View File

@ -40,7 +40,7 @@ bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos)
return false;
}
typename VolumeType::VoxelType voxel = volData->getVoxelAt(v3dPos);
typename VolumeType::VoxelType voxel = volData->getVoxel(v3dPos, WrapModes::Validate); // FIXME use templatised version of getVoxel(), but watch out for Linux compile issues.
if(voxel != 0)
{
return false;

View File

@ -64,27 +64,27 @@ void TestLowPassFilter::testExecute()
QBENCHMARK {
lowPassfilter.execute();
}
QCOMPARE(resultVolume.getVoxelAt(0,0,0), Density8(4));
QCOMPARE(resultVolume.getVoxelAt(1,1,1), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(2,2,2), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(3,3,3), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(4,4,4), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(5,5,5), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(6,6,6), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(7,7,7), Density8(4));
QCOMPARE(resultVolume.getVoxel(0,0,0), Density8(4));
QCOMPARE(resultVolume.getVoxel(1,1,1), Density8(21));
QCOMPARE(resultVolume.getVoxel(2,2,2), Density8(10));
QCOMPARE(resultVolume.getVoxel(3,3,3), Density8(21));
QCOMPARE(resultVolume.getVoxel(4,4,4), Density8(10));
QCOMPARE(resultVolume.getVoxel(5,5,5), Density8(21));
QCOMPARE(resultVolume.getVoxel(6,6,6), Density8(10));
QCOMPARE(resultVolume.getVoxel(7,7,7), Density8(4));
//Test the SAT implmentation
QBENCHMARK {
lowPassfilter.executeSAT();
}
QCOMPARE(resultVolume.getVoxelAt(0,0,0), Density8(4));
QCOMPARE(resultVolume.getVoxelAt(1,1,1), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(2,2,2), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(3,3,3), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(4,4,4), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(5,5,5), Density8(21));
QCOMPARE(resultVolume.getVoxelAt(6,6,6), Density8(10));
QCOMPARE(resultVolume.getVoxelAt(7,7,7), Density8(4));
QCOMPARE(resultVolume.getVoxel(0,0,0), Density8(4));
QCOMPARE(resultVolume.getVoxel(1,1,1), Density8(21));
QCOMPARE(resultVolume.getVoxel(2,2,2), Density8(10));
QCOMPARE(resultVolume.getVoxel(3,3,3), Density8(21));
QCOMPARE(resultVolume.getVoxel(4,4,4), Density8(10));
QCOMPARE(resultVolume.getVoxel(5,5,5), Density8(21));
QCOMPARE(resultVolume.getVoxel(6,6,6), Density8(10));
QCOMPARE(resultVolume.getVoxel(7,7,7), Density8(4));
}
QTEST_MAIN(TestLowPassFilter)

View File

@ -68,22 +68,77 @@ public:
/// Destructor
~VolumeSubclass() {};
/// 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 <tt>x,y,z</tt> coordinates
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
template <WrapMode eWrapMode>
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const
{
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
// FIXME: This templatised version is implemented in terms of the not template version. This is strange
// from a peformance point of view but it's just because we were encountering some compile issues on GCC.
return getVoxel(uXPos, uYPos, uZPos, eWrapMode, tBorder);
}
/// Gets a voxel at the position given by a 3D vector
template <WrapMode eWrapMode>
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const
{
// Simply call through to the real implementation
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
}
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const
{
switch(eWrapMode)
{
case WrapModes::Validate:
{
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 getBorderValue();
return tBorder;
}
}
case WrapModes::AssumeValid:
{
return mVolumeData[uXPos][uYPos][uZPos];
}
default:
{
// Should never happen
POLYVOX_ASSERT(false, "Invalid wrap mode");
return VoxelType();
}
}
}
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const { return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); }
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
}
/// Sets the value used for voxels which are outside the volume
void setBorderValue(const VoxelType& tBorder) { }

View File

@ -76,7 +76,7 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXO
}
else
{
result = cantorTupleFunction(result, volume->getVoxelWithWrapping(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
}
}
}
@ -189,7 +189,7 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowX
}
else
{
result = cantorTupleFunction(result, volume->getVoxelWithWrapping(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
}
}
}