Work on Block class.

This commit is contained in:
David Williams 2009-03-24 20:45:23 +00:00
parent 409afc3a99
commit d191902db3
7 changed files with 52 additions and 25 deletions

View File

@ -29,4 +29,13 @@ Generate ambient lighting from volume?
Utility function for closing outside surfaces? Utility function for closing outside surfaces?
Consider how seperate surface should be generated for a single region. Consider how seperate surface should be generated for a single region.
Consider transparent materials like glass. Consider transparent materials like glass.
Allow writing meshes into volumes? Allow writing meshes into volumes?
Documentation
=============
Define the following terms:
-Voxel
-Cell
-Volume
-Region
-Block

View File

@ -36,7 +36,7 @@ namespace PolyVox
//Make VolumeIterator a friend //Make VolumeIterator a friend
friend class VolumeIterator<VoxelType>; friend class VolumeIterator<VoxelType>;
public: public:
Block(uint8 uSideLengthPower); Block(uint8 uSideLength);
Block(const Block& rhs); Block(const Block& rhs);
~Block(); ~Block();
@ -44,8 +44,10 @@ namespace PolyVox
uint16 getSideLength(void) const; uint16 getSideLength(void) const;
VoxelType getVoxelAt(uint16 uXPos, uint16 uYPos, uint16 uZPos) 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(uint16 uXPos, uint16 uYPos, uint16 uZPos, VoxelType tValue);
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
void fill(VoxelType tValue); void fill(VoxelType tValue);

View File

@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma endregion #pragma endregion
#pragma region Headers #pragma region Headers
#include "Utility.h"
#include <cassert> #include <cassert>
#include <cstring> //For memcpy #include <cstring> //For memcpy
#include <stdexcept> //for std::invalid_argument #include <stdexcept> //for std::invalid_argument
@ -29,18 +31,21 @@ namespace PolyVox
{ {
#pragma region Constructors/Destructors #pragma region Constructors/Destructors
template <typename VoxelType> template <typename VoxelType>
Block<VoxelType>::Block(uint8 uSideLengthPower) Block<VoxelType>::Block(uint8 uSideLength)
:m_tData(0) :m_tData(0)
{ {
//Check the block size is sensible. This corresponds to a side length of 256 voxels //Debug mode error handling
if(uSideLengthPower > 8) 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 //Compute the side length
m_uSideLengthPower = uSideLengthPower; m_uSideLength = uSideLength;
m_uSideLength = 0x01 << uSideLengthPower; m_uSideLengthPower = logBase2(uSideLength);
//If this fails an exception will be thrown. Memory is not //If this fails an exception will be thrown. Memory is not
//allocated and there is nothing else in this class to clean up //allocated and there is nothing else in this class to clean up
@ -95,6 +100,12 @@ namespace PolyVox
uZPos * m_uSideLength * m_uSideLength uZPos * m_uSideLength * m_uSideLength
]; ];
} }
template <typename VoxelType>
VoxelType Block<VoxelType>::getVoxelAt(const Vector3DUint16& v3dPos) const
{
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
#pragma endregion #pragma endregion
#pragma region Setters #pragma region Setters
@ -112,6 +123,12 @@ namespace PolyVox
uZPos * m_uSideLength * m_uSideLength uZPos * m_uSideLength * m_uSideLength
] = tValue; ] = tValue;
} }
template <typename VoxelType>
void Block<VoxelType>::setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue)
{
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
}
#pragma endregion #pragma endregion
#pragma region Other #pragma region Other

View File

@ -26,20 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
namespace PolyVox 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 #endif

View File

@ -192,7 +192,7 @@ namespace PolyVox
{ {
if(tHomogenousValue != tValue) if(tHomogenousValue != tValue)
{ {
m_pBlocks[uBlockIndex] = new Block<VoxelType>(m_uBlockSideLengthPower); m_pBlocks[uBlockIndex] = new Block<VoxelType>(m_uBlockSideLength);
m_pIsShared[uBlockIndex] = false; m_pIsShared[uBlockIndex] = false;
m_pBlocks[uBlockIndex]->fill(tHomogenousValue); m_pBlocks[uBlockIndex]->fill(tHomogenousValue);
m_pBlocks[uBlockIndex]->setVoxelAt(xOffset,yOffset,zOffset, tValue); m_pBlocks[uBlockIndex]->setVoxelAt(xOffset,yOffset,zOffset, tValue);
@ -287,7 +287,7 @@ namespace PolyVox
typename std::map<VoxelType, Block<VoxelType>*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue); typename std::map<VoxelType, Block<VoxelType>*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue);
if(iterResult == m_pHomogenousBlocks.end()) if(iterResult == m_pHomogenousBlocks.end())
{ {
Block<VoxelType>* pBlock = new Block<VoxelType>(m_uBlockSideLengthPower); Block<VoxelType>* pBlock = new Block<VoxelType>(m_uBlockSideLength);
pBlock->fill(tHomogenousValue); pBlock->fill(tHomogenousValue);
m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock)); m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock));
return pBlock; return pBlock;

View File

@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "PolyVoxCore/Utility.h" #include "PolyVoxCore/Utility.h"
#include <cassert> #include <cassert>
#include <stdexcept>
namespace PolyVox namespace PolyVox
{ {
@ -29,9 +30,20 @@ namespace PolyVox
//If this is not the case then the output is undefined. //If this is not the case then the output is undefined.
uint8 logBase2(uint32 uInput) uint8 logBase2(uint32 uInput)
{ {
//Debug mode error handling
assert(uInput != 0); assert(uInput != 0);
assert(isPowerOf2(uInput)); 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; uint32 uResult = 0;
while( (uInput >> uResult) != 0) while( (uInput >> uResult) != 0)
{ {

View File

@ -49,7 +49,7 @@ namespace PolyVox
m_uVolumeSideLengthInRegions = volumeData->getSideLength() / m_uRegionSideLength; m_uVolumeSideLengthInRegions = volumeData->getSideLength() / m_uRegionSideLength;
m_uRegionSideLengthPower = PolyVox::logBase2(m_uRegionSideLength); m_uRegionSideLengthPower = PolyVox::logBase2(m_uRegionSideLength);
volRegionLastModified = new Block<int32>(m_uRegionSideLengthPower); volRegionLastModified = new Block<int32>(m_uRegionSideLength);
} }
VolumeChangeTracker::~VolumeChangeTracker() VolumeChangeTracker::~VolumeChangeTracker()