Work making decimated approach handle multiple resolutions.

This commit is contained in:
David Williams 2008-06-12 19:40:36 +00:00
parent 3566fc1863
commit e019c92dc2
6 changed files with 312 additions and 308 deletions

View File

@ -44,7 +44,7 @@ namespace PolyVox
bool operator>=(const BlockVolumeIterator& rhs); bool operator>=(const BlockVolumeIterator& rhs);
float getAveragedVoxel(boost::uint16_t size) const; float getAveragedVoxel(boost::uint16_t size) const;
VoxelType getMaxedVoxel(void) const; VoxelType getMaxedVoxel(boost::uint8_t level) 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;

View File

@ -137,18 +137,26 @@ namespace PolyVox
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType BlockVolumeIterator<VoxelType>::getMaxedVoxel(void) const VoxelType BlockVolumeIterator<VoxelType>::getMaxedVoxel(boost::uint8_t level) const
{ {
VoxelType tValue = getVoxel(); if(level == 0)
tValue = (std::max)(tValue, peekVoxel1px0py0pz()); {
tValue = (std::max)(tValue, peekVoxel0px1py0pz()); return getVoxel();
tValue = (std::max)(tValue, peekVoxel1px1py0pz()); }
tValue = (std::max)(tValue, peekVoxel0px0py1pz()); else if(level == 1)
tValue = (std::max)(tValue, peekVoxel1px0py1pz()); {
tValue = (std::max)(tValue, peekVoxel0px1py1pz()); VoxelType tValue = getVoxel();
tValue = (std::max)(tValue, peekVoxel1px1py1pz()); tValue = (std::max)(tValue, peekVoxel1px0py0pz());
return tValue; tValue = (std::max)(tValue, peekVoxel0px1py0pz());
tValue = (std::max)(tValue, peekVoxel1px1py0pz());
tValue = (std::max)(tValue, peekVoxel0px0py1pz());
tValue = (std::max)(tValue, peekVoxel1px0py1pz());
tValue = (std::max)(tValue, peekVoxel0px1py1pz());
tValue = (std::max)(tValue, peekVoxel1px1py1pz());
return tValue;
}
assert(false);
return 0;
} }
template <typename VoxelType> template <typename VoxelType>

View File

@ -36,9 +36,9 @@ namespace PolyVox
{ {
boost::uint32_t getDecimatedIndex(boost::uint32_t x, boost::uint32_t y); boost::uint32_t getDecimatedIndex(boost::uint32_t x, boost::uint32_t y);
POLYVOX_API void generateDecimatedMeshDataForRegion(BlockVolume<boost::uint8_t>* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); POLYVOX_API void generateDecimatedMeshDataForRegion(BlockVolume<boost::uint8_t>* volumeData, boost::uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch);
POLYVOX_API boost::uint32_t computeInitialDecimatedBitmaskForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, const Region& regSlice, const Vector3DFloat& offset, boost::uint8_t *bitmask); POLYVOX_API boost::uint32_t computeInitialDecimatedBitmaskForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, boost::uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, boost::uint8_t *bitmask);
POLYVOX_API boost::uint32_t computeDecimatedBitmaskForSliceFromPrevious(BlockVolumeIterator<boost::uint8_t>& volIter, const Region& regSlice, const Vector3DFloat& offset, boost::uint8_t *bitmask, boost::uint8_t *previousBitmask); POLYVOX_API boost::uint32_t computeDecimatedBitmaskForSliceFromPrevious(BlockVolumeIterator<boost::uint8_t>& volIter, boost::uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, boost::uint8_t *bitmask, boost::uint8_t *previousBitmask);
POLYVOX_API void generateDecimatedIndicesForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, boost::uint8_t* bitmask0, boost::uint8_t* bitmask1, boost::int32_t vertexIndicesX0[],boost::int32_t vertexIndicesY0[],boost::int32_t vertexIndicesZ0[], boost::int32_t vertexIndicesX1[],boost::int32_t vertexIndicesY1[],boost::int32_t vertexIndicesZ1[]); POLYVOX_API void generateDecimatedIndicesForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, const Region& regSlice, IndexedSurfacePatch* singleMaterialPatch, const Vector3DFloat& offset, boost::uint8_t* bitmask0, boost::uint8_t* bitmask1, boost::int32_t vertexIndicesX0[],boost::int32_t vertexIndicesY0[],boost::int32_t vertexIndicesZ0[], boost::int32_t vertexIndicesX1[],boost::int32_t vertexIndicesY1[],boost::int32_t vertexIndicesZ1[]);
POLYVOX_API void generateDecimatedVerticesForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, Region& regSlice, const Vector3DFloat& offset, boost::uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,boost::int32_t vertexIndicesX[],boost::int32_t vertexIndicesY[],boost::int32_t vertexIndicesZ[]); POLYVOX_API void generateDecimatedVerticesForSlice(BlockVolumeIterator<boost::uint8_t>& volIter, Region& regSlice, const Vector3DFloat& offset, boost::uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,boost::int32_t vertexIndicesX[],boost::int32_t vertexIndicesY[],boost::int32_t vertexIndicesZ[]);

View File

@ -29,7 +29,7 @@ namespace PolyVox
regionGeometry.m_patchSingleMaterial = new IndexedSurfacePatch(false); regionGeometry.m_patchSingleMaterial = new IndexedSurfacePatch(false);
regionGeometry.m_v3dRegionPosition = iterChangedRegions->getLowerCorner(); regionGeometry.m_v3dRegionPosition = iterChangedRegions->getLowerCorner();
generateDecimatedMeshDataForRegion(volume.getVolumeData(), *iterChangedRegions, regionGeometry.m_patchSingleMaterial); generateDecimatedMeshDataForRegion(volume.getVolumeData(), 1, *iterChangedRegions, regionGeometry.m_patchSingleMaterial);
//genMultiFromSingle(regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial); //genMultiFromSingle(regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial);

View File

@ -20,7 +20,7 @@ namespace PolyVox
return x + (y * (POLYVOX_REGION_SIDE_LENGTH+1)); return x + (y * (POLYVOX_REGION_SIDE_LENGTH+1));
} }
void generateDecimatedMeshDataForRegion(BlockVolume<uint8_t>* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) void generateDecimatedMeshDataForRegion(BlockVolume<uint8_t>* volumeData, uint8_t uLevel, Region region, IndexedSurfacePatch* singleMaterialPatch)
{ {
singleMaterialPatch->m_vecVertices.clear(); singleMaterialPatch->m_vecVertices.clear();
singleMaterialPatch->m_vecTriangleIndices.clear(); singleMaterialPatch->m_vecTriangleIndices.clear();
@ -37,10 +37,12 @@ namespace PolyVox
boost::uint8_t* bitmask0 = new boost::uint8_t[(POLYVOX_REGION_SIDE_LENGTH+1) * (POLYVOX_REGION_SIDE_LENGTH+1)]; boost::uint8_t* bitmask0 = new boost::uint8_t[(POLYVOX_REGION_SIDE_LENGTH+1) * (POLYVOX_REGION_SIDE_LENGTH+1)];
boost::uint8_t* bitmask1 = new boost::uint8_t[(POLYVOX_REGION_SIDE_LENGTH+1) * (POLYVOX_REGION_SIDE_LENGTH+1)]; boost::uint8_t* bitmask1 = new boost::uint8_t[(POLYVOX_REGION_SIDE_LENGTH+1) * (POLYVOX_REGION_SIDE_LENGTH+1)];
const uint8_t uStepSize = 1 << uLevel;
//When generating the mesh for a region we actually look one voxel outside it in the //When generating the mesh for a region we actually look one voxel outside it in the
// back, bottom, right direction. Protect against access violations by cropping region here // back, bottom, right direction. Protect against access violations by cropping region here
Region regVolume = volumeData->getEnclosingRegion(); Region regVolume = volumeData->getEnclosingRegion();
regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(uLevel+uStepSize,uLevel+uStepSize,uLevel+uStepSize));
region.cropTo(regVolume); region.cropTo(regVolume);
//Offset from volume corner //Offset from volume corner
@ -48,13 +50,15 @@ namespace PolyVox
//Create a region corresponding to the first slice //Create a region corresponding to the first slice
Region regSlice0(region); Region regSlice0(region);
regSlice0.setUpperCorner(Vector3DInt32(regSlice0.getUpperCorner().getX(),regSlice0.getUpperCorner().getY(),regSlice0.getLowerCorner().getZ())); Vector3DInt32 v3dUpperCorner = regSlice0.getUpperCorner();
v3dUpperCorner.setZ(regSlice0.getLowerCorner().getZ()); //Set the upper z to the lower z to make it one slice thick.
regSlice0.setUpperCorner(v3dUpperCorner);
//Iterator to access the volume data //Iterator to access the volume data
BlockVolumeIterator<boost::uint8_t> volIter(*volumeData); BlockVolumeIterator<boost::uint8_t> volIter(*volumeData);
//Compute bitmask for initial slice //Compute bitmask for initial slice
boost::uint32_t uNoOfNonEmptyCellsForSlice0 = computeInitialDecimatedBitmaskForSlice(volIter, regSlice0, offset, bitmask0); boost::uint32_t uNoOfNonEmptyCellsForSlice0 = computeInitialDecimatedBitmaskForSlice(volIter, uLevel, regSlice0, offset, bitmask0);
if(uNoOfNonEmptyCellsForSlice0 != 0) if(uNoOfNonEmptyCellsForSlice0 != 0)
{ {
//If there were some non-empty cells then generate initial slice vertices for them //If there were some non-empty cells then generate initial slice vertices for them
@ -66,7 +70,7 @@ namespace PolyVox
Region regSlice1(regSlice0); Region regSlice1(regSlice0);
regSlice1.shift(Vector3DInt32(0,0,2)); regSlice1.shift(Vector3DInt32(0,0,2));
boost::uint32_t uNoOfNonEmptyCellsForSlice1 = computeDecimatedBitmaskForSliceFromPrevious(volIter, regSlice1, offset, bitmask1, bitmask0); boost::uint32_t uNoOfNonEmptyCellsForSlice1 = computeDecimatedBitmaskForSliceFromPrevious(volIter, uLevel, regSlice1, offset, bitmask1, bitmask0);
if(uNoOfNonEmptyCellsForSlice1 != 0) if(uNoOfNonEmptyCellsForSlice1 != 0)
{ {
@ -106,304 +110,296 @@ namespace PolyVox
}*/ }*/
} }
boost::uint32_t computeInitialDecimatedBitmaskForSlice(BlockVolumeIterator<uint8_t>& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask) boost::uint32_t computeInitialDecimatedBitmaskForSlice(BlockVolumeIterator<uint8_t>& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask)
{ {
const uint8_t uStepSize = 1 << uLevel;
boost::uint32_t uNoOfNonEmptyCells = 0; boost::uint32_t uNoOfNonEmptyCells = 0;
//Iterate over each cell in the region //Iterate over each cell in the region
//volIter.setPosition(regSlice.getLowerCorner().getX(),regSlice.getLowerCorner().getY(), regSlice.getLowerCorner().getZ()); for(uint16_t y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += uStepSize)
//volIter.setValidRegion(regSlice);
//do
for(uint16_t y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += 2)
{ {
for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += 2) for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += uStepSize)
{ {
//Current position //Current position
//const uint16_t x = volIter.getPosX() - offset.getX();
//const uint16_t y = volIter.getPosY() - offset.getY();
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ());
//Determine the index into the edge table which tells us which vertices are inside of the surface
uint8_t iCubeIndex = 0;
if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY()))
{
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()); volIter.setPosition(x,y,regSlice.getLowerCorner().getZ());
const uint8_t v000 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ());
const uint8_t v100 = volIter.getMaxedVoxel();
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v010 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel();
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+2); //Determine the index into the edge table which tells us which vertices are inside of the surface
const uint8_t v001 = volIter.getMaxedVoxel(); uint8_t iCubeIndex = 0;
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ()+2);
const uint8_t v101 = volIter.getMaxedVoxel();
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v011 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
if (v000 == 0) iCubeIndex |= 1; if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY()))
if (v100 == 0) iCubeIndex |= 2; {
if (v110 == 0) iCubeIndex |= 4; volIter.setPosition(x,y,regSlice.getLowerCorner().getZ());
if (v010 == 0) iCubeIndex |= 8; const uint8_t v000 = volIter.getMaxedVoxel(uLevel);
if (v001 == 0) iCubeIndex |= 16; volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ());
if (v101 == 0) iCubeIndex |= 32; const uint8_t v100 = volIter.getMaxedVoxel(uLevel);
if (v111 == 0) iCubeIndex |= 64; volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ());
if (v011 == 0) iCubeIndex |= 128; const uint8_t v010 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v001 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v101 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v011 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(1);
if (v000 == 0) iCubeIndex |= 1;
if (v100 == 0) iCubeIndex |= 2;
if (v110 == 0) iCubeIndex |= 4;
if (v010 == 0) iCubeIndex |= 8;
if (v001 == 0) iCubeIndex |= 16;
if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128;
}
else if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY())
{
volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ());
const uint8_t v100 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v101 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY())];
uint8_t srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
uint8_t srcBit5 = iPreviousCubeIndexX & 32;
uint8_t destBit4 = srcBit5 >> 1;
uint8_t srcBit2 = iPreviousCubeIndexX & 4;
uint8_t destBit3 = srcBit2 << 1;
uint8_t srcBit1 = iPreviousCubeIndexX & 2;
uint8_t destBit0 = srcBit1 >> 1;
iCubeIndex |= destBit0;
if (v100 == 0) iCubeIndex |= 2;
if (v110 == 0) iCubeIndex |= 4;
iCubeIndex |= destBit3;
iCubeIndex |= destBit4;
if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
else if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY()))
{
volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ());
const uint8_t v010 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v011 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
uint8_t srcBit3 = iPreviousCubeIndexY & 8;
uint8_t destBit0 = srcBit3 >> 3;
uint8_t srcBit2 = iPreviousCubeIndexY & 4;
uint8_t destBit1 = srcBit2 >> 1;
iCubeIndex |= destBit0;
iCubeIndex |= destBit1;
if (v110 == 0) iCubeIndex |= 4;
if (v010 == 0) iCubeIndex |= 8;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128;
}
else
{
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
uint8_t srcBit3 = iPreviousCubeIndexY & 8;
uint8_t destBit0 = srcBit3 >> 3;
uint8_t srcBit2 = iPreviousCubeIndexY & 4;
uint8_t destBit1 = srcBit2 >> 1;
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY())];
srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
srcBit2 = iPreviousCubeIndexX & 4;
uint8_t destBit3 = srcBit2 << 1;
iCubeIndex |= destBit0;
iCubeIndex |= destBit1;
if (v110 == 0) iCubeIndex |= 4;
iCubeIndex |= destBit3;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
//Save the bitmask
bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())] = iCubeIndex;
if(edgeTable[iCubeIndex] != 0)
{
++uNoOfNonEmptyCells;
}
} }
else if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY())
{
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ());
const uint8_t v100 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ()+2);
const uint8_t v101 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-2,y- offset.getY())];
uint8_t srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
uint8_t srcBit5 = iPreviousCubeIndexX & 32;
uint8_t destBit4 = srcBit5 >> 1;
uint8_t srcBit2 = iPreviousCubeIndexX & 4;
uint8_t destBit3 = srcBit2 << 1;
uint8_t srcBit1 = iPreviousCubeIndexX & 2;
uint8_t destBit0 = srcBit1 >> 1;
iCubeIndex |= destBit0;
if (v100 == 0) iCubeIndex |= 2;
if (v110 == 0) iCubeIndex |= 4;
iCubeIndex |= destBit3;
iCubeIndex |= destBit4;
if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
else if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY()))
{
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v010 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel();
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v011 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-2)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
uint8_t srcBit3 = iPreviousCubeIndexY & 8;
uint8_t destBit0 = srcBit3 >> 3;
uint8_t srcBit2 = iPreviousCubeIndexY & 4;
uint8_t destBit1 = srcBit2 >> 1;
iCubeIndex |= destBit0;
iCubeIndex |= destBit1;
if (v110 == 0) iCubeIndex |= 4;
if (v010 == 0) iCubeIndex |= 8;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128;
}
else
{
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ());
const uint8_t v110 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-2)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
uint8_t srcBit3 = iPreviousCubeIndexY & 8;
uint8_t destBit0 = srcBit3 >> 3;
uint8_t srcBit2 = iPreviousCubeIndexY & 4;
uint8_t destBit1 = srcBit2 >> 1;
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-2,y- offset.getY())];
srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
srcBit2 = iPreviousCubeIndexX & 4;
uint8_t destBit3 = srcBit2 << 1;
iCubeIndex |= destBit0;
iCubeIndex |= destBit1;
if (v110 == 0) iCubeIndex |= 4;
iCubeIndex |= destBit3;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
//Save the bitmask
bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())] = iCubeIndex;
if(edgeTable[iCubeIndex] != 0)
{
++uNoOfNonEmptyCells;
}
}//while(volIter.moveForwardInRegionXYZ());//For each cell
} }
return uNoOfNonEmptyCells; return uNoOfNonEmptyCells;
} }
boost::uint32_t computeDecimatedBitmaskForSliceFromPrevious(BlockVolumeIterator<uint8_t>& volIter, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, uint8_t* previousBitmask) boost::uint32_t computeDecimatedBitmaskForSliceFromPrevious(BlockVolumeIterator<uint8_t>& volIter, uint8_t uLevel, const Region& regSlice, const Vector3DFloat& offset, uint8_t* bitmask, uint8_t* previousBitmask)
{ {
const uint8_t uStepSize = 1 << uLevel;
boost::uint32_t uNoOfNonEmptyCells = 0; boost::uint32_t uNoOfNonEmptyCells = 0;
//Iterate over each cell in the region //Iterate over each cell in the region
//volIter.setPosition(regSlice.getLowerCorner().getX(),regSlice.getLowerCorner().getY(), regSlice.getLowerCorner().getZ()); for(uint16_t y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY(); y += uStepSize)
//volIter.setValidRegion(regSlice);
//do
for(uint16_t y = regSlice.getLowerCorner().getY(); y <= regSlice.getUpperCorner().getY()+1; y += 2)
{ {
for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX()+1; x += 2) for(uint16_t x = regSlice.getLowerCorner().getX(); x <= regSlice.getUpperCorner().getX(); x += uStepSize)
{ {
//Current position //Current position
//const uint16_t x = volIter.getPosX() - offset.getX(); volIter.setPosition(x,y,regSlice.getLowerCorner().getZ());
//const uint16_t y = volIter.getPosY() - offset.getY();
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ());
//Determine the index into the edge table which tells us which vertices are inside of the surface //Determine the index into the edge table which tells us which vertices are inside of the surface
uint8_t iCubeIndex = 0; uint8_t iCubeIndex = 0;
if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY())) if((x==regSlice.getLowerCorner().getX()) && (y==regSlice.getLowerCorner().getY()))
{ {
volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v001 = volIter.getMaxedVoxel(); const uint8_t v001 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v101 = volIter.getMaxedVoxel(); const uint8_t v101 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v011 = volIter.getMaxedVoxel(); const uint8_t v011 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(); const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//z //z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())]; uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4; iCubeIndex = iPreviousCubeIndexZ >> 4;
if (v001 == 0) iCubeIndex |= 16; if (v001 == 0) iCubeIndex |= 16;
if (v101 == 0) iCubeIndex |= 32; if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64; if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128; if (v011 == 0) iCubeIndex |= 128;
} }
else if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY()) else if((x>regSlice.getLowerCorner().getX()) && y==regSlice.getLowerCorner().getY())
{ {
volIter.setPosition(x+2,y,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x+uStepSize,y,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v101 = volIter.getMaxedVoxel(); const uint8_t v101 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2); volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(); const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//z //z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())]; uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4; iCubeIndex = iPreviousCubeIndexZ >> 4;
//x //x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-2,y- offset.getY())]; uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY())];
uint8_t srcBit6 = iPreviousCubeIndexX & 64; uint8_t srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1; uint8_t destBit7 = srcBit6 << 1;
uint8_t srcBit5 = iPreviousCubeIndexX & 32;
uint8_t destBit4 = srcBit5 >> 1;
iCubeIndex |= destBit4;
if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
else if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY()))
{
volIter.setPosition(x,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v011 = volIter.getMaxedVoxel(uLevel);
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4;
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128;
}
else
{
volIter.setPosition(x+uStepSize,y+uStepSize,regSlice.getLowerCorner().getZ()+uStepSize);
const uint8_t v111 = volIter.getMaxedVoxel(uLevel);
//z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4;
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-uStepSize)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-uStepSize,y- offset.getY())];
srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
//Save the bitmask
bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())] = iCubeIndex;
if(edgeTable[iCubeIndex] != 0)
{
++uNoOfNonEmptyCells;
}
uint8_t srcBit5 = iPreviousCubeIndexX & 32; }//For each cell
uint8_t destBit4 = srcBit5 >> 1;
iCubeIndex |= destBit4;
if (v101 == 0) iCubeIndex |= 32;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
else if((x==regSlice.getLowerCorner().getX()) && (y>regSlice.getLowerCorner().getY()))
{
volIter.setPosition(x,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v011 = volIter.getMaxedVoxel();
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
//z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4;
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-2)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
if (v011 == 0) iCubeIndex |= 128;
}
else
{
volIter.setPosition(x+2,y+2,regSlice.getLowerCorner().getZ()+2);
const uint8_t v111 = volIter.getMaxedVoxel();
//z
uint8_t iPreviousCubeIndexZ = previousBitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())];
iCubeIndex = iPreviousCubeIndexZ >> 4;
//y
uint8_t iPreviousCubeIndexY = bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY()-2)];
uint8_t srcBit7 = iPreviousCubeIndexY & 128;
uint8_t destBit4 = srcBit7 >> 3;
uint8_t srcBit6 = iPreviousCubeIndexY & 64;
uint8_t destBit5 = srcBit6 >> 1;
//x
uint8_t iPreviousCubeIndexX = bitmask[getDecimatedIndex(x- offset.getX()-2,y- offset.getY())];
srcBit6 = iPreviousCubeIndexX & 64;
uint8_t destBit7 = srcBit6 << 1;
iCubeIndex |= destBit4;
iCubeIndex |= destBit5;
if (v111 == 0) iCubeIndex |= 64;
iCubeIndex |= destBit7;
}
//Save the bitmask
bitmask[getDecimatedIndex(x- offset.getX(),y- offset.getY())] = iCubeIndex;
if(edgeTable[iCubeIndex] != 0)
{
++uNoOfNonEmptyCells;
}
}//while(volIter.moveForwardInRegionXYZ());//For each cell
} }
return uNoOfNonEmptyCells; return uNoOfNonEmptyCells;
@ -426,7 +422,7 @@ namespace PolyVox
const uint16_t z = regSlice.getLowerCorner().getZ(); const uint16_t z = regSlice.getLowerCorner().getZ();
volIter.setPosition(x,y,z); volIter.setPosition(x,y,z);
const uint8_t v000 = volIter.getMaxedVoxel(); const uint8_t v000 = volIter.getMaxedVoxel(1);
//Determine the index into the edge table which tells us which vertices are inside of the surface //Determine the index into the edge table which tells us which vertices are inside of the surface
uint8_t iCubeIndex = bitmask[getDecimatedIndex(x - offset.getX(),y - offset.getY())]; uint8_t iCubeIndex = bitmask[getDecimatedIndex(x - offset.getX(),y - offset.getY())];
@ -445,7 +441,7 @@ namespace PolyVox
const Vector3DFloat v3dPosition(x - offset.getX() + 0.5f * 2.0f, y - offset.getY(), z - offset.getZ()); const Vector3DFloat v3dPosition(x - offset.getX() + 0.5f * 2.0f, y - offset.getY(), z - offset.getZ());
const Vector3DFloat v3dNormal(1.0,0.0,0.0); const Vector3DFloat v3dNormal(1.0,0.0,0.0);
volIter.setPosition(x+2,y,z); volIter.setPosition(x+2,y,z);
const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(); //Because one of these is 0, the or operation takes the max. const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(1); //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0); SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0);
singleMaterialPatch->m_vecVertices.push_back(surfaceVertex); singleMaterialPatch->m_vecVertices.push_back(surfaceVertex);
vertexIndicesX[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1; vertexIndicesX[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1;
@ -458,7 +454,7 @@ namespace PolyVox
const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY() + 0.5f * 2.0f, z - offset.getZ()); const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY() + 0.5f * 2.0f, z - offset.getZ());
const Vector3DFloat v3dNormal(0.0,1.0,0.0); const Vector3DFloat v3dNormal(0.0,1.0,0.0);
volIter.setPosition(x,y+2,z); volIter.setPosition(x,y+2,z);
const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(); //Because one of these is 0, the or operation takes the max. const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(1); //Because one of these is 0, the or operation takes the max.
SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0); SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0);
singleMaterialPatch->m_vecVertices.push_back(surfaceVertex); singleMaterialPatch->m_vecVertices.push_back(surfaceVertex);
vertexIndicesY[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1; vertexIndicesY[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1;
@ -471,7 +467,7 @@ namespace PolyVox
const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY(), z - offset.getZ() + 0.5f * 2.0f); const Vector3DFloat v3dPosition(x - offset.getX(), y - offset.getY(), z - offset.getZ() + 0.5f * 2.0f);
const Vector3DFloat v3dNormal(0.0,0.0,1.0); const Vector3DFloat v3dNormal(0.0,0.0,1.0);
volIter.setPosition(x,y,z+2); volIter.setPosition(x,y,z+2);
const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(); //Because one of these is 0, the or operation takes the max. const uint8_t uMaterial = v000 | volIter.getMaxedVoxel(1); //Because one of these is 0, the or operation takes the max.
const SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0); const SurfaceVertex surfaceVertex(v3dPosition, v3dNormal, uMaterial, 1.0);
singleMaterialPatch->m_vecVertices.push_back(surfaceVertex); singleMaterialPatch->m_vecVertices.push_back(surfaceVertex);
vertexIndicesZ[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1; vertexIndicesZ[getDecimatedIndex(x - offset.getX(),y - offset.getY())] = singleMaterialPatch->m_vecVertices.size()-1;
@ -618,21 +614,21 @@ namespace PolyVox
//while(volIter.moveForwardInRegionXYZ()) //while(volIter.moveForwardInRegionXYZ())
//{ //{
volIter.setPosition(x,y,z); volIter.setPosition(x,y,z);
const uint8_t v000 = volIter.getMaxedVoxel(); const uint8_t v000 = volIter.getMaxedVoxel(1);
volIter.setPosition(x+2,y,z); volIter.setPosition(x+2,y,z);
const uint8_t v100 = volIter.getMaxedVoxel(); const uint8_t v100 = volIter.getMaxedVoxel(1);
volIter.setPosition(x,y+2,z); volIter.setPosition(x,y+2,z);
const uint8_t v010 = volIter.getMaxedVoxel(); const uint8_t v010 = volIter.getMaxedVoxel(1);
volIter.setPosition(x+2,y+2,z); volIter.setPosition(x+2,y+2,z);
const uint8_t v110 = volIter.getMaxedVoxel(); const uint8_t v110 = volIter.getMaxedVoxel(1);
volIter.setPosition(x,y,z+2); volIter.setPosition(x,y,z+2);
const uint8_t v001 = volIter.getMaxedVoxel(); const uint8_t v001 = volIter.getMaxedVoxel(1);
volIter.setPosition(x+2,y,z+2); volIter.setPosition(x+2,y,z+2);
const uint8_t v101 = volIter.getMaxedVoxel(); const uint8_t v101 = volIter.getMaxedVoxel(1);
volIter.setPosition(x,y+2,z+2); volIter.setPosition(x,y+2,z+2);
const uint8_t v011 = volIter.getMaxedVoxel(); const uint8_t v011 = volIter.getMaxedVoxel(1);
volIter.setPosition(x+2,y+2,z+2); volIter.setPosition(x+2,y+2,z+2);
const uint8_t v111 = volIter.getMaxedVoxel(); const uint8_t v111 = volIter.getMaxedVoxel(1);
//Determine the index into the edge table which tells us which vertices are inside of the surface //Determine the index into the edge table which tells us which vertices are inside of the surface
uint8_t iCubeIndex = 0; uint8_t iCubeIndex = 0;

View File

@ -64,13 +64,13 @@ namespace PolyVox
listToFill.clear(); listToFill.clear();
//Regenerate meshes. //Regenerate meshes.
for(uint16_t regionZ = 0; regionZ < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1; ++regionZ) for(uint16_t regionZ = 0; regionZ < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionZ)
//for(uint16_t regionZ = 0; regionZ < 1; ++regionZ) //for(uint16_t regionZ = 0; regionZ < 1; ++regionZ)
{ {
for(uint16_t regionY = 0; regionY < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1; ++regionY) for(uint16_t regionY = 0; regionY < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionY)
//for(uint16_t regionY = 0; regionY < 2; ++regionY) //for(uint16_t regionY = 0; regionY < 2; ++regionY)
{ {
for(uint16_t regionX = 0; regionX < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1; ++regionX) for(uint16_t regionX = 0; regionX < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionX)
//for(uint16_t regionX = 0; regionX < 2; ++regionX) //for(uint16_t regionX = 0; regionX < 2; ++regionX)
{ {
if(volRegionUpToDate->getVoxelAt(regionX, regionY, regionZ) == false) if(volRegionUpToDate->getVoxelAt(regionX, regionY, regionZ) == false)