Improved support for borders in Volumes and VolumeSamplers.

More fixes for edge case handling in marching cubes.
This commit is contained in:
David Williams
2010-08-26 20:48:51 +00:00
parent a39cb23dc3
commit cc22b682fa
4 changed files with 61 additions and 57 deletions

View File

@ -66,19 +66,12 @@ namespace PolyVox
}
//Debug mode validation
assert(isPowerOf2(uWidth));
assert(isPowerOf2(uHeight));
assert(isPowerOf2(uDepth));
assert(isPowerOf2(uBlockSideLength));
assert(uBlockSideLength <= uWidth);
assert(uBlockSideLength <= uHeight);
assert(uBlockSideLength <= uDepth);
//Release mode validation
if(!(isPowerOf2(uWidth) && isPowerOf2(uHeight) && isPowerOf2(uDepth)))
{
throw std::invalid_argument("Volume width, height, and depth must all be a power of two.");
}
if(!isPowerOf2(uBlockSideLength))
{
throw std::invalid_argument("Block side length must be a power of two.");
@ -98,20 +91,19 @@ namespace PolyVox
//Compute the volume side lengths
m_uWidth = uWidth;
m_uWidthPower = logBase2(m_uWidth);
//m_uWidthPower = logBase2(m_uWidth);
m_uHeight = uHeight;
m_uHeightPower = logBase2(m_uHeight);
//m_uHeightPower = logBase2(m_uHeight);
m_uDepth = uDepth;
m_uDepthPower = logBase2(m_uDepth);
//m_uDepthPower = logBase2(m_uDepth);
//Compute the block side length
m_uBlockSideLength = uBlockSideLength;
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
//Compute the side length in blocks
//m_uSideLengthInBlocks = m_uSideLength / m_uBlockSideLength;
//Compute the side lengths in blocks
m_uWidthInBlocks = m_uWidth / m_uBlockSideLength;
m_uHeightInBlocks = m_uHeight / m_uBlockSideLength;
m_uDepthInBlocks = m_uDepth / m_uBlockSideLength;
@ -128,6 +120,11 @@ namespace PolyVox
m_vecBlockIsPotentiallyHomogenous[i] = false;
}
//Create the border block
std::shared_ptr< Block<VoxelType> > pTempBlock(new Block<VoxelType>(m_uBlockSideLength));
pTempBlock->fill(VoxelType());
m_pBorderBlock = pTempBlock;
//Other properties we might find useful later
m_uLongestSideLength = (std::max)((std::max)(m_uWidth,m_uHeight),m_uDepth);
m_uShortestSideLength = (std::min)((std::min)(m_uWidth,m_uHeight),m_uDepth);
@ -147,6 +144,18 @@ namespace PolyVox
#pragma endregion
#pragma region Getters
template <typename VoxelType>
////////////////////////////////////////////////////////////////////////////////
/// The border value is returned whenever an atempt is made to read a voxel which
/// is outside the extents of the volume.
/// \return The value used for voxels outside of the volume
////////////////////////////////////////////////////////////////////////////////
VoxelType Volume<VoxelType>::getBorderValue(void) const
{
return m_pBorderBlock->getVoxelAt(0,0,0);
}
////////////////////////////////////////////////////////////////////////////////
/// The result will always have a lower corner at (0,0,0) and an upper corner at one
/// less than the side length. For example, if a volume has dimensions 256x512x1024
@ -231,7 +240,7 @@ namespace PolyVox
/// \return the voxel value
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType Volume<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tDefault) const
VoxelType Volume<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
{
//We don't use getEnclosingRegion here because we care
//about speed and don't need to check the lower bound.
@ -256,7 +265,7 @@ namespace PolyVox
}
else
{
return tDefault;
return getBorderValue();
}
}
@ -273,6 +282,15 @@ namespace PolyVox
#pragma endregion
#pragma region Setters
////////////////////////////////////////////////////////////////////////////////
/// \param tBorder The value to use for voxels outside the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void Volume<VoxelType>::setBorderValue(const VoxelType& tBorder)
{
return m_pBorderBlock->fill(tBorder);
}
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel