Various refactoring of volume stuff. Including moving region growing code to scrapyard.

This commit is contained in:
David Williams 2008-04-20 21:32:44 +00:00
parent efce9b8c95
commit 286ba35b42
6 changed files with 25 additions and 249 deletions

View File

@ -21,6 +21,10 @@ namespace PolyVox
typedef Vector<3,boost::int32_t> Vector3DInt32;
typedef Vector<3,boost::uint32_t> Vector3DUint32;
template <typename VoxelType> class Volume;
//Some handy typedefs
typedef Volume<float> FloatVolume;
typedef Volume<boost::uint8_t> UInt8Volume;
typedef Volume<boost::uint16_t> UInt16Volume;
template <typename VoxelType> class VolumeIterator;
}

View File

@ -44,20 +44,20 @@ namespace PolyVox
Volume& operator=(const Volume& rhs);
public:
Block<VoxelType>* getBlock(boost::uint16_t index);
bool containsPoint(Vector3DFloat pos, float boundary);
bool containsPoint(Vector3DInt32 pos, boost::uint16_t boundary);
bool loadFromFile(const std::string& sFilename);
bool saveToFile(const std::string& sFilename);
void regionGrow(boost::uint16_t xStart, boost::uint16_t yStart, boost::uint16_t zStart, VoxelType value);
void tidy(void);
private:
Block<VoxelType>* getBlock(boost::uint16_t index);
Block<VoxelType>* mBlocks[POLYVOX_NO_OF_BLOCKS_IN_VOLUME];
};
//Some handy typedefs
typedef Volume<float> FloatVolume;
typedef Volume<boost::uint8_t> UInt8Volume;
typedef Volume<boost::uint16_t> UInt16Volume;
}
#include "Volume.inl"

View File

