diff --git a/include/BlockVolume.h b/include/BlockVolume.h index 27033530..212780dd 100644 --- a/include/BlockVolume.h +++ b/include/BlockVolume.h @@ -45,6 +45,7 @@ namespace PolyVox BlockVolume& operator=(const BlockVolume& rhs); + Region getEnclosingRegion(void); boost::uint16_t getSideLength(void) const; VoxelType getVoxelAt(boost::uint16_t uXPos, boost::uint16_t uYPos, boost::uint16_t uZPos) const; VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const; diff --git a/include/BlockVolume.inl b/include/BlockVolume.inl index 28226b8d..b8f38c16 100644 --- a/include/BlockVolume.inl +++ b/include/BlockVolume.inl @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma region Headers #include "Block.h" +#include "Region.h" #include "Vector.h" #include @@ -119,6 +120,12 @@ namespace PolyVox #pragma endregion #pragma region Getters + template + Region BlockVolume::getEnclosingRegion(void) + { + return Region(Vector3DInt32(0,0,0), Vector3DInt32(m_uSideLength-1,m_uSideLength-1,m_uSideLength-1)); + } + template boost::uint16_t BlockVolume::getSideLength(void) const { diff --git a/include/Region.h b/include/Region.h index 6f391172..53b30cde 100644 --- a/include/Region.h +++ b/include/Region.h @@ -42,6 +42,7 @@ namespace PolyVox bool containsPoint(const Vector3DFloat& pos, float boundary) const; bool containsPoint(const Vector3DInt32& pos, boost::uint8_t boundary) const; + void cropTo(const Region& other); private: Vector3DInt32 m_v3dLowerCorner; diff --git a/include/SurfaceExtractors.h b/include/SurfaceExtractors.h index 251ce977..f8debade 100644 --- a/include/SurfaceExtractors.h +++ b/include/SurfaceExtractors.h @@ -30,10 +30,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. namespace PolyVox { - void generateRoughMeshDataForRegion(BlockVolume* volumeData, boost::uint16_t regionX, boost::uint16_t regionY, boost::uint16_t regionZ, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch); + void generateRoughMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch); Vector3DFloat computeNormal(BlockVolume* volumeData, const Vector3DFloat& position, NormalGenerationMethod normalGenerationMethod); - void generateSmoothMeshDataForRegion(BlockVolume* volumeData, boost::uint16_t regionX, boost::uint16_t regionY, boost::uint16_t regionZ, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch); + void generateSmoothMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch); Vector3DFloat computeSmoothNormal(BlockVolume* volumeData, const Vector3DFloat& position, NormalGenerationMethod normalGenerationMethod); } diff --git a/include/VolumeIterator.h b/include/VolumeIterator.h index e7dbc3b5..2e775ee8 100644 --- a/include/VolumeIterator.h +++ b/include/VolumeIterator.h @@ -50,7 +50,7 @@ namespace PolyVox VoxelType getVoxel(void) const; 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(const Region& region); void setVoxel(VoxelType tValue); bool isValidForRegion(void) const; diff --git a/include/VolumeIterator.inl b/include/VolumeIterator.inl index 956febb6..661742ca 100644 --- a/include/VolumeIterator.inl +++ b/include/VolumeIterator.inl @@ -190,15 +190,15 @@ namespace PolyVox } template - void VolumeIterator::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 VolumeIterator::setValidRegion(const Region& region) { - mXRegionFirst = xFirst; - mYRegionFirst = yFirst; - mZRegionFirst = zFirst; + mXRegionFirst = region.getLowerCorner().x(); + mYRegionFirst = region.getLowerCorner().y(); + mZRegionFirst = region.getLowerCorner().z(); - mXRegionLast = xLast; - mYRegionLast = yLast; - mZRegionLast = zLast; + mXRegionLast = region.getUpperCorner().x(); + mYRegionLast = region.getUpperCorner().y(); + mZRegionLast = region.getUpperCorner().z(); mXRegionFirstBlock = mXRegionFirst >> mVolume.m_uBlockSideLengthPower; mYRegionFirstBlock = mYRegionFirst >> mVolume.m_uBlockSideLengthPower; diff --git a/source/Region.cpp b/source/Region.cpp index a44f6762..a0d1072b 100644 --- a/source/Region.cpp +++ b/source/Region.cpp @@ -53,4 +53,14 @@ namespace PolyVox && (pos.y() >= m_v3dLowerCorner.y() + boundary) && (pos.z() >= m_v3dLowerCorner.z() + boundary); } + + void Region::cropTo(const Region& other) + { + m_v3dLowerCorner.setX((std::max)(m_v3dLowerCorner.x(), other.m_v3dLowerCorner.x())); + m_v3dLowerCorner.setY((std::max)(m_v3dLowerCorner.y(), other.m_v3dLowerCorner.y())); + m_v3dLowerCorner.setZ((std::max)(m_v3dLowerCorner.z(), other.m_v3dLowerCorner.z())); + m_v3dUpperCorner.setX((std::min)(m_v3dUpperCorner.x(), other.m_v3dUpperCorner.x())); + m_v3dUpperCorner.setY((std::min)(m_v3dUpperCorner.y(), other.m_v3dUpperCorner.y())); + m_v3dUpperCorner.setZ((std::min)(m_v3dUpperCorner.z(), other.m_v3dUpperCorner.z())); + } } \ No newline at end of file diff --git a/source/SurfaceExtractors.cpp b/source/SurfaceExtractors.cpp index e4b0ebe3..46be9d1f 100644 --- a/source/SurfaceExtractors.cpp +++ b/source/SurfaceExtractors.cpp @@ -4,36 +4,51 @@ #include "GradientEstimators.h" #include "IndexedSurfacePatch.h" #include "MarchingCubesTables.h" +#include "Region.h" #include "VolumeIterator.h" using namespace boost; namespace PolyVox { - void generateRoughMeshDataForRegion(BlockVolume* volumeData, uint16_t regionX, uint16_t regionY, uint16_t regionZ, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch) + void generateRoughMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch) { //First and last voxels in the region - 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 = (std::min)(firstX + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); - const uint16_t lastY = (std::min)(firstY + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); - const uint16_t lastZ = (std::min)(firstZ + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //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 = (std::min)(firstX + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //const uint16_t lastY = (std::min)(firstY + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //const uint16_t lastZ = (std::min)(firstZ + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + + //We don't go right to the edge + Region regVolume = volumeData->getEnclosingRegion(); + regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); + region.cropTo(regVolume); + + //const uint16_t firstX = (uint16_t)region.getLowerCorner().x(); + //const uint16_t firstY = (uint16_t)region.getLowerCorner().y(); + //const uint16_t firstZ = (uint16_t)region.getLowerCorner().z(); + //FIXME - for this next step, define some operation to crop one region to another. We can then crop to the volume + //const uint16_t lastX = static_cast(region.getUpperCorner().x()); + //const uint16_t lastY = static_cast(region.getUpperCorner().y()); + //const uint16_t lastZ = static_cast(region.getUpperCorner().z()); + //Offset from lower block corner - const Vector3DFloat offset(firstX,firstY,firstZ); + const Vector3DFloat offset(region.getLowerCorner()); Vector3DFloat vertlist[12]; uint8_t vertMaterials[12]; VolumeIterator volIter(*volumeData); - volIter.setValidRegion(firstX,firstY,firstZ,lastX,lastY,lastZ); + volIter.setValidRegion(region); ////////////////////////////////////////////////////////////////////////// //Get mesh data ////////////////////////////////////////////////////////////////////////// //Iterate over each cell in the region - for(volIter.setPosition(firstX,firstY,firstZ);volIter.isValidForRegion();volIter.moveForwardInRegion()) + for(volIter.setPosition(region.getLowerCorner().x(),region.getLowerCorner().y(),region.getLowerCorner().z());volIter.isValidForRegion();volIter.moveForwardInRegion()) { //Current position const uint16_t x = volIter.getPosX(); @@ -410,23 +425,36 @@ namespace PolyVox return result; } - void generateSmoothMeshDataForRegion(BlockVolume* volumeData, uint16_t regionX, uint16_t regionY, uint16_t regionZ, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch) + void generateSmoothMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch) { //First and last voxels in the region - 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 = (std::min)(firstX + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); - const uint16_t lastY = (std::min)(firstY + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); - const uint16_t lastZ = (std::min)(firstZ + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //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 = (std::min)(firstX + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //const uint16_t lastY = (std::min)(firstY + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + //const uint16_t lastZ = (std::min)(firstZ + POLYVOX_REGION_SIDE_LENGTH-1,volumeData->getSideLength()-2); + + //We don't go right to the edge + Region regVolume = volumeData->getEnclosingRegion(); + regVolume.setUpperCorner(regVolume.getUpperCorner() - Vector3DInt32(1,1,1)); + region.cropTo(regVolume); + + //const uint16_t firstX = (uint16_t)region.getLowerCorner().x(); + //const uint16_t firstY = (uint16_t)region.getLowerCorner().y(); + //const uint16_t firstZ = (uint16_t)region.getLowerCorner().z(); + //FIXME - for this next step, define some operation to crop one region to another. We can then crop to the volume + //const uint16_t lastX = static_cast(region.getUpperCorner().x()); + //const uint16_t lastY = static_cast(region.getUpperCorner().y()); + //const uint16_t lastZ = static_cast(region.getUpperCorner().z()); //Offset from lower block corner - const Vector3DFloat offset(firstX,firstY,firstZ); + const Vector3DFloat offset(region.getLowerCorner()); Vector3DFloat vertlist[12]; uint8_t vertMaterials[12]; VolumeIterator volIter(*volumeData); - volIter.setValidRegion(firstX,firstY,firstZ,lastX,lastY,lastZ); + volIter.setValidRegion(region); const float threshold = 0.5f; @@ -435,7 +463,7 @@ namespace PolyVox ////////////////////////////////////////////////////////////////////////// //Iterate over each cell in the region - for(volIter.setPosition(firstX,firstY,firstZ);volIter.isValidForRegion();volIter.moveForwardInRegion()) + for(volIter.setPosition(region.getLowerCorner().x(),region.getLowerCorner().y(),region.getLowerCorner().z());volIter.isValidForRegion();volIter.moveForwardInRegion()) { //Current position const uint16_t x = volIter.getPosX(); diff --git a/source/VolumeChangeTracker.cpp b/source/VolumeChangeTracker.cpp index 849163bd..7b572ed3 100644 --- a/source/VolumeChangeTracker.cpp +++ b/source/VolumeChangeTracker.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "LinearVolume.h" #include "MarchingCubesTables.h" #include "VolumeChangeTracker.h" +#include "Region.h" #include "RegionGeometry.h" #include "SurfaceExtractors.h" #include "SurfaceVertex.h" @@ -83,7 +84,16 @@ namespace PolyVox regionGeometry.m_patchMultiMaterial = new IndexedSurfacePatch(true); regionGeometry.m_v3dRegionPosition = Vector3DInt32(regionX, regionY, regionZ); - generateRoughMeshDataForRegion(volumeData, regionX,regionY,regionZ, regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial); + 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; + + Region region(Vector3DInt32(firstX,firstY,firstZ),Vector3DInt32(lastX,lastY,lastZ)); + + generateRoughMeshDataForRegion(volumeData, region, regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial); regionGeometry.m_bContainsSingleMaterialPatch = regionGeometry.m_patchSingleMaterial->getVertices().size() > 0; regionGeometry.m_bContainsMultiMaterialPatch = regionGeometry.m_patchMultiMaterial->getVertices().size() > 0; @@ -135,7 +145,7 @@ namespace PolyVox lastZ = std::min(lastZ,int(volumeData->getSideLength()-1)); VolumeIterator volIter(*volumeData); - volIter.setValidRegion(firstX,firstY,firstZ,lastX,lastY,lastZ); + volIter.setValidRegion(Region(Vector3DInt32(firstX,firstY,firstZ),Vector3DInt32(lastX,lastY,lastZ))); volIter.setPosition(firstX,firstY,firstZ); while(volIter.isValidForRegion()) {