From a2c984408da4c7cf075b6d11cf792a539cb2d564 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 6 Oct 2007 00:52:43 +0000 Subject: [PATCH] Fixed problem with computeNormal() sometimes returning zero length. --- source/PolyVoxSceneManager.cpp | 121 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/source/PolyVoxSceneManager.cpp b/source/PolyVoxSceneManager.cpp index c5151332..230e8791 100644 --- a/source/PolyVoxSceneManager.cpp +++ b/source/PolyVoxSceneManager.cpp @@ -702,68 +702,73 @@ namespace Ogre Vector3 result; - switch(normalGenerationMethod) + + if(normalGenerationMethod == SOBEL) { - case SOBEL: - { - volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); - const Vector3 gradFloor = volIter.getSobelGradient(); - if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX+1.0),static_cast(posY),static_cast(posZ)); - } - if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX),static_cast(posY+1.0),static_cast(posZ)); - } - if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ+1.0)); - } - const Vector3 gradCeil = volIter.getSobelGradient(); - result = ((gradFloor + gradCeil) * -1.0); - break; + volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); + const Vector3 gradFloor = volIter.getSobelGradient(); + if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX+1.0),static_cast(posY),static_cast(posZ)); } - case CENTRAL_DIFFERENCE: - { - volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); - const Vector3 gradFloor = volIter.getCentralDifferenceGradient(); - if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX+1.0),static_cast(posY),static_cast(posZ)); - } - if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX),static_cast(posY+1.0),static_cast(posZ)); - } - if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 - { - volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ+1.0)); - } - const Vector3 gradCeil = volIter.getCentralDifferenceGradient(); - result = ((gradFloor + gradCeil) * -1.0); - break; + if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX),static_cast(posY+1.0),static_cast(posZ)); } - case SIMPLE: - default: + if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ+1.0)); + } + const Vector3 gradCeil = volIter.getSobelGradient(); + result = ((gradFloor + gradCeil) * -1.0); + if(result.squaredLength() < 0.0001) { - volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); - const uchar uFloor = volIter.getVoxel() > 0 ? 1 : 0; - if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 - { - uchar uCeil = volIter.peekVoxel1px0py0pz() > 0 ? 1 : 0; - result = Vector3(uFloor - uCeil,0.0,0.0); - } - else if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 - { - uchar uCeil = volIter.peekVoxel0px1py0pz() > 0 ? 1 : 0; - result = Vector3(0.0,uFloor - uCeil,0.0); - } - else if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 - { - uchar uCeil = volIter.peekVoxel0px0py1pz() > 0 ? 1 : 0; - result = Vector3(0.0, 0.0,uFloor - uCeil); - } + //Operation failed - fall back on simple gradient estimation + normalGenerationMethod = SIMPLE; + } + } + if(normalGenerationMethod == CENTRAL_DIFFERENCE) + { + volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); + const Vector3 gradFloor = volIter.getCentralDifferenceGradient(); + if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX+1.0),static_cast(posY),static_cast(posZ)); + } + if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX),static_cast(posY+1.0),static_cast(posZ)); + } + if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 + { + volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ+1.0)); + } + const Vector3 gradCeil = volIter.getCentralDifferenceGradient(); + result = ((gradFloor + gradCeil) * -1.0); + if(result.squaredLength() < 0.0001) + { + //Operation failed - fall back on simple gradient estimation + normalGenerationMethod = SIMPLE; + } + } + if(normalGenerationMethod == SIMPLE) + { + volIter.setPosition(static_cast(posX),static_cast(posY),static_cast(posZ)); + const uchar uFloor = volIter.getVoxel() > 0 ? 1 : 0; + if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5 + { + uchar uCeil = volIter.peekVoxel1px0py0pz() > 0 ? 1 : 0; + result = Vector3(uFloor - uCeil,0.0,0.0); + } + else if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5 + { + uchar uCeil = volIter.peekVoxel0px1py0pz() > 0 ? 1 : 0; + result = Vector3(0.0,uFloor - uCeil,0.0); + } + else if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5 + { + uchar uCeil = volIter.peekVoxel0px0py1pz() > 0 ? 1 : 0; + result = Vector3(0.0, 0.0,uFloor - uCeil); } } return result;