Combining BoundsChecks and WrapMode into a single enum.

This commit is contained in:
Daviw Williams
2013-06-06 16:07:47 +02:00
parent 073c415a38
commit 2b03e84f83
5 changed files with 74 additions and 31 deletions

View File

@ -41,11 +41,15 @@ namespace PolyVox
enum BoundsCheck
{
None = 0,
Full = 1
Full = 1,
ClampPos = 2,
BorderPos = 3
};
}
typedef BoundsChecks::BoundsCheck BoundsCheck;
// Required for a trick to implement specialization of template member
// functions in template classes. See http://stackoverflow.com/a/4951057
template <BoundsCheck B> struct BoundsCheckType{};
namespace WrapModes

View File

@ -24,7 +24,7 @@ freely, subject to the following restrictions:
#ifndef __PolyVox_Config_H__
#define __PolyVox_Config_H__
#define POLYVOX_ASSERTS_ENABLED
//#define POLYVOX_ASSERTS_ENABLED
#define POLYVOX_THROW_ENABLED
#endif

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, BoundsChecks::BorderPos));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, BoundsChecks::BorderPos));
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, BoundsChecks::BorderPos));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, BoundsChecks::BorderPos));
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, BoundsChecks::BorderPos);
AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ, BoundsChecks::BorderPos);
AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ, BoundsChecks::BorderPos);
AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ, BoundsChecks::BorderPos);
AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ, BoundsChecks::BorderPos);
AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ, BoundsChecks::BorderPos);
AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ, BoundsChecks::BorderPos);
AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ, BoundsChecks::BorderPos);
AccumulationType sum = h+c-d-g-f-a+b+e;
uint32_t sideLength = border * 2 + 1;

View File

@ -117,12 +117,12 @@ namespace PolyVox
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
template <BoundsCheck eBoundsCheck>
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, 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, BoundsCheck eBoundsCheck = BoundsChecks::Full) const;
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck = BoundsChecks::Full, VoxelType tBorder = VoxelType()) const;
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck = BoundsChecks::Full) const;
VoxelType getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck = BoundsChecks::Full, 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;
/// Gets a voxel at the position given by a 3D vector
@ -155,9 +155,11 @@ namespace PolyVox
void initialise(const Region& regValidRegion);
template <BoundsCheck eBoundsCheck>
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType<eBoundsCheck>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType<BoundsChecks::Full>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType<BoundsChecks::None>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<eBoundsCheck>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::Full>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::None>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::ClampPos>) const;
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::BorderPos>) const;
//The block data
VoxelType* m_pData;

View File

@ -84,10 +84,10 @@ namespace PolyVox
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
template <BoundsCheck eBoundsCheck>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
{
// Simply call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType<eBoundsCheck>());
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<eBoundsCheck>());
}
////////////////////////////////////////////////////////////////////////////////
@ -100,19 +100,29 @@ namespace PolyVox
/// \return The voxel value
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck) const
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck, VoxelType tBorder) const
{
// If bounds checking is enabled then we validate the
// bounds, and throw an exception if they are violated.
if(eBoundsCheck == BoundsChecks::Full)
{
// Call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType<BoundsChecks::Full>());
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::Full>());
}
else if(eBoundsCheck == BoundsChecks::None)
{
// Call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::None>());
}
else if(eBoundsCheck == BoundsChecks::ClampPos)
{
// Call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::ClampPos>());
}
else
{
// Call through to the real implementation
return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType<BoundsChecks::None>());
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::BorderPos>());
}
}
@ -124,9 +134,9 @@ namespace PolyVox
/// is inside the volume's enclosing region then you can skip this check to gain some performance.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck) const
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, BoundsCheck eBoundsCheck, VoxelType tBorder) const
{
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eBoundsCheck);
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eBoundsCheck, tBorder);
}
////////////////////////////////////////////////////////////////////////////////
@ -357,24 +367,24 @@ namespace PolyVox
template <typename VoxelType>
template <BoundsCheck eBoundsCheck>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType<eBoundsCheck>) const
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<eBoundsCheck>) const
{
POLYVOX_THROW(not_implemented, "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, BoundsCheckType<BoundsChecks::Full>) const
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::Full>) 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, BoundsCheckType<BoundsChecks::None>());
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::None>());
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType<BoundsChecks::None>) const
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::None>) const
{
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
@ -388,5 +398,32 @@ namespace PolyVox
iLocalZPos * this->getWidth() * this->getHeight()
];
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::ClampPos>) const
{
//Perform clamping
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::None>());
}
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder, BoundsCheckType<BoundsChecks::BorderPos>) const
{
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
{
return getVoxelImpl(uXPos, uYPos, uZPos, tBorder, BoundsCheckType<BoundsChecks::None>()); // No bounds checks as we've just validated the position.
}
else
{
return tBorder; //FIXME - Should return border value.
}
}
}