@ -85,46 +85,6 @@ namespace PolyVox
return *this;
}
/*VoxelType Volume::getVoxelAt(const uint16_t xPosition, const uint16_t yPosition, const uint16_t zPosition) const
{
const uint16_t blockX = xPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockY = yPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockZ = zPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t xOffset = xPosition - (blockX << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t yOffset = yPosition - (blockY << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t zOffset = zPosition - (blockZ << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
Block* block = mBlocks
[
blockX +
blockY * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS +
blockZ * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS
];
return block->getVoxelAt(xOffset,yOffset,zOffset);
}*/
/*void Volume::setVoxelAt(const uint16_t xPosition, const uint16_t yPosition, const uint16_t zPosition, const VoxelType value)
{
const uint16_t blockX = xPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockY = yPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockZ = zPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t xOffset = xPosition - (blockX << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t yOffset = yPosition - (blockY << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t zOffset = zPosition - (blockZ << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
Block* block = mBlocks
[
blockX +
blockY * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS +
blockZ * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS
];
block->setVoxelAt(xOffset,yOffset,zOffset, value);
}*/
template <typename VoxelType>
Block<VoxelType>* Volume<VoxelType>::getBlock(boost::uint16_t index)
{
@ -151,171 +111,7 @@ namespace PolyVox
&& (pos.x() > boundary)
&& (pos.y() > boundary)
&& (pos.z() > boundary);
}
template <typename VoxelType>
bool Volume<VoxelType>::loadFromFile(const std::string& sFilename)
{
//Open the file
std::ifstream file;
file.open(sFilename.c_str(), std::ios::in | std::ios::binary);
if(!file.is_open())
{
//LogManager::getSingleton().logMessage("Failed to open volume file " + sFilename);
return false;
}
//Read volume dimensions
uint8_t volumeWidth = 0;
uint8_t volumeHeight = 0;
uint8_t volumeDepth = 0;
file.read(reinterpret_cast<char*>(&volumeWidth), sizeof(volumeWidth));
file.read(reinterpret_cast<char*>(&volumeHeight), sizeof(volumeHeight));
file.read(reinterpret_cast<char*>(&volumeDepth), sizeof(volumeDepth));
if(file.fail())
{
//LogManager::getSingleton().logMessage("Failed to read dimentions");
return false;
}
//Read data
VolumeIterator volIter(*this);
for(uint16_t z = 0; z < POLYVOX_VOLUME_SIDE_LENGTH; ++z)
{
for(uint16_t y = 0; y < POLYVOX_VOLUME_SIDE_LENGTH; ++y)
{
for(uint16_t x = 0; x < POLYVOX_VOLUME_SIDE_LENGTH; ++x)
{
VoxelType value;
file.read(reinterpret_cast<char*>(&value), sizeof(value)); //FIXME - check for error here
volIter.setVoxelAt(x,y,z,value);
}
}
//Periodically see if we can tidy the memory to avoid excessive usage during loading.
if(z%POLYVOX_BLOCK_SIDE_LENGTH == POLYVOX_BLOCK_SIDE_LENGTH-1)
{
tidy(); //FIXME - we don't actually have to tidy the whole volume here - just the part we loaded since the last call to tidy.
}
}
return true;
}
template <typename VoxelType>
bool Volume<VoxelType>::saveToFile(const std::string& sFilename)
{
//Open the file
std::ofstream file;
file.open(sFilename.c_str(), std::ios::out | std::ios::binary);
if(!file.is_open())
{
//LogManager::getSingleton().logMessage("Failed to open file for saving volume");
return false;
}
//Read volume dimensions
boost::uint8_t volumeWidth = 0;
boost::uint8_t volumeHeight = 0;
boost::uint8_t volumeDepth = 0;
file.write(reinterpret_cast<char*>(&volumeWidth), sizeof(volumeWidth));
file.write(reinterpret_cast<char*>(&volumeHeight), sizeof(volumeHeight));
file.write(reinterpret_cast<char*>(&volumeDepth), sizeof(volumeDepth));
if(file.fail())
{
//LogManager::getSingleton().logMessage("Failed to write dimensions");
return false;
}
//Write data
VolumeIterator<VoxelType> volIter(*this);
for(boost::uint16_t z = 0; z < POLYVOX_VOLUME_SIDE_LENGTH; ++z)
{
for(boost::uint16_t y = 0; y < POLYVOX_VOLUME_SIDE_LENGTH; ++y)
{
for(boost::uint16_t x = 0; x < POLYVOX_VOLUME_SIDE_LENGTH; ++x)
{
VoxelType value = volIter.getVoxelAt(x,y,z);
file.write(reinterpret_cast<char*>(&value), sizeof(value)); //FIXME - check for error here
}
}
}
return true;
}
template <typename VoxelType>
void Volume<VoxelType>::regionGrow(boost::uint16_t xStart, boost::uint16_t yStart, boost::uint16_t zStart, VoxelType value)
{
//FIXME - introduce integrer 'isInVolume' function
if((xStart > POLYVOX_VOLUME_SIDE_LENGTH-1) || (yStart > POLYVOX_VOLUME_SIDE_LENGTH-1) || (zStart > POLYVOX_VOLUME_SIDE_LENGTH-1)
|| (xStart < 0) || (yStart < 0) || (zStart < 0))
{
//FIXME - error message..
return;
}
VolumeIterator<VoxelType> volIter(*this);
const VoxelType uSeedValue = volIter.getVoxelAt(xStart,yStart,zStart);
if(value == uSeedValue)
{
return; //FIXME - Error message? Exception?
}
std::queue<Vector3DUint32> seeds;
seeds.push(Vector3DUint32(xStart,yStart,zStart));
while(!seeds.empty())
{
Vector3DUint32 currentSeed = seeds.front();
seeds.pop();
//std::cout << "x = " << currentSeed.x << " y = " << currentSeed.y << " z = " << currentSeed.z << std::endl;
//FIXME - introduce 'safe' function which tests this?
if((currentSeed.x() > POLYVOX_VOLUME_SIDE_LENGTH-2) || (currentSeed.y() > POLYVOX_VOLUME_SIDE_LENGTH-2) || (currentSeed.z() > POLYVOX_VOLUME_SIDE_LENGTH-2)
|| (currentSeed.x() < 1) || (currentSeed.y() < 1) || (currentSeed.z() < 1))
{
continue;
}
if(volIter.getVoxelAt(currentSeed.x(), currentSeed.y(), currentSeed.z()+1) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x(), currentSeed.y(), currentSeed.z()+1, value);
seeds.push(Vector3DUint32(currentSeed.x(), currentSeed.y(), currentSeed.z()+1));
}
if(volIter.getVoxelAt(currentSeed.x(), currentSeed.y(), currentSeed.z()-1) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x(), currentSeed.y(), currentSeed.z()-1, value);
seeds.push(Vector3DUint32(currentSeed.x(), currentSeed.y(), currentSeed.z()-1));
}
if(volIter.getVoxelAt(currentSeed.x(), currentSeed.y()+1, currentSeed.z()) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x(), currentSeed.y()+1, currentSeed.z(), value);
seeds.push(Vector3DUint32(currentSeed.x(), currentSeed.y()+1, currentSeed.z()));
}
if(volIter.getVoxelAt(currentSeed.x(), currentSeed.y()-1, currentSeed.z()) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x(), currentSeed.y()-1, currentSeed.z(), value);
seeds.push(Vector3DUint32(currentSeed.x(), currentSeed.y()-1, currentSeed.z()));
}
if(volIter.getVoxelAt(currentSeed.x()+1, currentSeed.y(), currentSeed.z()) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x()+1, currentSeed.y(), currentSeed.z(), value);
seeds.push(Vector3DUint32(currentSeed.x()+1, currentSeed.y(), currentSeed.z()));
}
if(volIter.getVoxelAt(currentSeed.x()-1, currentSeed.y(), currentSeed.z()) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x()-1, currentSeed.y(), currentSeed.z(), value);
seeds.push(Vector3DUint32(currentSeed.x()-1, currentSeed.y(), currentSeed.z()));
}
}
}
}
template <typename VoxelType>
void Volume<VoxelType>::tidy(void)

