diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 3e394efc..bfc0a73e 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -44,7 +44,6 @@ SET(CORE_INC_FILES include/PolyVoxCore/PolyVoxForwardDeclarations.h include/PolyVoxCore/RawVolume.h include/PolyVoxCore/RawVolume.inl - include/PolyVoxCore/RawVolumeBlock.inl include/PolyVoxCore/RawVolumeSampler.inl include/PolyVoxCore/Raycast.h include/PolyVoxCore/Raycast.inl diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index 03757138..88e04f6b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -37,30 +37,6 @@ namespace PolyVox { public: #ifndef SWIG - class Block - { - //Make Sampler a friend - friend class RawVolume::Sampler; - public: - 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; - - void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue); - void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); - - void fill(VoxelType tValue); - void initialise(uint16_t uSideLength); - uint32_t calculateSizeInBytes(void); - - public: - VoxelType* m_tUncompressedData; - uint16_t m_uSideLength; - uint8_t m_uSideLengthPower; - }; - class Sampler { public: @@ -117,7 +93,6 @@ namespace PolyVox inline VoxelType peekVoxel1px1py1pz(void) const; private: - //The current volume RawVolume* mVolume; @@ -175,30 +150,14 @@ namespace PolyVox void resize(const Region& regValidRegion); private: - //Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; - //The block data - Block* m_pOnlyBlock; + VoxelType* m_pData; - //We don't store an actual Block for the border, just the uncompressed data. This is partly because the border - //block does not have a position (so can't be passed to getUncompressedBlock()) and partly because there's a - //good chance we'll often hit it anyway. It's a chunk of homogenous data (rather than a single value) so that - //the VolumeIterator can do it's usual pointer arithmetic without needing to know it's gone outside the volume. - VoxelType m_pUncompressedBorderData; + //The border value + VoxelType m_tBorderValue; //The size of the volume Region m_regValidRegion; - //Region m_regValidRegionInBlocks; - - //Volume size measured in blocks. - //uint32_t m_uNoOfBlocksInVolume; - //uint16_t m_uWidthInBlocks; - //uint16_t m_uHeightInBlocks; - //uint16_t m_uDepthInBlocks; - - //The size of the blocks - //uint16_t m_uBlockSideLength; - //uint8_t m_uBlockSideLengthPower; //Some useful sizes int32_t m_uLongestSideLength; @@ -207,7 +166,6 @@ private: }; } -#include "PolyVoxCore/RawVolumeBlock.inl" #include "PolyVoxCore/RawVolume.inl" #include "PolyVoxCore/RawVolumeSampler.inl" diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl index d9387f12..e174d9bc 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl @@ -58,8 +58,8 @@ namespace PolyVox template RawVolume::~RawVolume() { - delete[] m_pOnlyBlock; - m_pOnlyBlock = 0; + delete[] m_pData; + m_pData = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -70,7 +70,7 @@ namespace PolyVox template VoxelType RawVolume::getBorderValue(void) const { - return m_pUncompressedBorderData; + return m_tBorderValue; } //////////////////////////////////////////////////////////////////////////////// @@ -157,7 +157,12 @@ namespace PolyVox { if(m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))) { - return m_pOnlyBlock->getVoxelAt(uXPos, uYPos, uZPos); + return m_pData + [ + uXPos + + uYPos * getWidth() + + uZPos * getWidth() * getHeight() + ]; } else { @@ -181,10 +186,7 @@ namespace PolyVox template void RawVolume::setBorderValue(const VoxelType& tBorder) { - /*Block* pUncompressedBorderBlock = getUncompressedBlock(&m_pBorderBlock); - return pUncompressedBorderBlock->fill(tBorder);*/ - //std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength, tBorder); - m_pUncompressedBorderData = tBorder; + m_tBorderValue = tBorder; } //////////////////////////////////////////////////////////////////////////////// @@ -199,7 +201,12 @@ namespace PolyVox { assert(m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))); - m_pOnlyBlock->setVoxelAt(uXPos, uYPos, uZPos, tValue); + m_pData + [ + uXPos + + uYPos * getWidth() + + uZPos * getWidth() * getHeight() + ] = tValue; //Return true to indicate that we modified a voxel. return true; @@ -222,50 +229,15 @@ namespace PolyVox template void RawVolume::resize(const Region& regValidRegion) { - //Debug mode validation - /*assert(uBlockSideLength > 0); - - //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."); - }*/ - - //m_uBlockSideLength = uBlockSideLength; - //m_pUncompressedBorderData = 0; - m_regValidRegion = regValidRegion; - //m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast(uBlockSideLength)); - //m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast(uBlockSideLength)); + //Ensure dimensions of the specified Region are valid + assert(getWidth() > 0); + assert(getHeight() > 0); + assert(getDepth() > 0); - //Compute the block side length - //m_uBlockSideLength = uBlockSideLength; - //m_uBlockSideLengthPower = logBase2(m_uBlockSideLength); - - //Compute the size of the volume in blocks (and note +1 at the end) - //m_uWidthInBlocks = m_regValidRegionInBlocks.getUpperCorner().getX() - m_regValidRegionInBlocks.getLowerCorner().getX() + 1; - //m_uHeightInBlocks = m_regValidRegionInBlocks.getUpperCorner().getY() - m_regValidRegionInBlocks.getLowerCorner().getY() + 1; - //m_uDepthInBlocks = m_regValidRegionInBlocks.getUpperCorner().getZ() - m_regValidRegionInBlocks.getLowerCorner().getZ() + 1; - //m_uNoOfBlocksInVolume = m_uWidthInBlocks * m_uHeightInBlocks * m_uDepthInBlocks; - - //Allocate the data - /*m_pBlocks = new Block[m_uNoOfBlocksInVolume]; - for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) - { - m_pBlocks[i].initialise(m_uBlockSideLength); - }*/ - - m_pOnlyBlock = new Block; - m_pOnlyBlock->initialise(getWidth()); - - //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()); + //Create the data + m_pData = new VoxelType[getWidth() * getHeight()* getDepth()]; //Other properties we might find useful later m_uLongestSideLength = (std::max)((std::max)(getWidth(),getHeight()),getDepth()); @@ -273,40 +245,13 @@ namespace PolyVox m_fDiagonalLength = sqrtf(static_cast(getWidth() * getWidth() + getHeight() * getHeight() + getDepth() * getDepth())); } - /*template - typename RawVolume::Block* RawVolume::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const - { - //The lower left corner of the volume could be - //anywhere, but array indices need to start at zero. - uBlockX -= m_regValidRegionInBlocks.getLowerCorner().getX(); - uBlockY -= m_regValidRegionInBlocks.getLowerCorner().getY(); - uBlockZ -= m_regValidRegionInBlocks.getLowerCorner().getZ(); - - //Compute the block index - uint32_t uBlockIndex = - uBlockX + - uBlockY * m_uWidthInBlocks + - uBlockZ * m_uWidthInBlocks * m_uHeightInBlocks; - - //Return the block - return &(m_pBlocks[uBlockIndex]); - }*/ - //////////////////////////////////////////////////////////////////////////////// /// Note: This function needs reviewing for accuracy... //////////////////////////////////////////////////////////////////////////////// template uint32_t RawVolume::calculateSizeInBytes(void) { - /*uint32_t uSizeInBytes = sizeof(RawVolume); - - uint32_t uSizeOfBlockInBytes = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); - - //Memory used by the blocks ( + 1 is for border) - uSizeInBytes += uSizeOfBlockInBytes * (m_uNoOfBlocksInVolume + 1); - - return uSizeInBytes;*/ - return 42; + return getWidth() * getHeight() * getDepth() * sizeof(VoxelType); } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeBlock.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeBlock.inl deleted file mode 100644 index 4600c783..00000000 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeBlock.inl +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* -Copyright (c) 2005-2009 David Williams - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*******************************************************************************/ - -#include "PolyVoxImpl/Utility.h" -#include "Vector.h" - -#include -#include //For memcpy -#include -#include //for std::invalid_argument - -namespace PolyVox -{ - template - RawVolume::Block::Block(uint16_t uSideLength) - :m_uSideLength(0) - ,m_uSideLengthPower(0) - ,m_tUncompressedData(0) - { - if(uSideLength != 0) - { - initialise(uSideLength); - } - } - - template - uint16_t RawVolume::Block::getSideLength(void) const - { - return m_uSideLength; - } - - template - VoxelType RawVolume::Block::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const - { - assert(uXPos < m_uSideLength); - assert(uYPos < m_uSideLength); - assert(uZPos < m_uSideLength); - - assert(m_tUncompressedData); - - return m_tUncompressedData - [ - uXPos + - uYPos * m_uSideLength + - uZPos * m_uSideLength * m_uSideLength - ]; - } - - template - VoxelType RawVolume::Block::getVoxelAt(const Vector3DUint16& v3dPos) const - { - return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); - } - - template - void RawVolume::Block::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue) - { - assert(uXPos < m_uSideLength); - assert(uYPos < m_uSideLength); - assert(uZPos < m_uSideLength); - - assert(m_tUncompressedData); - - m_tUncompressedData - [ - uXPos + - uYPos * m_uSideLength + - uZPos * m_uSideLength * m_uSideLength - ] = tValue; - } - - template - void RawVolume::Block::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) - { - setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); - } - - template - void RawVolume::Block::fill(VoxelType tValue) - { - const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; - std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue); - } - - template - void RawVolume::Block::initialise(uint16_t uSideLength) - { - //Debug mode validation - assert(isPowerOf2(uSideLength)); - - //Release mode validation - if(!isPowerOf2(uSideLength)) - { - throw std::invalid_argument("Block side length must be a power of two."); - } - - //Compute the side length - m_uSideLength = uSideLength; - m_uSideLengthPower = logBase2(uSideLength); - - m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; - - RawVolume::Block::fill(VoxelType()); - } - - template - uint32_t RawVolume::Block::calculateSizeInBytes(void) - { - uint32_t uSizeInBytes = sizeof(Block); - uSizeInBytes += sizeof(VoxelType) * m_uSideLength * m_uSideLength * m_uSideLength; - return uSizeInBytes; - } -} diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl index 38994fae..6542a5bb 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl @@ -104,13 +104,11 @@ namespace PolyVox if(mVolume->m_regValidRegionInBlocks.containsPoint(Vector3DInt32(uXBlock, uYBlock, uZBlock))) { - //Block* pUncompressedCurrentBlock = mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock); - - mCurrentVoxel = mVolume->m_pOnlyBlock + uVoxelIndex; + mCurrentVoxel = mVolume->m_pData + uVoxelIndex; } else { - mCurrentVoxel = mVolume->m_pUncompressedBorderData; + mCurrentVoxel = mVolume->m_tBorderValue; } } @@ -119,16 +117,14 @@ namespace PolyVox { mXPosInVolume++; - //Note the *post* decreament here if(mXPosInVolume <= mVolume->getEnclosingRegion().getUpperCorner().getX()) { - //No need to compute new block. ++mCurrentVoxel; } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } } @@ -137,16 +133,14 @@ namespace PolyVox { mYPosInVolume++; - //Note the *post* decreament here if(mYPosInVolume <= mVolume->getEnclosingRegion().getUpperCorner().getY()) { - //No need to compute new block. mCurrentVoxel += mVolume->getWidth(); } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } } @@ -157,14 +151,12 @@ namespace PolyVox if(mZPosInVolume <= mVolume->getEnclosingRegion().getUpperCorner().getZ()) { - //No need to compute new block. mCurrentVoxel += mVolume->getWidth() * mVolume->getHeight(); } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - //setPosition(mXPosInVolume, mYPosInVolume, mZPosInVolume); - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } } @@ -173,16 +165,14 @@ namespace PolyVox { mXPosInVolume--; - //Note the *post* decreament here if(mXPosInVolume >= mVolume->getEnclosingRegion().getLowerCorner().getX()) { - //No need to compute new block. --mCurrentVoxel; } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } } @@ -191,16 +181,14 @@ namespace PolyVox { mYPosInVolume--; - //Note the *post* decreament here if(mYPosInVolume >= mVolume->getEnclosingRegion().getLowerCorner().getY()) { - //No need to compute new block. mCurrentVoxel -= mVolume->getWidth(); } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } } @@ -211,14 +199,12 @@ namespace PolyVox if(mZPosInVolume >= mVolume->getEnclosingRegion().getLowerCorner().getZ()) { - //No need to compute new block. mCurrentVoxel -= mVolume->getWidth() * mVolume->getHeight(); } else { - //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this. - //setPosition(mXPosInVolume, mYPosInVolume, mZPosInVolume); - mCurrentVoxel = &mVolume->m_pUncompressedBorderData; + //We've hit the volume boundary. + mCurrentVoxel = &mVolume->m_tBorderValue; } }