From fab64488ee70b752c03e3ce032fe06cfebdedad6 Mon Sep 17 00:00:00 2001 From: David Williams Date: Thu, 26 Mar 2009 21:17:37 +0000 Subject: [PATCH] Renamed Block to BlockData. Introduced new Block class which can be shared. --- library/CMakeLists.txt | 4 +- .../PolyVoxCore/{Block.h => BlockData.h} | 18 +-- .../PolyVoxCore/{Block.inl => BlockData.inl} | 26 +++-- .../PolyVoxCore/PolyVoxForwardDeclarations.h | 2 +- library/include/PolyVoxCore/Volume.h | 25 +++-- library/include/PolyVoxCore/Volume.inl | 106 +++++++----------- .../include/PolyVoxCore/VolumeIterator.inl | 10 +- .../include/PolyVoxUtil/VolumeChangeTracker.h | 2 +- .../source/PolyVoxCore/GradientEstimators.cpp | 4 +- .../source/PolyVoxCore/SurfaceAdjusters.cpp | 8 +- .../PolyVoxUtil/VolumeChangeTracker.cpp | 2 +- 11 files changed, 95 insertions(+), 112 deletions(-) rename library/include/PolyVoxCore/{Block.h => BlockData.h} (83%) rename library/include/PolyVoxCore/{Block.inl => BlockData.inl} (75%) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 61fb3eee..b3964ab6 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -17,8 +17,8 @@ SET(CORE_SRC_FILES #Projects headers files SET(CORE_INC_FILES - include/PolyVoxCore/Block.h - include/PolyVoxCore/Block.inl + include/PolyVoxCore/BlockData.h + include/PolyVoxCore/BlockData.inl include/PolyVoxCore/Constants.h include/PolyVoxCore/Enums.h include/PolyVoxCore/GradientEstimators.h diff --git a/library/include/PolyVoxCore/Block.h b/library/include/PolyVoxCore/BlockData.h similarity index 83% rename from library/include/PolyVoxCore/Block.h rename to library/include/PolyVoxCore/BlockData.h index 737f5011..040f7493 100644 --- a/library/include/PolyVoxCore/Block.h +++ b/library/include/PolyVoxCore/BlockData.h @@ -19,8 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ******************************************************************************/ #pragma endregion -#ifndef __PolyVox_Block_H__ -#define __PolyVox_Block_H__ +#ifndef __PolyVox_BlockData_H__ +#define __PolyVox_BlockData_H__ #pragma region Headers #include "PolyVoxForwardDeclarations.h" @@ -31,16 +31,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. namespace PolyVox { template - class Block + class BlockData { //Make VolumeIterator a friend friend class VolumeIterator; public: - Block(uint8 uSideLength); - Block(const Block& rhs); - ~Block(); + BlockData(uint8 uSideLength); + BlockData(const BlockData& rhs); + ~BlockData(); - Block& operator=(const Block& rhs); + BlockData& operator=(const BlockData& rhs); uint16 getSideLength(void) const; VoxelType getVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos) const; @@ -52,12 +52,12 @@ namespace PolyVox void fill(VoxelType tValue); private: - uint8 m_uSideLengthPower; uint16 m_uSideLength; + uint8 m_uSideLengthPower; VoxelType* m_tData; }; } -#include "Block.inl" +#include "BlockData.inl" #endif diff --git a/library/include/PolyVoxCore/Block.inl b/library/include/PolyVoxCore/BlockData.inl similarity index 75% rename from library/include/PolyVoxCore/Block.inl rename to library/include/PolyVoxCore/BlockData.inl index 5582a544..218580d2 100644 --- a/library/include/PolyVoxCore/Block.inl +++ b/library/include/PolyVoxCore/BlockData.inl @@ -31,7 +31,7 @@ namespace PolyVox { #pragma region Constructors/Destructors template - Block::Block(uint8 uSideLength) + BlockData::BlockData(uint8 uSideLength) :m_tData(0) { //Debug mode validation @@ -40,7 +40,7 @@ namespace PolyVox //Release mode validation if(!isPowerOf2(uSideLength)) { - throw std::invalid_argument("Block side length must be a power of two."); + throw std::invalid_argument("BlockData side length must be a power of two."); } //Compute the side length @@ -53,13 +53,13 @@ namespace PolyVox } template - Block::Block(const Block& rhs) + BlockData::BlockData(const BlockData& rhs) { *this = rhs; } template - Block::~Block() + BlockData::~BlockData() { delete[] m_tData; m_tData = 0; @@ -68,26 +68,30 @@ namespace PolyVox #pragma region Operators template - Block& Block::operator=(const Block& rhs) + BlockData& BlockData::operator=(const BlockData& rhs) { if (this == &rhs) { return *this; } + + m_uSideLength = rhs.m_uSideLength; + m_uSideLengthPower = rhs.m_uSideLengthPower; memcpy(m_tData, rhs.m_tData, m_uSideLength * m_uSideLength * m_uSideLength); + return *this; } #pragma endregion #pragma region Getters template - uint16 Block::getSideLength(void) const + uint16 BlockData::getSideLength(void) const { return m_uSideLength; } template - VoxelType Block::getVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos) const + VoxelType BlockData::getVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos) const { assert(uXPos < m_uSideLength); assert(uYPos < m_uSideLength); @@ -102,7 +106,7 @@ namespace PolyVox } template - VoxelType Block::getVoxelAt(const Vector3DUint16& v3dPos) const + VoxelType BlockData::getVoxelAt(const Vector3DUint16& v3dPos) const { return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); } @@ -110,7 +114,7 @@ namespace PolyVox #pragma region Setters template - void Block::setVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos, VoxelType tValue) + void BlockData::setVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos, VoxelType tValue) { assert(uXPos < m_uSideLength); assert(uYPos < m_uSideLength); @@ -125,7 +129,7 @@ namespace PolyVox } template - void Block::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) + void BlockData::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) { setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); } @@ -133,7 +137,7 @@ namespace PolyVox #pragma region Other template - void Block::fill(VoxelType tValue) + void BlockData::fill(VoxelType tValue) { memset(m_tData, tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType)); } diff --git a/library/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/include/PolyVoxCore/PolyVoxForwardDeclarations.h index 5d81fc00..ac376f88 100644 --- a/library/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. namespace PolyVox { - template class Block; + template class BlockData; //---------- Volume ---------- template class Volume; diff --git a/library/include/PolyVoxCore/Volume.h b/library/include/PolyVoxCore/Volume.h index 02ff6298..5973f77d 100644 --- a/library/include/PolyVoxCore/Volume.h +++ b/library/include/PolyVoxCore/Volume.h @@ -32,6 +32,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. namespace PolyVox { + template + class Block + { + public: + BlockData* m_pBlockData; + VoxelType m_pHomogenousValue; + bool m_pIsShared; + bool m_pIsPotentiallySharable; + }; + template class Volume { @@ -53,21 +63,20 @@ namespace PolyVox void setVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos, VoxelType tValue); void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); - bool containsPoint(const Vector3DFloat& pos, float boundary) const; - bool containsPoint(const Vector3DInt32& pos, uint16 boundary) const; VolumeIterator firstVoxel(void); void idle(uint32 uAmount); bool isRegionHomogenous(const Region& region); VolumeIterator lastVoxel(void); private: - Block* getHomogenousBlock(VoxelType tHomogenousValue) const; + BlockData* getHomogenousBlock(VoxelType tHomogenousValue) const; - Block** m_pBlocks; - bool* m_pIsShared; - bool* m_pIsPotentiallySharable; - VoxelType* m_pHomogenousValue; - mutable std::map*> m_pHomogenousBlocks; + //Block** m_pBlocks; + //bool* m_pIsShared; + //bool* m_pIsPotentiallySharable; + //VoxelType* m_pHomogenousValue; + Block* m_pBlocks; + mutable std::map*> m_pHomogenousBlocks; uint32 m_uNoOfBlocksInVolume; uint16 m_uSideLengthInBlocks; diff --git a/library/include/PolyVoxCore/Volume.inl b/library/include/PolyVoxCore/Volume.inl index 885c0588..fe07942b 100644 --- a/library/include/PolyVoxCore/Volume.inl +++ b/library/include/PolyVoxCore/Volume.inl @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma endregion #pragma region Headers -#include "Block.h" +#include "BlockData.h" #include "VolumeIterator.h" #include "Region.h" #include "Vector.h" @@ -70,7 +70,7 @@ namespace PolyVox m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks; //Create the blocks - m_pBlocks = new Block*[m_uNoOfBlocksInVolume]; + /*m_pBlocks = new Block*[m_uNoOfBlocksInVolume]; m_pIsShared = new bool[m_uNoOfBlocksInVolume]; m_pIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume]; m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume]; @@ -80,6 +80,15 @@ namespace PolyVox m_pIsShared[i] = true; m_pIsPotentiallySharable[i] = false; m_pHomogenousValue[i] = 0; + }*/ + + m_pBlocks = new Block[m_uNoOfBlocksInVolume]; + for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i) + { + m_pBlocks[i].m_pBlockData = getHomogenousBlock(0); + m_pBlocks[i].m_pIsShared = true; + m_pBlocks[i].m_pIsPotentiallySharable = false; + m_pBlocks[i].m_pHomogenousValue = 0; } } @@ -94,8 +103,16 @@ namespace PolyVox { for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i) { - delete m_pBlocks[i]; + if(m_pBlocks[i].m_pIsShared == false) + { + delete m_pBlocks[i].m_pBlockData; + m_pBlocks[i].m_pBlockData = 0; + } } + delete[] m_pBlocks; + /*delete[] m_pIsShared; + delete[] m_pIsPotentiallySharable; + delete[] m_pHomogenousValue;*/ } #pragma endregion @@ -103,33 +120,7 @@ namespace PolyVox template Volume& Volume::operator=(const Volume& rhs) { - if (this == &rhs) - { - return *this; - } - - /*for(uint16 i = 0; i < POLYVOX_NO_OF_BLOCKS_IN_VOLUME; ++i) - { - //FIXME - Add checking... - m_pBlocks[i] = SharedPtr(new Block); - }*/ - - for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i) - { - //I think this is OK... If a block is in the homogeneous array it's ref count will be greater - //than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array. - /*if(rhs.m_pBlocks[i].unique()) - { - m_pBlocks[i] = SharedPtr(new Block(*(rhs.m_pBlocks[i]))); - } - else - {*/ - //we have a block in the homogeneous array - just copy the pointer. - m_pBlocks[i] = rhs.m_pBlocks[i]; - //} - } - - return *this; + } #pragma endregion @@ -161,12 +152,12 @@ namespace PolyVox const uint16 yOffset = uYPos - (blockY << m_uBlockSideLengthPower); const uint16 zOffset = uZPos - (blockZ << m_uBlockSideLengthPower); - const Block* block = m_pBlocks + const BlockData* block = m_pBlocks [ blockX + blockY * m_uSideLengthInBlocks + blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks - ]; + ].m_pBlockData; return block->getVoxelAt(xOffset,yOffset,zOffset); } @@ -199,23 +190,24 @@ namespace PolyVox blockY * m_uSideLengthInBlocks + blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks; - const bool bIsShared = m_pIsShared[uBlockIndex]; - const VoxelType tHomogenousValue = m_pHomogenousValue[uBlockIndex]; + const bool bIsShared = m_pBlocks[uBlockIndex].m_pIsShared; if(bIsShared) { + const VoxelType tHomogenousValue = m_pBlocks[uBlockIndex].m_pHomogenousValue; if(tHomogenousValue != tValue) { - m_pBlocks[uBlockIndex] = new Block(m_uBlockSideLength); - m_pIsShared[uBlockIndex] = false; - m_pBlocks[uBlockIndex]->fill(tHomogenousValue); - m_pBlocks[uBlockIndex]->setVoxelAt(xOffset,yOffset,zOffset, tValue); + m_pBlocks[uBlockIndex].m_pBlockData = new BlockData(m_uBlockSideLength); + m_pBlocks[uBlockIndex].m_pIsShared = false; + m_pBlocks[uBlockIndex].m_pBlockData->fill(tHomogenousValue); + m_pBlocks[uBlockIndex].m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue); } } else - { - //There is a chance that setting this voxel makes the block homogenous and therefore shareable. - m_pIsPotentiallySharable[uBlockIndex] = true; - m_pBlocks[uBlockIndex]->setVoxelAt(xOffset,yOffset,zOffset, tValue); + { + m_pBlocks[uBlockIndex].m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue); + //There is a chance that setting this voxel makes the block homogenous and therefore shareable. But checking + //this will take some time, so for now just set a flag. + m_pBlocks[uBlockIndex].m_pIsPotentiallySharable = true; } } @@ -227,28 +219,6 @@ namespace PolyVox #pragma endregion #pragma region Other - template - bool Volume::containsPoint(const Vector3DFloat& pos, float boundary) const - { - return (pos.getX() <= m_uSideLength - 1 - boundary) - && (pos.getY() <= m_uSideLength - 1 - boundary) - && (pos.getZ() <= m_uSideLength - 1 - boundary) - && (pos.getX() >= boundary) - && (pos.getY() >= boundary) - && (pos.getZ() >= boundary); - } - - template - bool Volume::containsPoint(const Vector3DInt32& pos, uint16 boundary) const - { - return (pos.getX() <= m_uSideLength - 1 - boundary) - && (pos.getY() <= m_uSideLength - 1 - boundary) - && (pos.getZ() <= m_uSideLength - 1 - boundary) - && (pos.getX() >= boundary) - && (pos.getY() >= boundary) - && (pos.getZ() >= boundary); - } - template VolumeIterator Volume::firstVoxel(void) { @@ -295,17 +265,17 @@ namespace PolyVox #pragma region Private Implementation template - Block* Volume::getHomogenousBlock(VoxelType tHomogenousValue) const + BlockData* Volume::getHomogenousBlock(VoxelType tHomogenousValue) const { - typename std::map*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue); + typename std::map*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue); if(iterResult == m_pHomogenousBlocks.end()) { - Block* pBlock = new Block(m_uBlockSideLength); + BlockData* pBlock = new BlockData(m_uBlockSideLength); pBlock->fill(tHomogenousValue); m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock)); return pBlock; } - return iterResult->second; + return iterResult->second; } #pragma endregion } diff --git a/library/include/PolyVoxCore/VolumeIterator.inl b/library/include/PolyVoxCore/VolumeIterator.inl index 0c2d2d9b..e17f340b 100644 --- a/library/include/PolyVoxCore/VolumeIterator.inl +++ b/library/include/PolyVoxCore/VolumeIterator.inl @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma endregion #pragma region Headers -#include "Block.h" +#include "BlockData.h" #include "Volume.h" #include "Vector.h" #include "Region.h" @@ -201,7 +201,7 @@ namespace PolyVox mBlockIndexInVolume = mXBlock + mYBlock * mVolume.m_uSideLengthInBlocks + mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; - Block* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; + BlockData* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume].m_pBlockData; mVoxelIndexInBlock = mXPosInBlock + mYPosInBlock * mVolume.m_uBlockSideLength + @@ -257,7 +257,7 @@ namespace PolyVox mVoxelIndexInBlock = mXPosInBlock + mYPosInBlock * mVolume.m_uBlockSideLength + mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; - Block* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; + BlockData* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; mYPosInBlock++; @@ -270,7 +270,7 @@ namespace PolyVox mVoxelIndexInBlock = mXPosInBlock + mYPosInBlock * mVolume.m_uBlockSideLength + mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; - Block* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; + BlockData* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; mZPosInBlock++; @@ -309,7 +309,7 @@ namespace PolyVox } } - Block* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; + BlockData* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; //mCurrentBlock = mVolume->m_pBlocks[mBlockIndexInVolume]; mXPosInVolume = (std::max)(mXRegionFirst,uint16(mXBlock * mVolume.m_uBlockSideLength)); diff --git a/library/include/PolyVoxUtil/VolumeChangeTracker.h b/library/include/PolyVoxUtil/VolumeChangeTracker.h index 48a1ddee..bc1330b4 100644 --- a/library/include/PolyVoxUtil/VolumeChangeTracker.h +++ b/library/include/PolyVoxUtil/VolumeChangeTracker.h @@ -70,7 +70,7 @@ namespace PolyVox //It's not what the block class was designed for, but it //provides a handy way of storing a 3D grid of values. - Block* volRegionLastModified; + BlockData* volRegionLastModified; static int32 m_iCurrentTime; }; diff --git a/library/source/PolyVoxCore/GradientEstimators.cpp b/library/source/PolyVoxCore/GradientEstimators.cpp index 3e50d43a..ec971bf8 100644 --- a/library/source/PolyVoxCore/GradientEstimators.cpp +++ b/library/source/PolyVoxCore/GradientEstimators.cpp @@ -20,8 +20,8 @@ namespace PolyVox VolumeIterator volIter(*volumeData); //Check all corners are within the volume, allowing a boundary for gradient estimation - bool lowerCornerInside = volumeData->containsPoint(v3dFloor,2); - bool upperCornerInside = volumeData->containsPoint(v3dFloor+Vector3DInt32(1,1,1),2); + bool lowerCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor,2); + bool upperCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor+Vector3DInt32(1,1,1),2); if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was { diff --git a/library/source/PolyVoxCore/SurfaceAdjusters.cpp b/library/source/PolyVoxCore/SurfaceAdjusters.cpp index 20767b64..14ab00d8 100644 --- a/library/source/PolyVoxCore/SurfaceAdjusters.cpp +++ b/library/source/PolyVoxCore/SurfaceAdjusters.cpp @@ -30,8 +30,8 @@ namespace PolyVox const Vector3DFloat& v3dRem = v3dPos - static_cast(v3dFloor); //Check all corners are within the volume, allowing a boundary for gradient estimation - bool lowerCornerInside = volumeData->containsPoint(v3dFloor,2); - bool upperCornerInside = volumeData->containsPoint(v3dFloor+Vector3DInt32(1,1,1),2); + bool lowerCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor,2); + bool upperCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor+Vector3DInt32(1,1,1),2); if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was { @@ -90,8 +90,8 @@ namespace PolyVox VolumeIterator volIter(*volumeData); //Check all corners are within the volume, allowing a boundary for gradient estimation - bool lowerCornerInside = volumeData->containsPoint(v3dFloor,1); - bool upperCornerInside = volumeData->containsPoint(v3dFloor+Vector3DInt32(1,1,1),1); + bool lowerCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor,1); + bool upperCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor+Vector3DInt32(1,1,1),1); if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was { diff --git a/library/source/PolyVoxUtil/VolumeChangeTracker.cpp b/library/source/PolyVoxUtil/VolumeChangeTracker.cpp index 5f7b7024..efa80870 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_uRegionSideLength); + volRegionLastModified = new BlockData(m_uRegionSideLength); } VolumeChangeTracker::~VolumeChangeTracker()