View File

@ -37,9 +37,6 @@ namespace PolyVox
void setVoxel(VoxelType value);
VoxelType getVoxel(void);
VoxelType getVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition) const;
void setVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition, const VoxelType value);
float getAveragedVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition, boost::uint16_t size) const;
//FIXME - this shouldn't return float vector
@ -88,6 +85,9 @@ namespace PolyVox
VoxelType peekVoxel1px1py1pz(void) const;
private:
VoxelType getVoxelAt(const boost::uint16_t xPosition, const boost::uint16_t yPosition, const boost::uint16_t zPosition) const;
//The current volume
Volume<VoxelType>& mVolume;

View File

@ -130,35 +130,6 @@ namespace PolyVox
return sum;
}
template <typename VoxelType>
void VolumeIterator<VoxelType>::setVoxelAt(const uint16_t xPosition, const uint16_t yPosition, const uint16_t zPosition, const VoxelType value)
{
const uint16_t blockX = xPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockY = yPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t blockZ = zPosition >> POLYVOX_BLOCK_SIDE_LENGTH_POWER;
const uint16_t xOffset = xPosition - (blockX << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t yOffset = yPosition - (blockY << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
const uint16_t zOffset = zPosition - (blockZ << POLYVOX_BLOCK_SIDE_LENGTH_POWER);
Block<VoxelType>* block = mVolume.mBlocks
[
blockX +
blockY * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS +
blockZ * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS * POLYVOX_VOLUME_SIDE_LENGTH_IN_BLOCKS
];
/*if(!block.unique())
{
Block* copy(new Block(*block));
block = copy;
mCurrentVoxel = block->mData + mVoxelIndexInBlock;
}*/
block->setVoxelAt(xOffset,yOffset,zOffset, value);
}
template <typename VoxelType>
Vector3DFloat VolumeIterator<VoxelType>::getCentralDifferenceGradient(void) const
{

View File

@ -159,10 +159,11 @@ namespace PolyVox
{
for(uint16_t x = 0; x < POLYVOX_VOLUME_SIDE_LENGTH; ++x)
{
volIter.setPosition(x,y,z);
if((x/16+y/16+z/16)%2 == 0)
volIter.setVoxelAt(x,y,z,4);
volIter.setVoxel(4);
else
volIter.setVoxelAt(x,y,z,8);
volIter.setVoxel(8);
}
}
}
@ -182,7 +183,8 @@ namespace PolyVox
(x>225)
)
{
volIter.setVoxelAt(x,y,z,2);
volIter.setPosition(x,y,z);
volIter.setVoxel(2);
}
}
}
@ -202,7 +204,8 @@ namespace PolyVox
{
for(uint16_t x = static_cast<uint16_t>(centre.x()) - uHalfX; x < static_cast<uint16_t>(centre.x()) + uHalfX; x++)
{
volIter.setVoxelAt(x,y,z,0);
volIter.setPosition(x,y,z);
volIter.setVoxel(0);
}
}
}
@ -224,7 +227,8 @@ namespace PolyVox
(x<=225)
)
{
volIter.setVoxelAt(x,y,z,1);
volIter.setPosition(x,y,z);
volIter.setVoxel(1);
}
}
}
@ -696,7 +700,8 @@ namespace PolyVox
if(volumeData->containsPoint(Vector3DInt32(uX,uY,uZ),0))
{
VolumeIterator<boost::uint8_t> volIter(*volumeData);
return volIter.getVoxelAt(uX,uY,uZ);
volIter.setPosition(uX,uY,uZ);
return volIter.getVoxel();
}
else
{