From e49859fc40abaaa8638566cadb3c23cbea0e91f2 Mon Sep 17 00:00:00 2001 From: David Williams Date: Tue, 3 Jun 2008 19:14:27 +0000 Subject: [PATCH] Initial version of new experimental marching cubes algorithm. Currently about half as fast. --- include/BlockVolumeIterator.h | 3 +- include/BlockVolumeIterator.inl | 55 ++++- include/SurfaceExtractors.h | 1 + source/SurfaceExtractors.cpp | 395 +++++++++++++++++++++++++++++++- source/VolumeChangeTracker.cpp | 12 +- 5 files changed, 454 insertions(+), 12 deletions(-) diff --git a/include/BlockVolumeIterator.h b/include/BlockVolumeIterator.h index 378a51ac..d82e938e 100644 --- a/include/BlockVolumeIterator.h +++ b/include/BlockVolumeIterator.h @@ -55,7 +55,8 @@ namespace PolyVox void setVoxel(VoxelType tValue); bool isValidForRegion(void) const; - void moveForwardInRegion(void); + void moveForwardInRegionFast(void); + bool moveForwardInRegionXYZ(void); VoxelType peekVoxel1nx1ny1nz(void) const; VoxelType peekVoxel1nx1ny0pz(void) const; diff --git a/include/BlockVolumeIterator.inl b/include/BlockVolumeIterator.inl index f6d063d3..b1fc729b 100644 --- a/include/BlockVolumeIterator.inl +++ b/include/BlockVolumeIterator.inl @@ -253,7 +253,7 @@ namespace PolyVox } template - void BlockVolumeIterator::moveForwardInRegion(void) + void BlockVolumeIterator::moveForwardInRegionFast(void) { mXPosInBlock++; mCurrentVoxel++; @@ -337,6 +337,59 @@ namespace PolyVox } } } + + template + bool BlockVolumeIterator::moveForwardInRegionXYZ(void) + { + if(mXPosInVolume < mXRegionLast) + { + ++mXPosInVolume; + if(mXPosInVolume % mVolume.m_uBlockSideLength != 0) + { + //No need to compute new block. + ++mVoxelIndexInBlock; + ++mCurrentVoxel; + } + else + { + //A more complex situation. Just call setPosition(). + setPosition(mXPosInVolume, mYPosInVolume, mZPosInVolume); + } + } + else + { + mXPosInVolume = mXRegionFirst; + if(mYPosInVolume < mYRegionLast) + { + ++mYPosInVolume; + //In the case of 'X' we used a trick to avoid calling this evey time. It's hard to use the same + //trick here because the x position has been reset and so is likely to be in a different block. + setPosition(mXPosInVolume, mYPosInVolume, mZPosInVolume); + } + else + { + mYPosInVolume = mYRegionFirst; + if(mZPosInVolume < mZRegionLast) + { + ++mZPosInVolume; + //In the case of 'X' we used a trick to avoid calling this evey time. It's hard to use the same + //trick here because the x position has been reset and so is likely to be in a different block. + setPosition(mXPosInVolume, mYPosInVolume, mZPosInVolume); + } + else + { + //We've hit the end of the region. Reset x and y positions to where they were. + mXPosInVolume = mXRegionLast; + mYPosInVolume = mYRegionLast; + + //Return false to indicate we failed to move forward. + return false; + } + } + } + + return true; + } #pragma endregion #pragma region Peekers diff --git a/include/SurfaceExtractors.h b/include/SurfaceExtractors.h index 9159a57f..6e08bd24 100644 --- a/include/SurfaceExtractors.h +++ b/include/SurfaceExtractors.h @@ -35,6 +35,7 @@ namespace PolyVox { POLYVOX_API std::list getChangedRegionGeometry(VolumeChangeTracker& volume); + POLYVOX_API void generateExperimentalMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); POLYVOX_API void generateRoughMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); POLYVOX_API Vector3DFloat computeNormal(BlockVolume* volumeData, const Vector3DFloat& position, NormalGenerationMethod normalGenerationMethod); diff --git a/source/SurfaceExtractors.cpp b/source/SurfaceExtractors.cpp index 789955f4..7afe2b80 100644 --- a/source/SurfaceExtractors.cpp +++ b/source/SurfaceExtractors.cpp @@ -26,7 +26,7 @@ namespace PolyVox regionGeometry.m_patchSingleMaterial = new IndexedSurfacePatch(false); regionGeometry.m_v3dRegionPosition = iterChangedRegions->getLowerCorner(); - generateRoughMeshDataForRegion(volume.getVolumeData(), *iterChangedRegions, regionGeometry.m_patchSingleMaterial); + generateExperimentalMeshDataForRegion(volume.getVolumeData(), *iterChangedRegions, regionGeometry.m_patchSingleMaterial); //genMultiFromSingle(regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial); @@ -39,7 +39,7 @@ namespace PolyVox return listChangedRegionGeometry; } - void generateRoughMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) + void generateExperimentalMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) { //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 @@ -47,6 +47,392 @@ namespace PolyVox regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); region.cropTo(regVolume); + //Offset from region corner + const Vector3DFloat offset = static_cast(region.getLowerCorner()); + + Vector3DFloat vertlist[12]; + uint8_t vertMaterials[12]; + BlockVolumeIterator volIter(*volumeData); + + //For edge indices + boost::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + boost::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + boost::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + memset(vertexIndicesX,0xFF,sizeof(vertexIndicesX)); //0xFF is -1 as two's complement - this may not be portable... + memset(vertexIndicesY,0xFF,sizeof(vertexIndicesY)); + memset(vertexIndicesZ,0xFF,sizeof(vertexIndicesZ)); + + std::vector vecTriangleIndices; + std::vector vecVertices; + + ////////////////////////////////////////////////////////////////////////// + //Get mesh data + ////////////////////////////////////////////////////////////////////////// + + //Iterate over each cell in the region + volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ()); + volIter.setValidRegion(region); + while(volIter.moveForwardInRegionXYZ()) + { + //Current position + const uint16_t x = volIter.getPosX() - offset.getX(); + const uint16_t y = volIter.getPosY() - offset.getY(); + const uint16_t z = volIter.getPosZ() - offset.getZ(); + + //Voxels values + const uint8_t v000 = volIter.getVoxel(); + const uint8_t v100 = volIter.peekVoxel1px0py0pz(); + const uint8_t v010 = volIter.peekVoxel0px1py0pz(); + const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + const uint8_t v001 = volIter.peekVoxel0px0py1pz(); + const uint8_t v101 = volIter.peekVoxel1px0py1pz(); + const uint8_t v011 = volIter.peekVoxel0px1py1pz(); + const uint8_t v111 = volIter.peekVoxel1px1py1pz(); + + //Determine the index into the edge table which tells us which vertices are inside of the surface + uint8_t iCubeIndex = 0; + + 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; + + /* Cube is entirely in/out of the surface */ + if (edgeTable[iCubeIndex] == 0) + { + continue; + } + + /* Find the vertices where the surface intersects the cube */ + if (edgeTable[iCubeIndex] & 1) + { + if((x + offset.getX()) != region.getUpperCorner().getX()) + { + vertlist[0].setX(x + 0.5f); + vertlist[0].setY(y); + vertlist[0].setZ(z); + vertMaterials[0] = v000 | v100; //Because one of these is 0, the or operation takes the max. + SurfaceVertex surfaceVertex(vertlist[0],vertMaterials[0], 1.0); + vecVertices.push_back(surfaceVertex); + vertexIndicesX[x][y][z] = vecVertices.size()-1; + } + } + /*if (edgeTable[iCubeIndex] & 2) + { + vertlist[1].setX(x + 1.0f); + vertlist[1].setY(y + 0.5f); + vertlist[1].setZ(z); + vertMaterials[1] = v100 | v110; + }*/ + /*if (edgeTable[iCubeIndex] & 4) + { + vertlist[2].setX(x + 0.5f); + vertlist[2].setY(y + 1.0f); + vertlist[2].setZ(z); + vertMaterials[2] = v010 | v110; + }*/ + if (edgeTable[iCubeIndex] & 8) + { + if((y + offset.getY()) != region.getUpperCorner().getY()) + { + vertlist[3].setX(x); + vertlist[3].setY(y + 0.5f); + vertlist[3].setZ(z); + vertMaterials[3] = v000 | v010; + SurfaceVertex surfaceVertex(vertlist[3],vertMaterials[3], 1.0); + vecVertices.push_back(surfaceVertex); + vertexIndicesY[x][y][z] = vecVertices.size()-1; + } + } + /*if (edgeTable[iCubeIndex] & 16) + { + vertlist[4].setX(x + 0.5f); + vertlist[4].setY(y); + vertlist[4].setZ(z + 1.0f); + vertMaterials[4] = v001 | v101; + }*/ + /*if (edgeTable[iCubeIndex] & 32) + { + vertlist[5].setX(x + 1.0f); + vertlist[5].setY(y + 0.5f); + vertlist[5].setZ(z + 1.0f); + vertMaterials[5] = v101 | v111; + }*/ + /*if (edgeTable[iCubeIndex] & 64) + { + vertlist[6].setX(x + 0.5f); + vertlist[6].setY(y + 1.0f); + vertlist[6].setZ(z + 1.0f); + vertMaterials[6] = v011 | v111; + }*/ + /*if (edgeTable[iCubeIndex] & 128) + { + vertlist[7].setX(x); + vertlist[7].setY(y + 0.5f); + vertlist[7].setZ(z + 1.0f); + vertMaterials[7] = v001 | v011; + }*/ + if (edgeTable[iCubeIndex] & 256) + { + if((z + offset.getZ()) != region.getUpperCorner().getZ()) + { + vertlist[8].setX(x); + vertlist[8].setY(y); + vertlist[8].setZ(z + 0.5f); + vertMaterials[8] = v000 | v001; + SurfaceVertex surfaceVertex(vertlist[8],vertMaterials[8], 1.0); + vecVertices.push_back(surfaceVertex); + vertexIndicesZ[x][y][z] = vecVertices.size()-1; + } + } + /*if (edgeTable[iCubeIndex] & 512) + { + vertlist[9].setX(x + 1.0f); + vertlist[9].setY(y); + vertlist[9].setZ(z + 0.5f); + vertMaterials[9] = v100 | v101; + }*/ + /*if (edgeTable[iCubeIndex] & 1024) + { + vertlist[10].setX(x + 1.0f); + vertlist[10].setY(y + 1.0f); + vertlist[10].setZ(z + 0.5f); + vertMaterials[10] = v110 | v111; + }*/ + /*if (edgeTable[iCubeIndex] & 2048) + { + vertlist[11].setX(x); + vertlist[11].setY(y + 1.0f); + vertlist[11].setZ(z + 0.5f); + vertMaterials[11] = v010 | v011; + }*/ + + /*for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) + { + //The three vertices forming a triangle + const Vector3DFloat vertex0 = vertlist[triTable[iCubeIndex][i ]] - offset; + const Vector3DFloat vertex1 = vertlist[triTable[iCubeIndex][i+1]] - offset; + const Vector3DFloat vertex2 = vertlist[triTable[iCubeIndex][i+2]] - offset; + + const uint8_t material0 = vertMaterials[triTable[iCubeIndex][i ]]; + const uint8_t material1 = vertMaterials[triTable[iCubeIndex][i+1]]; + const uint8_t material2 = vertMaterials[triTable[iCubeIndex][i+2]]; + + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1f,1.0f); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1f,1.0f); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material2 + 0.1f,1.0f); + singleMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); + }*///For each triangle + }//For each cell + + boost::uint32_t indlist[12]; + //Iterate over each cell in the region + region.setUpperCorner(region.getUpperCorner() - Vector3DInt32(1,1,1)); + volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ()); + volIter.setValidRegion(region); + while(volIter.moveForwardInRegionXYZ()) + { + //Current position + const uint16_t x = volIter.getPosX() - offset.getX(); + const uint16_t y = volIter.getPosY() - offset.getY(); + const uint16_t z = volIter.getPosZ() - offset.getZ(); + + //Voxels values + const uint8_t v000 = volIter.getVoxel(); + const uint8_t v100 = volIter.peekVoxel1px0py0pz(); + const uint8_t v010 = volIter.peekVoxel0px1py0pz(); + const uint8_t v110 = volIter.peekVoxel1px1py0pz(); + const uint8_t v001 = volIter.peekVoxel0px0py1pz(); + const uint8_t v101 = volIter.peekVoxel1px0py1pz(); + const uint8_t v011 = volIter.peekVoxel0px1py1pz(); + const uint8_t v111 = volIter.peekVoxel1px1py1pz(); + + //Determine the index into the edge table which tells us which vertices are inside of the surface + uint8_t iCubeIndex = 0; + + 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; + + /* Cube is entirely in/out of the surface */ + if (edgeTable[iCubeIndex] == 0) + { + continue; + } + + /* Find the vertices where the surface intersects the cube */ + if (edgeTable[iCubeIndex] & 1) + { + indlist[0] = vertexIndicesX[x][y][z]; + assert(indlist[0] != -1); + /*vertlist[0].setX(x + 0.5f); + vertlist[0].setY(y); + vertlist[0].setZ(z); + vertMaterials[0] = v000 | v100;*/ //Because one of these is 0, the or operation takes the max. + } + if (edgeTable[iCubeIndex] & 2) + { + indlist[1] = vertexIndicesY[x+1][y][z]; + assert(indlist[1] != -1); + /*vertlist[1].setX(x + 1.0f); + vertlist[1].setY(y + 0.5f); + vertlist[1].setZ(z); + vertMaterials[1] = v100 | v110;*/ + } + if (edgeTable[iCubeIndex] & 4) + { + indlist[2] = vertexIndicesX[x][y+1][z]; + assert(indlist[2] != -1); + /*vertlist[2].setX(x + 0.5f); + vertlist[2].setY(y + 1.0f); + vertlist[2].setZ(z); + vertMaterials[2] = v010 | v110;*/ + } + if (edgeTable[iCubeIndex] & 8) + { + indlist[3] = vertexIndicesY[x][y][z]; + assert(indlist[3] != -1); + /*vertlist[3].setX(x); + vertlist[3].setY(y + 0.5f); + vertlist[3].setZ(z); + vertMaterials[3] = v000 | v010;*/ + } + if (edgeTable[iCubeIndex] & 16) + { + indlist[4] = vertexIndicesX[x][y][z+1]; + assert(indlist[4] != -1); + /*vertlist[4].setX(x + 0.5f); + vertlist[4].setY(y); + vertlist[4].setZ(z + 1.0f); + vertMaterials[4] = v001 | v101;*/ + } + if (edgeTable[iCubeIndex] & 32) + { + indlist[5] = vertexIndicesY[x+1][y][z+1]; + assert(indlist[5] != -1); + /*vertlist[5].setX(x + 1.0f); + vertlist[5].setY(y + 0.5f); + vertlist[5].setZ(z + 1.0f); + vertMaterials[5] = v101 | v111;*/ + } + if (edgeTable[iCubeIndex] & 64) + { + indlist[6] = vertexIndicesX[x][y+1][z+1]; + assert(indlist[6] != -1); + /*vertlist[6].setX(x + 0.5f); + vertlist[6].setY(y + 1.0f); + vertlist[6].setZ(z + 1.0f); + vertMaterials[6] = v011 | v111;*/ + } + if (edgeTable[iCubeIndex] & 128) + { + indlist[7] = vertexIndicesY[x][y][z+1]; + assert(indlist[7] != -1); + /*vertlist[7].setX(x); + vertlist[7].setY(y + 0.5f); + vertlist[7].setZ(z + 1.0f); + vertMaterials[7] = v001 | v011;*/ + } + if (edgeTable[iCubeIndex] & 256) + { + indlist[8] = vertexIndicesZ[x][y][z]; + assert(indlist[8] != -1); + /*vertlist[8].setX(x); + vertlist[8].setY(y); + vertlist[8].setZ(z + 0.5f); + vertMaterials[8] = v000 | v001;*/ + } + if (edgeTable[iCubeIndex] & 512) + { + indlist[9] = vertexIndicesZ[x+1][y][z]; + assert(indlist[9] != -1); + /*vertlist[9].setX(x + 1.0f); + vertlist[9].setY(y); + vertlist[9].setZ(z + 0.5f); + vertMaterials[9] = v100 | v101;*/ + } + if (edgeTable[iCubeIndex] & 1024) + { + indlist[10] = vertexIndicesZ[x+1][y+1][z]; + assert(indlist[10] != -1); + /*vertlist[10].setX(x + 1.0f); + vertlist[10].setY(y + 1.0f); + vertlist[10].setZ(z + 0.5f); + vertMaterials[10] = v110 | v111;*/ + } + if (edgeTable[iCubeIndex] & 2048) + { + indlist[11] = vertexIndicesZ[x][y+1][z]; + assert(indlist[11] != -1); + /*vertlist[11].setX(x); + vertlist[11].setY(y + 1.0f); + vertlist[11].setZ(z + 0.5f); + vertMaterials[11] = v010 | v011;*/ + } + + for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) + { + boost::uint32_t ind0 = indlist[triTable[iCubeIndex][i ]]; + boost::uint32_t ind1 = indlist[triTable[iCubeIndex][i+1]]; + boost::uint32_t ind2 = indlist[triTable[iCubeIndex][i+2]]; + + vecTriangleIndices.push_back(ind0); + vecTriangleIndices.push_back(ind1); + vecTriangleIndices.push_back(ind2); + + //The three vertices forming a triangle + /*const Vector3DFloat vertex0 = vertlist[triTable[iCubeIndex][i ]] - offset; + const Vector3DFloat vertex1 = vertlist[triTable[iCubeIndex][i+1]] - offset; + const Vector3DFloat vertex2 = vertlist[triTable[iCubeIndex][i+2]] - offset; + + const uint8_t material0 = vertMaterials[triTable[iCubeIndex][i ]]; + const uint8_t material1 = vertMaterials[triTable[iCubeIndex][i+1]]; + const uint8_t material2 = vertMaterials[triTable[iCubeIndex][i+2]]; + + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1f,1.0f); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1f,1.0f); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material2 + 0.1f,1.0f); + singleMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1);*/ + }//For each triangle + }//For each cell + + //FIXME - can it happen that we have no vertices or triangles? Should exit early? + + singleMaterialPatch->m_vecVertices = vecVertices; + singleMaterialPatch->m_vecTriangleIndices = vecTriangleIndices; + + + //for(std::map::iterator iterPatch = surfacePatchMapResult.begin(); iterPatch != surfacePatchMapResult.end(); ++iterPatch) + { + + std::vector::iterator iterSurfaceVertex = singleMaterialPatch->getVertices().begin(); + while(iterSurfaceVertex != singleMaterialPatch->getVertices().end()) + { + Vector3DFloat tempNormal = computeNormal(volumeData, static_cast(iterSurfaceVertex->getPosition() + offset), CENTRAL_DIFFERENCE); + const_cast(*iterSurfaceVertex).setNormal(tempNormal); + ++iterSurfaceVertex; + } + } + } + + void generateRoughMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) + { + //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 + Region regVolume = volumeData->getEnclosingRegion(); + //regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); + region.cropTo(regVolume); + region.setUpperCorner(region.getUpperCorner() - Vector3DInt32(1,1,1)); + //Offset from lower block corner const Vector3DFloat offset = static_cast(region.getLowerCorner()); @@ -60,7 +446,8 @@ namespace PolyVox ////////////////////////////////////////////////////////////////////////// //Iterate over each cell in the region - for(volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ());volIter.isValidForRegion();volIter.moveForwardInRegion()) + volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ()); + while(volIter.moveForwardInRegionXYZ()) { //Current position const uint16_t x = volIter.getPosX(); @@ -339,7 +726,7 @@ namespace PolyVox ////////////////////////////////////////////////////////////////////////// //Iterate over each cell in the region - for(volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ());volIter.isValidForRegion();volIter.moveForwardInRegion()) + for(volIter.setPosition(region.getLowerCorner().getX(),region.getLowerCorner().getY(), region.getLowerCorner().getZ());volIter.isValidForRegion();volIter.moveForwardInRegionXYZ()) { //Current position const uint16_t x = volIter.getPosX(); diff --git a/source/VolumeChangeTracker.cpp b/source/VolumeChangeTracker.cpp index 88676498..6b933d15 100644 --- a/source/VolumeChangeTracker.cpp +++ b/source/VolumeChangeTracker.cpp @@ -65,22 +65,22 @@ namespace PolyVox //Regenerate meshes. for(uint16_t regionZ = 0; regionZ < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionZ) - //for(uint16_t regionZ = 6; regionZ < 7; ++regionZ) + //for(uint16_t regionZ = 0; regionZ < 1; ++regionZ) { for(uint16_t regionY = 0; regionY < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionY) - //for(uint16_t regionY = 6; regionY < 7; ++regionY) + //for(uint16_t regionY = 0; regionY < 2; ++regionY) { for(uint16_t regionX = 0; regionX < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++regionX) - //for(uint16_t regionX = 3; regionX < 4; ++regionX) + //for(uint16_t regionX = 0; regionX < 2; ++regionX) { if(volRegionUpToDate->getVoxelAt(regionX, regionY, regionZ) == false) { const uint16_t firstX = regionX * POLYVOX_REGION_SIDE_LENGTH; const uint16_t firstY = regionY * POLYVOX_REGION_SIDE_LENGTH; const uint16_t firstZ = regionZ * POLYVOX_REGION_SIDE_LENGTH; - const uint16_t lastX = firstX + POLYVOX_REGION_SIDE_LENGTH-1; - const uint16_t lastY = firstY + POLYVOX_REGION_SIDE_LENGTH-1; - const uint16_t lastZ = firstZ + POLYVOX_REGION_SIDE_LENGTH-1; + const uint16_t lastX = firstX + POLYVOX_REGION_SIDE_LENGTH; + const uint16_t lastY = firstY + POLYVOX_REGION_SIDE_LENGTH; + const uint16_t lastZ = firstZ + POLYVOX_REGION_SIDE_LENGTH; listToFill.push_back(Region(Vector3DInt32(firstX, firstY, firstZ), Vector3DInt32(lastX, lastY, lastZ))); }