diff --git a/include/SurfaceExtractors.h b/include/SurfaceExtractors.h index 251ce977..ead8f2cc 100644 --- a/include/SurfaceExtractors.h +++ b/include/SurfaceExtractors.h @@ -30,7 +30,7 @@ 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); diff --git a/source/SurfaceExtractors.cpp b/source/SurfaceExtractors.cpp index e4b0ebe3..22adcc72 100644 --- a/source/SurfaceExtractors.cpp +++ b/source/SurfaceExtractors.cpp @@ -4,21 +4,27 @@ #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); + //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); + + const uint16_t firstX = region.getLowerCorner().x(); + const uint16_t firstY = region.getLowerCorner().y(); + const uint16_t firstZ = region.getLowerCorner().z(); + const uint16_t lastX = region.getUpperCorner().x(); + const uint16_t lastY = region.getUpperCorner().y(); + const uint16_t lastZ = region.getUpperCorner().z(); //Offset from lower block corner const Vector3DFloat offset(firstX,firstY,firstZ); diff --git a/source/VolumeChangeTracker.cpp b/source/VolumeChangeTracker.cpp index 849163bd..f5f164a8 100644 --- a/source/VolumeChangeTracker.cpp +++ b/source/VolumeChangeTracker.cpp @@ -83,7 +83,14 @@ 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; + + generateRoughMeshDataForRegion(volumeData, Region(Vector3DInt32(firstX, firstY, firstZ), Vector3DInt32(lastX, lastY, lastZ)), regionGeometry.m_patchSingleMaterial, regionGeometry.m_patchMultiMaterial); regionGeometry.m_bContainsSingleMaterialPatch = regionGeometry.m_patchSingleMaterial->getVertices().size() > 0; regionGeometry.m_bContainsMultiMaterialPatch = regionGeometry.m_patchMultiMaterial->getVertices().size() > 0;