Reverted some of ker's changes to bring back the concepts of width, height, and depth.
This commit is contained in:
@ -59,10 +59,48 @@ namespace PolyVox
|
||||
{
|
||||
setBlockCacheSize(m_uMaxUncompressedBlockCacheSize);
|
||||
|
||||
m_regValidRegion.setToMaxSize();
|
||||
|
||||
m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||
m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||
|
||||
//Create a volume of the right size.
|
||||
resize(uBlockSideLength);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Builds a volume of the desired dimensions
|
||||
/// \param uWidth The desired width in voxels. This must be a power of two.
|
||||
/// \param uHeight The desired height in voxels. This must be a power of two.
|
||||
/// \param uDepth The desired depth in voxels. This must be a power of two.
|
||||
/// \param uBlockSideLength The size of the blocks which make up the volume. Small
|
||||
/// blocks are more likely to be homogeneous (so more easily shared) and have better
|
||||
/// cache behaviour. However, there is a memory overhead per block so if they are
|
||||
/// not shared it could actually be less efficient (this will depend on the data).
|
||||
/// The size of the volume may also be a factor when choosing block size. Accept
|
||||
/// the default if you are not sure what to choose here.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
Volume<VoxelType>::Volume(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength)
|
||||
:m_uTimestamper(0)
|
||||
,m_uMaxUncompressedBlockCacheSize(256)
|
||||
,m_uBlockSideLength(uBlockSideLength)
|
||||
,m_pUncompressedBorderData(0)
|
||||
,m_uMaxBlocksLoaded(4096)
|
||||
,m_v3dLastAccessedBlockPos((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)()) //An invalid index
|
||||
{
|
||||
setBlockCacheSize(m_uMaxUncompressedBlockCacheSize);
|
||||
|
||||
m_regValidRegion.setLowerCorner(Vector3DInt32(0,0,0));
|
||||
m_regValidRegion.setUpperCorner(Vector3DInt32(uWidth - 1,uHeight - 1,uDepth - 1));
|
||||
|
||||
m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||
m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
|
||||
|
||||
//Create a volume of the right size.
|
||||
resize(uWidth, uHeight, uDepth, uBlockSideLength);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Destroys the volume and frees any blocks which are not in use by other volumes.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -75,6 +113,95 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType Volume<VoxelType>::getBorderValue(void) const
|
||||
{
|
||||
/*Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(const_cast<Block<VoxelType>*>(&m_pBorderBlock));
|
||||
return pUncompressedBorderBlock->getVoxelAt(0,0,0);*/
|
||||
return *m_pUncompressedBorderData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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
|
||||
/// then the upper corner of the enclosing region will be at (255,511,1023).
|
||||
/// \return A Region representing the extent of the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
Region Volume<VoxelType>::getEnclosingRegion(void) const
|
||||
{
|
||||
return Region(Vector3DInt32(0,0,0), Vector3DInt32(m_uWidth-1,m_uHeight-1,m_uDepth-1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The width of the volume in voxels
|
||||
/// \sa getHeight(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t Volume<VoxelType>::getWidth(void) const
|
||||
{
|
||||
return m_uWidth;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The height of the volume in voxels
|
||||
/// \sa getWidth(), getDepth()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t Volume<VoxelType>::getHeight(void) const
|
||||
{
|
||||
return m_uHeight;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The depth of the volume in voxels
|
||||
/// \sa getWidth(), getHeight()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t Volume<VoxelType>::getDepth(void) const
|
||||
{
|
||||
return m_uDepth;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the shortest side in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return 256.
|
||||
/// \sa getLongestSideLength(), getDiagonalLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t Volume<VoxelType>::getShortestSideLength(void) const
|
||||
{
|
||||
return m_uShortestSideLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the longest side in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return 1024.
|
||||
/// \sa getShortestSideLength(), getDiagonalLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
int32_t Volume<VoxelType>::getLongestSideLength(void) const
|
||||
{
|
||||
return m_uLongestSideLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The length of the diagonal in voxels. For example, if a volume has
|
||||
/// dimensions 256x512x1024 this function will return sqrt(256*256+512*512+1024*1024)
|
||||
/// = 1173.139. This value is computed on volume creation so retrieving it is fast.
|
||||
/// \sa getShortestSideLength(), getLongestSideLength()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
float Volume<VoxelType>::getDiagonalLength(void) const
|
||||
{
|
||||
return m_fDiagonalLength;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
@ -145,6 +272,17 @@ namespace PolyVox
|
||||
m_uMaxBlocksLoaded = uMaxBlocks;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param tBorder The value to use for voxels outside the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void Volume<VoxelType>::setBorderValue(const VoxelType& tBorder)
|
||||
{
|
||||
/*Block<VoxelType>* pUncompressedBorderBlock = getUncompressedBlock(&m_pBorderBlock);
|
||||
return pUncompressedBorderBlock->fill(tBorder);*/
|
||||
std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
@ -230,6 +368,99 @@ namespace PolyVox
|
||||
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Note: Calling this function will destroy all existing data in the volume.
|
||||
/// \param uWidth The desired width in voxels. This must be a power of two.
|
||||
/// \param uHeight The desired height in voxels. This must be a power of two.
|
||||
/// \param uDepth The desired depth in voxels. This must be a power of two.
|
||||
/// \param uBlockSideLength The size of the blocks which make up the volume. Small
|
||||
/// blocks are more likely to be homogeneous (so more easily shared) and have better
|
||||
/// cache behaviour. However, there is a memory overhead per block so if they are
|
||||
/// not shared it could actually be less efficient (this will depend on the data).
|
||||
/// The size of the volume may also be a factor when choosing block size. Accept
|
||||
/// the default if you are not sure what to choose here.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void Volume<VoxelType>::resize(int32_t uWidth, int32_t uHeight, int32_t uDepth, uint16_t uBlockSideLength)
|
||||
{
|
||||
//Debug mode validation
|
||||
assert(uBlockSideLength > 0);
|
||||
assert(isPowerOf2(uBlockSideLength));
|
||||
assert(uBlockSideLength <= uWidth);
|
||||
assert(uBlockSideLength <= uHeight);
|
||||
assert(uBlockSideLength <= uDepth);
|
||||
assert(0 < uWidth);
|
||||
assert(0 < uHeight);
|
||||
assert(0 < uDepth);
|
||||
|
||||
//Release mode validation
|
||||
if(uBlockSideLength == 0)
|
||||
{
|
||||
throw std::invalid_argument("Block side length cannot be zero.");
|
||||
}
|
||||
if(!isPowerOf2(uBlockSideLength))
|
||||
{
|
||||
throw std::invalid_argument("Block side length must be a power of two.");
|
||||
}
|
||||
if(uBlockSideLength > uWidth)
|
||||
{
|
||||
throw std::invalid_argument("Block side length cannot be greater than volume width.");
|
||||
}
|
||||
if(uBlockSideLength > uHeight)
|
||||
{
|
||||
throw std::invalid_argument("Block side length cannot be greater than volume height.");
|
||||
}
|
||||
if(uBlockSideLength > uDepth)
|
||||
{
|
||||
throw std::invalid_argument("Block side length cannot be greater than volume depth.");
|
||||
}
|
||||
if(0 >= uWidth)
|
||||
{
|
||||
throw std::invalid_argument("Volume width cannot be smaller than 1.");
|
||||
}
|
||||
if(0 >= uHeight)
|
||||
{
|
||||
throw std::invalid_argument("Volume height cannot be smaller than 1.");
|
||||
}
|
||||
if(0 >= uDepth)
|
||||
{
|
||||
throw std::invalid_argument("Volume depth cannot be smaller than 1.");
|
||||
}
|
||||
|
||||
//Clear the previous data
|
||||
m_pBlocks.clear();
|
||||
m_pUncompressedTimestamps.clear();
|
||||
|
||||
//Compute the volume side lengths
|
||||
m_uWidth = uWidth;
|
||||
m_uHeight = uHeight;
|
||||
m_uDepth = uDepth;
|
||||
|
||||
//Compute the block side length
|
||||
m_uBlockSideLength = uBlockSideLength;
|
||||
m_uBlockSideLengthPower = logBase2(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;
|
||||
|
||||
//Clear the previous data
|
||||
m_pBlocks.clear();
|
||||
m_pUncompressedTimestamps.clear();
|
||||
|
||||
m_pUncompressedTimestamps.resize(m_uMaxUncompressedBlockCacheSize, 0);
|
||||
|
||||
//Create the border block
|
||||
m_pUncompressedBorderData = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength];
|
||||
std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength, VoxelType());
|
||||
|
||||
//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);
|
||||
m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Volume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itBlock) const
|
||||
{
|
||||
|
Reference in New Issue
Block a user