From d191902db3a5044625a778949f9a70b410ad61fd Mon Sep 17 00:00:00 2001 From: David Williams Date: Tue, 24 Mar 2009 20:45:23 +0000 Subject: [PATCH] Work on Block class. --- TODO.txt | 11 ++++++- library/include/PolyVoxCore/Block.h | 4 ++- library/include/PolyVoxCore/Block.inl | 31 ++++++++++++++----- library/include/PolyVoxCore/Constants.h | 13 -------- library/include/PolyVoxCore/Volume.inl | 4 +-- library/source/PolyVoxCore/Utility.cpp | 12 +++++++ .../PolyVoxUtil/VolumeChangeTracker.cpp | 2 +- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/TODO.txt b/TODO.txt index 72c80888..8ef149f8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -29,4 +29,13 @@ Generate ambient lighting from volume? Utility function for closing outside surfaces? Consider how seperate surface should be generated for a single region. Consider transparent materials like glass. -Allow writing meshes into volumes? \ No newline at end of file +Allow writing meshes into volumes? + +Documentation +============= +Define the following terms: +-Voxel +-Cell +-Volume +-Region +-Block \ No newline at end of file diff --git a/library/include/PolyVoxCore/Block.h b/library/include/PolyVoxCore/Block.h index a4f3fa9e..737f5011 100644 --- a/library/include/PolyVoxCore/Block.h +++ b/library/include/PolyVoxCore/Block.h @@ -36,7 +36,7 @@ namespace PolyVox //Make VolumeIterator a friend friend class VolumeIterator; public: - Block(uint8 uSideLengthPower); + Block(uint8 uSideLength); Block(const Block& rhs); ~Block(); @@ -44,8 +44,10 @@ namespace PolyVox uint16 getSideLength(void) const; VoxelType getVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos) const; + VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; void setVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos, VoxelType tValue); + void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); void fill(VoxelType tValue); diff --git a/library/include/PolyVoxCore/Block.inl b/library/include/PolyVoxCore/Block.inl index 2b0f81d7..a829490e 100644 --- a/library/include/PolyVoxCore/Block.inl +++ b/library/include/PolyVoxCore/Block.inl @@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma endregion #pragma region Headers +#include "Utility.h" + #include #include //For memcpy #include //for std::invalid_argument @@ -29,18 +31,21 @@ namespace PolyVox { #pragma region Constructors/Destructors template - Block::Block(uint8 uSideLengthPower) + Block::Block(uint8 uSideLength) :m_tData(0) { - //Check the block size is sensible. This corresponds to a side length of 256 voxels - if(uSideLengthPower > 8) + //Debug mode error handling + assert(isPowerOf2(uSideLength)); + + //Release mode error handling + if(!isPowerOf2(uSideLength)) { - throw std::invalid_argument("Block side length power must be less than or equal to eight"); + throw std::invalid_argument("Block side length must be a power of two."); } - //Compute the side length - m_uSideLengthPower = uSideLengthPower; - m_uSideLength = 0x01 << uSideLengthPower; + //Compute the side length + m_uSideLength = uSideLength; + m_uSideLengthPower = logBase2(uSideLength); //If this fails an exception will be thrown. Memory is not //allocated and there is nothing else in this class to clean up @@ -95,6 +100,12 @@ namespace PolyVox uZPos * m_uSideLength * m_uSideLength ]; } + + template + VoxelType Block::getVoxelAt(const Vector3DUint16& v3dPos) const + { + return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); + } #pragma endregion #pragma region Setters @@ -112,6 +123,12 @@ namespace PolyVox uZPos * m_uSideLength * m_uSideLength ] = tValue; } + + template + void Block::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) + { + setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); + } #pragma endregion #pragma region Other diff --git a/library/include/PolyVoxCore/Constants.h b/library/include/PolyVoxCore/Constants.h index 3edeea58..db64817e 100644 --- a/library/include/PolyVoxCore/Constants.h +++ b/library/include/PolyVoxCore/Constants.h @@ -26,20 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. namespace PolyVox { - //FIXME - i think we can define mod using a bitmask which flattens the upper bits. Should define that here. - //const uint32 POLYVOX_BLOCK_SIDE_LENGTH_POWER = 5; - //const uint32 POLYVOX_BLOCK_SIDE_LENGTH = (0x0001 << POLYVOX_BLOCK_SIDE_LENGTH_POWER); - //const uint32 POLYVOX_NO_OF_VOXELS_IN_BLOCK = (POLYVOX_BLOCK_SIDE_LENGTH * POLYVOX_BLOCK_SIDE_LENGTH * POLYVOX_BLOCK_SIDE_LENGTH); - const uint16 POLYVOX_VOLUME_SIDE_LENGTH_POWER = 8; - const uint16 POLYVOX_VOLUME_SIDE_LENGTH = (0x0001 << POLYVOX_VOLUME_SIDE_LENGTH_POWER); - //const uint32 POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS = (POLYVOX_VOLUME_SIDE_LENGTH >> POLYVOX_BLOCK_SIDE_LENGTH_POWER); - //const uint32 POLYVOX_NO_OF_BLOCKS_IN_VOLUME = (POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS); - //const uint32 POLYVOX_NO_OF_VOXELS_IN_VOLUME = (POLYVOX_VOLUME_SIDE_LENGTH * POLYVOX_VOLUME_SIDE_LENGTH * POLYVOX_VOLUME_SIDE_LENGTH); - - const uint16 POLYVOX_REGION_SIDE_LENGTH_POWER = 5; - const uint16 POLYVOX_REGION_SIDE_LENGTH = (0x0001 << POLYVOX_REGION_SIDE_LENGTH_POWER); - const uint16 POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS = (POLYVOX_VOLUME_SIDE_LENGTH >> POLYVOX_REGION_SIDE_LENGTH_POWER); } #endif diff --git a/library/include/PolyVoxCore/Volume.inl b/library/include/PolyVoxCore/Volume.inl index b51360eb..b4fadd0e 100644 --- a/library/include/PolyVoxCore/Volume.inl +++ b/library/include/PolyVoxCore/Volume.inl @@ -192,7 +192,7 @@ namespace PolyVox { if(tHomogenousValue != tValue) { - m_pBlocks[uBlockIndex] = new Block(m_uBlockSideLengthPower); + m_pBlocks[uBlockIndex] = new Block(m_uBlockSideLength); m_pIsShared[uBlockIndex] = false; m_pBlocks[uBlockIndex]->fill(tHomogenousValue); m_pBlocks[uBlockIndex]->setVoxelAt(xOffset,yOffset,zOffset, tValue); @@ -287,7 +287,7 @@ namespace PolyVox typename std::map*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue); if(iterResult == m_pHomogenousBlocks.end()) { - Block* pBlock = new Block(m_uBlockSideLengthPower); + Block* pBlock = new Block(m_uBlockSideLength); pBlock->fill(tHomogenousValue); m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock)); return pBlock; diff --git a/library/source/PolyVoxCore/Utility.cpp b/library/source/PolyVoxCore/Utility.cpp index 4fc738f4..70901937 100644 --- a/library/source/PolyVoxCore/Utility.cpp +++ b/library/source/PolyVoxCore/Utility.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "PolyVoxCore/Utility.h" #include +#include namespace PolyVox { @@ -29,9 +30,20 @@ namespace PolyVox //If this is not the case then the output is undefined. uint8 logBase2(uint32 uInput) { + //Debug mode error handling assert(uInput != 0); assert(isPowerOf2(uInput)); + //Release mode error handling + if(uInput == 0) + { + throw std::invalid_argument("Cannot compute the log of zero."); + } + if(!isPowerOf2(uInput)) + { + throw std::invalid_argument("Input must be a power of two in order to compute the log."); + } + uint32 uResult = 0; while( (uInput >> uResult) != 0) { diff --git a/library/source/PolyVoxUtil/VolumeChangeTracker.cpp b/library/source/PolyVoxUtil/VolumeChangeTracker.cpp index c1fea670..5f7b7024 100644 --- a/library/source/PolyVoxUtil/VolumeChangeTracker.cpp +++ b/library/source/PolyVoxUtil/VolumeChangeTracker.cpp @@ -49,7 +49,7 @@ namespace PolyVox m_uVolumeSideLengthInRegions = volumeData->getSideLength() / m_uRegionSideLength; m_uRegionSideLengthPower = PolyVox::logBase2(m_uRegionSideLength); - volRegionLastModified = new Block(m_uRegionSideLengthPower); + volRegionLastModified = new Block(m_uRegionSideLength); } VolumeChangeTracker::~VolumeChangeTracker()