diff --git a/include/SurfaceExtractors.h b/include/SurfaceExtractors.h index ead8f2cc..f8debade 100644 --- a/include/SurfaceExtractors.h +++ b/include/SurfaceExtractors.h @@ -33,7 +33,7 @@ namespace PolyVox 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..8a74ca65 100644 --- a/include/VolumeIterator.h +++ b/include/VolumeIterator.h @@ -50,6 +50,7 @@ namespace PolyVox VoxelType getVoxel(void) const; void setPosition(boost::uint16_t xPos, boost::uint16_t yPos, boost::uint16_t zPos); + void setValidRegion(const Region& region); 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 setVoxel(VoxelType tValue); diff --git a/include/VolumeIterator.inl b/include/VolumeIterator.inl index 956febb6..7f174c14 100644 --- a/include/VolumeIterator.inl +++ b/include/VolumeIterator.inl @@ -189,6 +189,12 @@ namespace PolyVox mCurrentVoxel = currentBlock->m_tData + mVoxelIndexInBlock; } + template + void VolumeIterator::setValidRegion(const Region& region) + { + setValidRegion(region.getLowerCorner().x(),region.getLowerCorner().y(),region.getLowerCorner().z(),region.getUpperCorner().x(),region.getUpperCorner().y(),region.getUpperCorner().z()); + } + 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) { diff --git a/source/SurfaceExtractors.cpp b/source/SurfaceExtractors.cpp index 22adcc72..b01d553c 100644 --- a/source/SurfaceExtractors.cpp +++ b/source/SurfaceExtractors.cpp @@ -19,27 +19,20 @@ namespace PolyVox 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); + const Vector3DFloat offset = static_cast(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(); @@ -416,23 +409,21 @@ 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); + //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); //Offset from lower block corner - const Vector3DFloat offset(firstX,firstY,firstZ); + const Vector3DFloat offset = static_cast(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; @@ -441,7 +432,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();