Mostly refactoring and tidying up the code.
This commit is contained in:
		| @@ -47,6 +47,8 @@ namespace PolyVox | |||||||
|  |  | ||||||
| 		void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue); | 		void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue); | ||||||
|  |  | ||||||
|  | 		void fill(VoxelType tValue); | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 		boost::uint8_t m_uSideLengthPower; | 		boost::uint8_t m_uSideLengthPower; | ||||||
| 		boost::uint16_t m_uSideLength; | 		boost::uint16_t m_uSideLength; | ||||||
|   | |||||||
| @@ -106,11 +106,19 @@ namespace PolyVox | |||||||
| 		assert(uZPos < m_uSideLength); | 		assert(uZPos < m_uSideLength); | ||||||
|  |  | ||||||
| 		m_tData | 		m_tData | ||||||
| 			[ | 		[ | ||||||
| 				uXPos +  | 			uXPos +  | ||||||
| 				uYPos * m_uSideLength +  | 			uYPos * m_uSideLength +  | ||||||
| 				uZPos * m_uSideLength * m_uSideLength | 			uZPos * m_uSideLength * m_uSideLength | ||||||
| 			] = tValue; | 		] = tValue; | ||||||
|  | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Other | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void Block<VoxelType>::fill(VoxelType tValue) | ||||||
|  | 	{ | ||||||
|  | 		memset(m_tData, tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType)); | ||||||
| 	} | 	} | ||||||
| 	#pragma endregion | 	#pragma endregion | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,6 +26,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | |||||||
| #include "PolyVoxForwardDeclarations.h" | #include "PolyVoxForwardDeclarations.h" | ||||||
|  |  | ||||||
| #include "boost/cstdint.hpp" | #include "boost/cstdint.hpp" | ||||||
|  |  | ||||||
|  | #include <map> | ||||||
| #pragma endregion | #pragma endregion | ||||||
|  |  | ||||||
| namespace PolyVox | namespace PolyVox | ||||||
| @@ -43,26 +45,39 @@ namespace PolyVox | |||||||
|  |  | ||||||
| 		Volume& operator=(const Volume& rhs); | 		Volume& operator=(const Volume& rhs); | ||||||
|  |  | ||||||
| 		boost::uint16_t getSideLength(void); | 		boost::uint16_t getSideLength(void) const; | ||||||
| 		VoxelType getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const; | 		VoxelType getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const; | ||||||
| 		VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; | 		VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; | ||||||
|  |  | ||||||
| 		void setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue); |  | ||||||
| 		void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); |  | ||||||
|  |  | ||||||
| 		bool containsPoint(Vector3DFloat pos, float boundary) const; | 		bool containsPoint(Vector3DFloat pos, float boundary) const; | ||||||
| 		bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const; | 		bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary) const; | ||||||
|  | 		void idle(boost::uint32_t uAmount); | ||||||
|  | 		void lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner); | ||||||
|  | 		void unlock(void); | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 		Block<VoxelType>** mBlocks; | 		bool isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos); | ||||||
|  |  | ||||||
|  | 		Block<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const; | ||||||
|  |  | ||||||
|  | 		Block<VoxelType>** m_pBlocks; | ||||||
|  | 		bool* m_pIsShared; | ||||||
|  | 		bool* m_pIsPotentiallySharable; | ||||||
|  | 		VoxelType* m_pHomogenousValue; | ||||||
|  | 		mutable std::map<VoxelType, Block<VoxelType>*> m_pHomogenousBlocks; | ||||||
|  |  | ||||||
| 		boost::uint32_t m_uNoOfBlocksInVolume; | 		boost::uint32_t m_uNoOfBlocksInVolume; | ||||||
| 		boost::uint16_t m_uSideLengthInBlocks; | 		boost::uint16_t m_uSideLengthInBlocks; | ||||||
|  |  | ||||||
| 		boost::uint8_t m_uSideLengthPower; | 		boost::uint8_t m_uSideLengthPower; | ||||||
| 		boost::uint16_t m_uSideLength; | 		boost::uint16_t m_uSideLength; | ||||||
|  |  | ||||||
| 		boost::uint16_t m_uBlockSideLengthPower; | 		boost::uint8_t m_uBlockSideLengthPower; | ||||||
| 		boost::uint16_t m_uBlockSideLength; | 		boost::uint16_t m_uBlockSideLength; | ||||||
|  |  | ||||||
|  | 		Vector3DUint16 m_v3dLastLockedLowerCorner; | ||||||
|  | 		Vector3DUint16 m_v3dLastLockedUpperCorner; | ||||||
|  | 		bool m_bIsLocked; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	//Some handy typedefs | 	//Some handy typedefs | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ namespace PolyVox | |||||||
| 	#pragma region Constructors/Destructors | 	#pragma region Constructors/Destructors | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	Volume<VoxelType>::Volume(boost::uint8_t uSideLengthPower, boost::uint8_t uBlockSideLengthPower) | 	Volume<VoxelType>::Volume(boost::uint8_t uSideLengthPower, boost::uint8_t uBlockSideLengthPower) | ||||||
| 		:mBlocks(0) | 		:m_pBlocks(0) | ||||||
| 	{ | 	{ | ||||||
| 		//Check the volume size is sensible. This corresponds to a side length of 65536 voxels | 		//Check the volume size is sensible. This corresponds to a side length of 65536 voxels | ||||||
| 		if(uSideLengthPower > 16) | 		if(uSideLengthPower > 16) | ||||||
| @@ -53,15 +53,17 @@ namespace PolyVox | |||||||
| 		//Compute number of blocks in the volume | 		//Compute number of blocks in the volume | ||||||
| 		m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks; | 		m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks; | ||||||
|  |  | ||||||
| 		mBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume]; | 		//Create the blocks | ||||||
|  | 		m_pBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume]; | ||||||
|  | 		m_pIsShared = new bool[m_uNoOfBlocksInVolume]; | ||||||
|  | 		m_pIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume]; | ||||||
|  | 		m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume]; | ||||||
| 		for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | 		for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | ||||||
| 		{ | 		{ | ||||||
| 			mBlocks[i] = 0; | 			m_pBlocks[i] = getHomogenousBlock(0); //new Block<VoxelType>(uBlockSideLengthPower); | ||||||
| 		} | 			m_pIsShared[i] = true; | ||||||
|  | 			m_pIsPotentiallySharable[i] = false; | ||||||
| 		for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | 			m_pHomogenousValue[i] = 0; | ||||||
| 		{ |  | ||||||
| 			mBlocks[i] = new Block<VoxelType>(uBlockSideLengthPower); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -76,7 +78,7 @@ namespace PolyVox | |||||||
| 	{ | 	{ | ||||||
| 		for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | 		for(boost::uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | ||||||
| 		{ | 		{ | ||||||
| 			delete mBlocks[i]; | 			delete m_pBlocks[i]; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	#pragma endregion | 	#pragma endregion | ||||||
| @@ -93,21 +95,21 @@ namespace PolyVox | |||||||
| 		/*for(uint16_t i = 0; i < POLYVOX_NO_OF_BLOCKS_IN_VOLUME; ++i) | 		/*for(uint16_t i = 0; i < POLYVOX_NO_OF_BLOCKS_IN_VOLUME; ++i) | ||||||
| 		{ | 		{ | ||||||
| 			//FIXME - Add checking... | 			//FIXME - Add checking... | ||||||
| 			mBlocks[i] = SharedPtr<Block>(new Block); | 			m_pBlocks[i] = SharedPtr<Block>(new Block); | ||||||
| 		}*/ | 		}*/ | ||||||
|  |  | ||||||
| 		for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i) | 		for(uint32_t 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 | 			//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. | 			//than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array. | ||||||
| 			/*if(rhs.mBlocks[i].unique()) | 			/*if(rhs.m_pBlocks[i].unique()) | ||||||
| 			{ | 			{ | ||||||
| 				mBlocks[i] = SharedPtr<Block>(new Block(*(rhs.mBlocks[i]))); | 				m_pBlocks[i] = SharedPtr<Block>(new Block(*(rhs.m_pBlocks[i]))); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{*/ | 			{*/ | ||||||
| 				//we have a block in the homogeneous array - just copy the pointer. | 				//we have a block in the homogeneous array - just copy the pointer. | ||||||
| 				mBlocks[i] = rhs.mBlocks[i]; | 				m_pBlocks[i] = rhs.m_pBlocks[i]; | ||||||
| 			//} | 			//} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -117,7 +119,7 @@ namespace PolyVox | |||||||
|  |  | ||||||
| 	#pragma region Getters | 	#pragma region Getters | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	boost::uint16_t Volume<VoxelType>::getSideLength(void) | 	boost::uint16_t Volume<VoxelType>::getSideLength(void) const | ||||||
| 	{ | 	{ | ||||||
| 		return m_uSideLength; | 		return m_uSideLength; | ||||||
| 	} | 	} | ||||||
| @@ -125,9 +127,9 @@ namespace PolyVox | |||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	VoxelType Volume<VoxelType>::getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const | 	VoxelType Volume<VoxelType>::getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const | ||||||
| 	{ | 	{ | ||||||
| 		assert(uXPos < mVolume.getSideLength()); | 		assert(uXPos < getSideLength()); | ||||||
| 		assert(uYPos < mVolume.getSideLength()); | 		assert(uYPos < getSideLength()); | ||||||
| 		assert(uZPos < mVolume.getSideLength()); | 		assert(uZPos < getSideLength()); | ||||||
|  |  | ||||||
| 		const uint16_t blockX = uXPos >> m_uBlockSideLengthPower; | 		const uint16_t blockX = uXPos >> m_uBlockSideLengthPower; | ||||||
| 		const uint16_t blockY = uYPos >> m_uBlockSideLengthPower; | 		const uint16_t blockY = uYPos >> m_uBlockSideLengthPower; | ||||||
| @@ -137,7 +139,7 @@ namespace PolyVox | |||||||
| 		const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower); | 		const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower); | ||||||
| 		const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower); | 		const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower); | ||||||
|  |  | ||||||
| 		const Block<VoxelType>* block = mBlocks | 		const Block<VoxelType>* block = m_pBlocks | ||||||
| 			[ | 			[ | ||||||
| 				blockX +  | 				blockX +  | ||||||
| 				blockY * m_uSideLengthInBlocks +  | 				blockY * m_uSideLengthInBlocks +  | ||||||
| @@ -158,43 +160,6 @@ namespace PolyVox | |||||||
| 	} | 	} | ||||||
| 	#pragma endregion	 | 	#pragma endregion	 | ||||||
|  |  | ||||||
| 	#pragma region Setters |  | ||||||
| 	template <typename VoxelType> |  | ||||||
| 	void Volume<VoxelType>::setVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos, VoxelType tValue) |  | ||||||
| 	{ |  | ||||||
| 		assert(uXPos < mVolume.getSideLength()); |  | ||||||
| 		assert(uYPos < mVolume.getSideLength()); |  | ||||||
| 		assert(uZPos < mVolume.getSideLength()); |  | ||||||
|  |  | ||||||
| 		const uint16_t blockX = uXPos >> m_uBlockSideLengthPower; |  | ||||||
| 		const uint16_t blockY = uYPos >> m_uBlockSideLengthPower; |  | ||||||
| 		const uint16_t blockZ = uZPos >> m_uBlockSideLengthPower; |  | ||||||
|  |  | ||||||
| 		const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower); |  | ||||||
| 		const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower); |  | ||||||
| 		const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower); |  | ||||||
|  |  | ||||||
| 		const Block<VoxelType>* block = mBlocks |  | ||||||
| 			[ |  | ||||||
| 				blockX +  |  | ||||||
| 				blockY * m_uSideLengthInBlocks +  |  | ||||||
| 				blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks |  | ||||||
| 			]; |  | ||||||
|  |  | ||||||
| 		return block->setVoxelAt(xOffset,yOffset,zOffset, tValue); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	template <typename VoxelType> |  | ||||||
| 	void Volume<VoxelType>::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue) |  | ||||||
| 	{ |  | ||||||
| 		assert(v3dPos.x() < m_uSideLength); |  | ||||||
| 		assert(v3dPos.y() < m_uSideLength); |  | ||||||
| 		assert(v3dPos.z() < m_uSideLength); |  | ||||||
|  |  | ||||||
| 		setVoxelAt(v3dPos.x(), v3dPos.y(), v3dPos.z(), tValue); |  | ||||||
| 	} |  | ||||||
| 	#pragma endregion |  | ||||||
|  |  | ||||||
| 	#pragma region Other | 	#pragma region Other | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	bool Volume<VoxelType>::containsPoint(Vector3DFloat pos, float boundary) const | 	bool Volume<VoxelType>::containsPoint(Vector3DFloat pos, float boundary) const | ||||||
| @@ -217,5 +182,108 @@ namespace PolyVox | |||||||
| 			&& (pos.y() >= boundary) | 			&& (pos.y() >= boundary) | ||||||
| 			&& (pos.z() >= boundary); | 			&& (pos.z() >= boundary); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void Volume<VoxelType>::idle(boost::uint32_t uAmount) | ||||||
|  | 	{ | ||||||
|  | 		//Check the volume isn't locked | ||||||
|  | 		if(m_bIsLocked) | ||||||
|  | 		{ | ||||||
|  | 			throw std::logic_error("Cannot perform idle tasks on a locked volume"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void Volume<VoxelType>::lock(const Vector3DUint16& v3dLowerCorner, const Vector3DUint16& v3dUpperCorner) | ||||||
|  | 	{ | ||||||
|  | 		//Check the volume isn't already locked | ||||||
|  | 		if(m_bIsLocked) | ||||||
|  | 		{ | ||||||
|  | 			throw std::logic_error("Cannot lock an already locked volume"); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		//Find the block corresponding to the lower corner | ||||||
|  | 		Vector3DUint16 v3dBlockLowerCorner | ||||||
|  | 		( | ||||||
|  | 			v3dLowerCorner.x() >> m_uBlockSideLengthPower, | ||||||
|  | 			v3dLowerCorner.y() >> m_uBlockSideLengthPower, | ||||||
|  | 			v3dLowerCorner.z() >> m_uBlockSideLengthPower | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		//Find the block corresponding to the upper corner | ||||||
|  | 		Vector3DUint16 v3dBlockUpperCorner | ||||||
|  | 		( | ||||||
|  | 			v3dUpperCorner.x() >> m_uBlockSideLengthPower, | ||||||
|  | 			v3dUpperCorner.y() >> m_uBlockSideLengthPower, | ||||||
|  | 			v3dUpperCorner.z() >> m_uBlockSideLengthPower | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		//Set all covered blocks to be potentially sharable | ||||||
|  | 		for(boost::uint16_t z = v3dBlockLowerCorner.z(); z <= v3dBlockUpperCorner.z(); ++z) | ||||||
|  | 		{ | ||||||
|  | 			for(boost::uint16_t y = v3dBlockLowerCorner.y(); y <= v3dBlockUpperCorner.y(); ++y) | ||||||
|  | 			{ | ||||||
|  | 				for(boost::uint16_t x = v3dBlockLowerCorner.x(); x <= v3dBlockUpperCorner.x(); ++x) | ||||||
|  | 				{ | ||||||
|  | 					const boost::uint32_t uBlockIndex =  | ||||||
|  | 						blockX +  | ||||||
|  | 						blockY * m_uSideLengthInBlocks +  | ||||||
|  | 						blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks; | ||||||
|  | 					m_pIsPotentiallySharable[uBlockIndex] = true; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		//Store the values so that we can verify voxels are locked before writing to them | ||||||
|  | 		m_v3dLastLockedLowerCorner = v3dLowerCorner; | ||||||
|  | 		m_v3dLastLockedUpperCorner = v3dUpperCorner; | ||||||
|  | 		m_bIsLocked = true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void Volume<VoxelType>::unlock(void) | ||||||
|  | 	{ | ||||||
|  | 		//Check the volume isn't already locked. | ||||||
|  | 		if(!m_bIsLocked) | ||||||
|  | 		{ | ||||||
|  | 			throw std::logic_error("Cannot unlock an already unlocked volume"); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		//Unlock it | ||||||
|  | 		m_bIsLocked = false; | ||||||
|  | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Private Implementation | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	Block<VoxelType>* Volume<VoxelType>::getHomogenousBlock(VoxelType tHomogenousValue) const | ||||||
|  | 	{ | ||||||
|  | 		std::map<VoxelType, Block<VoxelType>*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue); | ||||||
|  | 		if(iterResult == m_pHomogenousBlocks.end()) | ||||||
|  | 		{ | ||||||
|  | 			Block<VoxelType>* pBlock = new Block<VoxelType>(m_uBlockSideLengthPower); | ||||||
|  | 			pBlock->fill(tHomogenousValue); | ||||||
|  | 			m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock)); | ||||||
|  | 			return pBlock; | ||||||
|  | 		} | ||||||
|  | 		return  iterResult->second; | ||||||
|  | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Private Implementation | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	bool Volume<VoxelType>::isVoxelLocked(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) | ||||||
|  | 	{ | ||||||
|  | 		return | ||||||
|  | 		( | ||||||
|  | 			(uXPos >= m_v3dLastLockedLowerCorner.x()) && | ||||||
|  | 			(uYPos >= m_v3dLastLockedLowerCorner.y()) && | ||||||
|  | 			(uZPos >= m_v3dLastLockedLowerCorner.z()) && | ||||||
|  | 			(uXPos <= m_v3dLastLockedUpperCorner.x()) && | ||||||
|  | 			(uYPos <= m_v3dLastLockedUpperCorner.y()) && | ||||||
|  | 			(uZPos <= m_v3dLastLockedUpperCorner.z()) && | ||||||
|  | 			(m_bIsLocked) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
| 	#pragma endregion | 	#pragma endregion | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,11 +22,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | |||||||
| #ifndef __VolumeIterator_H__ | #ifndef __VolumeIterator_H__ | ||||||
| #define __VolumeIterator_H__ | #define __VolumeIterator_H__ | ||||||
|  |  | ||||||
| #include "boost/cstdint.hpp" | #pragma region Headers | ||||||
|  |  | ||||||
| #include "PolyVoxForwardDeclarations.h" | #include "PolyVoxForwardDeclarations.h" | ||||||
| #include "TypeDef.h" |  | ||||||
| #include "Vector.h" | #include "boost/cstdint.hpp" | ||||||
|  | #pragma endregion | ||||||
|  |  | ||||||
| namespace PolyVox | namespace PolyVox | ||||||
| { | { | ||||||
| @@ -37,22 +37,20 @@ namespace PolyVox | |||||||
| 		VolumeIterator(Volume<VoxelType>& volume); | 		VolumeIterator(Volume<VoxelType>& volume); | ||||||
| 		~VolumeIterator();		 | 		~VolumeIterator();		 | ||||||
|  |  | ||||||
| 		void setVoxel(VoxelType value); | 		bool operator==(const VolumeIterator& rhs); | ||||||
| 		VoxelType getVoxel(void); |  | ||||||
|  |  | ||||||
| 		float getAveragedVoxel(boost::uint16_t size) const; | 		float getAveragedVoxel(boost::uint16_t size) const; | ||||||
|  |  | ||||||
| 		 |  | ||||||
|  |  | ||||||
| 		boost::uint16_t getPosX(void) const; | 		boost::uint16_t getPosX(void) const; | ||||||
| 		boost::uint16_t getPosY(void) const; | 		boost::uint16_t getPosY(void) const; | ||||||
| 		boost::uint16_t getPosZ(void) const; | 		boost::uint16_t getPosZ(void) const; | ||||||
|  | 		VoxelType getVoxel(void) const;			 | ||||||
|  |  | ||||||
| 		void setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos); | 		void setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos); | ||||||
| 		void setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast); | 		void setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast); | ||||||
| 		void moveForwardInRegion(void); | 		void setVoxel(VoxelType tValue);	 | ||||||
|  |  | ||||||
| 		bool isValidForRegion(void); | 		bool isValidForRegion(void) const; | ||||||
|  | 		void moveForwardInRegion(void);		 | ||||||
|  |  | ||||||
| 		VoxelType peekVoxel1nx1ny1nz(void) const; | 		VoxelType peekVoxel1nx1ny1nz(void) const; | ||||||
| 		VoxelType peekVoxel1nx1ny0pz(void) const; | 		VoxelType peekVoxel1nx1ny0pz(void) const; | ||||||
| @@ -85,9 +83,6 @@ namespace PolyVox | |||||||
| 		VoxelType peekVoxel1px1py1pz(void) const; | 		VoxelType peekVoxel1px1py1pz(void) const; | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
|  |  | ||||||
| 		//VoxelType getVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition) const; |  | ||||||
|  |  | ||||||
| 		//The current volume | 		//The current volume | ||||||
| 		Volume<VoxelType>& mVolume; | 		Volume<VoxelType>& mVolume; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,13 +19,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | |||||||
| ******************************************************************************/ | ******************************************************************************/ | ||||||
| #pragma endregion | #pragma endregion | ||||||
|  |  | ||||||
|  | #pragma region Headers | ||||||
| #include "Block.h" | #include "Block.h" | ||||||
|  | #include "Vector.h" | ||||||
| #include "Volume.h" | #include "Volume.h" | ||||||
|  | #pragma endregion | ||||||
| using namespace boost; |  | ||||||
|  |  | ||||||
| namespace PolyVox | namespace PolyVox | ||||||
| { | { | ||||||
|  | 	#pragma region Constructors/Destructors | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume) | 	VolumeIterator<VoxelType>::VolumeIterator(Volume<VoxelType>& volume) | ||||||
| 		:mVolume(volume) | 		:mVolume(volume) | ||||||
| @@ -51,8 +53,7 @@ namespace PolyVox | |||||||
| 		,mYPosInBlock(0) | 		,mYPosInBlock(0) | ||||||
| 		,mZPosInBlock(0) | 		,mZPosInBlock(0) | ||||||
| 		,mIsValidForRegion(true) | 		,mIsValidForRegion(true) | ||||||
| 		,mCurrentVoxel(volume.mBlocks[0]->m_tData) | 		,mCurrentVoxel(volume.m_pBlocks[0]->m_tData) | ||||||
| 		//,mCurrentBlock(volume->mBlocks[0]) |  | ||||||
| 		,mVoxelIndexInBlock(0) | 		,mVoxelIndexInBlock(0) | ||||||
| 		,mBlockIndexInVolume(0) | 		,mBlockIndexInVolume(0) | ||||||
| 	{ | 	{ | ||||||
| @@ -62,57 +63,25 @@ namespace PolyVox | |||||||
| 	VolumeIterator<VoxelType>::~VolumeIterator() | 	VolumeIterator<VoxelType>::~VolumeIterator() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Operators | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	void VolumeIterator<VoxelType>::setVoxel(VoxelType value) | 	bool VolumeIterator<VoxelType>::operator==(const VolumeIterator<VoxelType>& rhs) | ||||||
| 	{ | 	{ | ||||||
| 		Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; | 		//We could just check whether the two mCurrentVoxel pointers are equal, but this may not | ||||||
|  | 		//be safe in the future if we decide to allow blocks to be shared between volumes | ||||||
| 		/*if(!currentBlock.unique()) | 		//So we really check whether the volumes and positions are the same | ||||||
| 		{ | 		/*return | ||||||
| 			Block* copy(new Block(*currentBlock)); | 		( | ||||||
| 			currentBlock = copy; | 			mVolume. | ||||||
|  | 		);*/ | ||||||
| 			mCurrentVoxel = currentBlock->mData + mVoxelIndexInBlock; |  | ||||||
| 		}*/ |  | ||||||
|  |  | ||||||
| 		*mCurrentVoxel = value; |  | ||||||
| 	} | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Getters | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	VoxelType VolumeIterator<VoxelType>::getVoxel(void) | 	float VolumeIterator<VoxelType>::getAveragedVoxel(boost::uint16_t size) const | ||||||
| 	{ |  | ||||||
| 		//return getVoxelAt(mXPosInVolume,mYPosInVolume,mZPosInVolume); |  | ||||||
| 		return *mCurrentVoxel; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/*template <typename VoxelType> |  | ||||||
| 	VoxelType VolumeIterator<VoxelType>::getVoxelAt(const uint16_t xPosition, const uint16_t yPosition, const uint16_t zPosition) const |  | ||||||
| 	{ |  | ||||||
| 		assert(xPosition < mVolume.getSideLength()); |  | ||||||
| 		assert(yPosition < mVolume.getSideLength()); |  | ||||||
| 		assert(zPosition < mVolume.getSideLength()); |  | ||||||
|  |  | ||||||
| 		const uint16_t blockX = xPosition >> mVolume.m_uBlockSideLengthPower; |  | ||||||
| 		const uint16_t blockY = yPosition >> mVolume.m_uBlockSideLengthPower; |  | ||||||
| 		const uint16_t blockZ = zPosition >> mVolume.m_uBlockSideLengthPower; |  | ||||||
|  |  | ||||||
| 		const uint16_t xOffset = xPosition - (blockX << mVolume.m_uBlockSideLengthPower); |  | ||||||
| 		const uint16_t yOffset = yPosition - (blockY << mVolume.m_uBlockSideLengthPower); |  | ||||||
| 		const uint16_t zOffset = zPosition - (blockZ << mVolume.m_uBlockSideLengthPower); |  | ||||||
|  |  | ||||||
| 		const Block<VoxelType>* block = mVolume.mBlocks |  | ||||||
| 			[ |  | ||||||
| 				blockX +  |  | ||||||
| 				blockY * mVolume.m_uSideLengthInBlocks +  |  | ||||||
| 				blockZ * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks |  | ||||||
| 			]; |  | ||||||
|  |  | ||||||
| 		return block->getVoxelAt(xOffset,yOffset,zOffset); |  | ||||||
| 	}*/ |  | ||||||
|  |  | ||||||
| 	template <typename VoxelType> |  | ||||||
| 	float VolumeIterator<VoxelType>::getAveragedVoxel(uint16_t size) const |  | ||||||
| 	{ | 	{ | ||||||
| 		assert(mXPosInVolume >= size); | 		assert(mXPosInVolume >= size); | ||||||
| 		assert(mYPosInVolume >= size); | 		assert(mYPosInVolume >= size); | ||||||
| @@ -144,25 +113,33 @@ namespace PolyVox | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	uint16_t VolumeIterator<VoxelType>::getPosX(void) const | 	boost::uint16_t VolumeIterator<VoxelType>::getPosX(void) const | ||||||
| 	{ | 	{ | ||||||
| 		return mXPosInVolume; | 		return mXPosInVolume; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	uint16_t VolumeIterator<VoxelType>::getPosY(void) const | 	boost::uint16_t VolumeIterator<VoxelType>::getPosY(void) const | ||||||
| 	{ | 	{ | ||||||
| 		return mYPosInVolume; | 		return mYPosInVolume; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	uint16_t VolumeIterator<VoxelType>::getPosZ(void) const | 	boost::uint16_t VolumeIterator<VoxelType>::getPosZ(void) const | ||||||
| 	{ | 	{ | ||||||
| 		return mZPosInVolume; | 		return mZPosInVolume; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	void VolumeIterator<VoxelType>::setPosition(uint16_t xPos, uint16_t yPos, uint16_t zPos) | 	VoxelType VolumeIterator<VoxelType>::getVoxel(void) const | ||||||
|  | 	{ | ||||||
|  | 		return *mCurrentVoxel; | ||||||
|  | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Setters | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void VolumeIterator<VoxelType>::setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos) | ||||||
| 	{ | 	{ | ||||||
| 		mXPosInVolume = xPos; | 		mXPosInVolume = xPos; | ||||||
| 		mYPosInVolume = yPos; | 		mYPosInVolume = yPos; | ||||||
| @@ -179,7 +156,7 @@ namespace PolyVox | |||||||
| 		mBlockIndexInVolume = mXBlock +  | 		mBlockIndexInVolume = mXBlock +  | ||||||
| 			mYBlock * mVolume.m_uSideLengthInBlocks +  | 			mYBlock * mVolume.m_uSideLengthInBlocks +  | ||||||
| 			mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; | 			mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; | ||||||
| 		Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; | 		Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; | ||||||
|  |  | ||||||
| 		mVoxelIndexInBlock = mXPosInBlock +  | 		mVoxelIndexInBlock = mXPosInBlock +  | ||||||
| 			mYPosInBlock * mVolume.m_uBlockSideLength +  | 			mYPosInBlock * mVolume.m_uBlockSideLength +  | ||||||
| @@ -189,7 +166,7 @@ namespace PolyVox | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	void VolumeIterator<VoxelType>::setValidRegion(uint16_t xFirst, uint16_t yFirst, uint16_t zFirst, uint16_t xLast, uint16_t yLast, uint16_t zLast) | 	void VolumeIterator<VoxelType>::setValidRegion(boost::uint16_t xFirst, boost::uint16_t yFirst, boost::uint16_t zFirst, boost::uint16_t xLast, boost::uint16_t yLast, boost::uint16_t zLast) | ||||||
| 	{ | 	{ | ||||||
| 		mXRegionFirst = xFirst; | 		mXRegionFirst = xFirst; | ||||||
| 		mYRegionFirst = yFirst; | 		mYRegionFirst = yFirst; | ||||||
| @@ -208,6 +185,43 @@ namespace PolyVox | |||||||
| 		mZRegionLastBlock = mZRegionLast >> mVolume.m_uBlockSideLengthPower; | 		mZRegionLastBlock = mZRegionLast >> mVolume.m_uBlockSideLengthPower; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	void VolumeIterator<VoxelType>::setVoxel(VoxelType tValue) | ||||||
|  | 	{ | ||||||
|  | 		assert(mVolume.isVoxelLocked(mXPosInVolume,mYPosInVolume,mZPosInVolume)); | ||||||
|  |  | ||||||
|  | 		const boost::uint32_t uBlockIndex =  | ||||||
|  | 				mXBlock +  | ||||||
|  | 				mYBlock * mVolume.m_uSideLengthInBlocks +  | ||||||
|  | 				mZBlock * mVolume.m_uSideLengthInBlocks * mVolume.m_uSideLengthInBlocks; | ||||||
|  |  | ||||||
|  | 		const bool bIsShared = mVolume.m_pIsShared[uBlockIndex]; | ||||||
|  | 		const VoxelType tHomogenousValue = mVolume.m_pHomogenousValue[uBlockIndex]; | ||||||
|  | 		if(bIsShared) | ||||||
|  | 		{ | ||||||
|  | 			if(tHomogenousValue != tValue) | ||||||
|  | 			{ | ||||||
|  | 				mVolume.m_pBlocks[uBlockIndex] = new Block<VoxelType>(mVolume.m_uBlockSideLengthPower); | ||||||
|  | 				mVolume.m_pIsShared[uBlockIndex] = false; | ||||||
|  | 				mVolume.m_pBlocks[uBlockIndex]->fill(tHomogenousValue); | ||||||
|  | 				mCurrentVoxel = mVolume.m_pBlocks[uBlockIndex]->m_tData + mVoxelIndexInBlock; | ||||||
|  | 				*mCurrentVoxel = tValue; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			*mCurrentVoxel = tValue; | ||||||
|  | 		}		 | ||||||
|  | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
|  | 	#pragma region Other | ||||||
|  | 	template <typename VoxelType> | ||||||
|  | 	bool VolumeIterator<VoxelType>::isValidForRegion(void) const | ||||||
|  | 	{ | ||||||
|  | 		return mIsValidForRegion; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	void VolumeIterator<VoxelType>::moveForwardInRegion(void) | 	void VolumeIterator<VoxelType>::moveForwardInRegion(void) | ||||||
| 	{ | 	{ | ||||||
| @@ -221,7 +235,7 @@ namespace PolyVox | |||||||
| 			mVoxelIndexInBlock = mXPosInBlock +  | 			mVoxelIndexInBlock = mXPosInBlock +  | ||||||
| 				mYPosInBlock * mVolume.m_uBlockSideLength +  | 				mYPosInBlock * mVolume.m_uBlockSideLength +  | ||||||
| 				mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; | 				mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; | ||||||
| 			Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; | 			Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; | ||||||
| 			mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; | 			mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; | ||||||
|  |  | ||||||
| 			mYPosInBlock++; | 			mYPosInBlock++; | ||||||
| @@ -234,7 +248,7 @@ namespace PolyVox | |||||||
| 				mVoxelIndexInBlock = mXPosInBlock +  | 				mVoxelIndexInBlock = mXPosInBlock +  | ||||||
| 					mYPosInBlock * mVolume.m_uBlockSideLength +  | 					mYPosInBlock * mVolume.m_uBlockSideLength +  | ||||||
| 					mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; | 					mZPosInBlock * mVolume.m_uBlockSideLength * mVolume.m_uBlockSideLength; | ||||||
| 				Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; | 				Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; | ||||||
| 				mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; | 				mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; | ||||||
|  |  | ||||||
| 				mZPosInBlock++; | 				mZPosInBlock++; | ||||||
| @@ -273,8 +287,8 @@ namespace PolyVox | |||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					Block<VoxelType>* currentBlock = mVolume.mBlocks[mBlockIndexInVolume]; | 					Block<VoxelType>* currentBlock = mVolume.m_pBlocks[mBlockIndexInVolume]; | ||||||
| 					//mCurrentBlock = mVolume->mBlocks[mBlockIndexInVolume];					 | 					//mCurrentBlock = mVolume->m_pBlocks[mBlockIndexInVolume];					 | ||||||
|  |  | ||||||
| 					mXPosInVolume = (std::max)(mXRegionFirst,uint16_t(mXBlock * mVolume.m_uBlockSideLength));					 | 					mXPosInVolume = (std::max)(mXRegionFirst,uint16_t(mXBlock * mVolume.m_uBlockSideLength));					 | ||||||
| 					mYPosInVolume = (std::max)(mYRegionFirst,uint16_t(mYBlock * mVolume.m_uBlockSideLength));					 | 					mYPosInVolume = (std::max)(mYRegionFirst,uint16_t(mYBlock * mVolume.m_uBlockSideLength));					 | ||||||
| @@ -293,13 +307,9 @@ namespace PolyVox | |||||||
| 			} | 			} | ||||||
| 		}		 | 		}		 | ||||||
| 	} | 	} | ||||||
|  | 	#pragma endregion | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	#pragma region Peekers | ||||||
| 	bool VolumeIterator<VoxelType>::isValidForRegion(void) |  | ||||||
| 	{ |  | ||||||
| 		return mIsValidForRegion; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	template <typename VoxelType> | 	template <typename VoxelType> | ||||||
| 	VoxelType VolumeIterator<VoxelType>::peekVoxel1nx1ny1nz(void) const | 	VoxelType VolumeIterator<VoxelType>::peekVoxel1nx1ny1nz(void) const | ||||||
| 	{ | 	{ | ||||||
| @@ -569,4 +579,5 @@ namespace PolyVox | |||||||
| 		} | 		} | ||||||
| 		return mVolume.getVoxelAt(mXPosInVolume+1,mYPosInVolume+1,mZPosInVolume+1); | 		return mVolume.getVoxelAt(mXPosInVolume+1,mYPosInVolume+1,mZPosInVolume+1); | ||||||
| 	} | 	} | ||||||
|  | 	#pragma endregion | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user