00001 /******************************************************************************* 00002 Copyright (c) 2005-2009 David Williams 00003 00004 This software is provided 'as-is', without any express or implied 00005 warranty. In no event will the authors be held liable for any damages 00006 arising from the use of this software. 00007 00008 Permission is granted to anyone to use this software for any purpose, 00009 including commercial applications, and to alter it and redistribute it 00010 freely, subject to the following restrictions: 00011 00012 1. The origin of this software must not be misrepresented; you must not 00013 claim that you wrote the original software. If you use this software 00014 in a product, an acknowledgment in the product documentation would be 00015 appreciated but is not required. 00016 00017 2. Altered source versions must be plainly marked as such, and must not be 00018 misrepresented as being the original software. 00019 00020 3. This notice may not be removed or altered from any source 00021 distribution. 00022 *******************************************************************************/ 00023 00024 #include "PolyVoxImpl/TypeDef.h" 00025 00026 #include "PolyVoxCore/GradientEstimators.h" 00027 00028 using namespace std; 00029 00030 namespace PolyVox 00031 { 00032 /*void computeNormalsForVertices(LargeVolume<uint8_t>* volumeData, SurfaceMesh<PositionMaterialNormal>& mesh, NormalGenerationMethod normalGenerationMethod) 00033 { 00034 std::vector<PositionMaterialNormal>& vecVertices = mesh.getRawVertexData(); 00035 std::vector<PositionMaterialNormal>::iterator iterSurfaceVertex = vecVertices.begin(); 00036 while(iterSurfaceVertex != vecVertices.end()) 00037 { 00038 const Vector3DFloat& v3dPos = iterSurfaceVertex->getPosition() + static_cast<Vector3DFloat>(mesh.m_Region.getLowerCorner()); 00039 const Vector3DInt32 v3dFloor = static_cast<Vector3DInt32>(v3dPos); 00040 00041 LargeVolume<uint8_t>::Sampler volIter(volumeData); 00042 00043 //Check all corners are within the volume, allowing a boundary for gradient estimation 00044 bool lowerCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor,2); 00045 bool upperCornerInside = volumeData->getEnclosingRegion().containsPoint(v3dFloor+Vector3DInt32(1,1,1),2); 00046 00047 if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was 00048 { 00049 Vector3DFloat v3dGradient = computeNormal(volumeData, v3dPos, normalGenerationMethod); 00050 00051 if(v3dGradient.lengthSquared() > 0.0001) 00052 { 00053 //If we got a normal of significant length then update it. 00054 //Otherwise leave it as it was (should be the 'simple' version) 00055 v3dGradient.normalise(); 00056 iterSurfaceVertex->setNormal(v3dGradient); 00057 } 00058 } //(lowerCornerInside && upperCornerInside) 00059 ++iterSurfaceVertex; 00060 } 00061 }*/ 00062 00063 /*Vector3DFloat computeNormal(LargeVolume<uint8_t>* volumeData, const Vector3DFloat& v3dPos, NormalGenerationMethod normalGenerationMethod) 00064 { 00065 Vector3DFloat v3dGradient; //To store the result 00066 00067 LargeVolume<uint8_t>::Sampler volIter(volumeData); 00068 00069 const Vector3DInt32 v3dFloor = static_cast<Vector3DInt32>(v3dPos); 00070 00071 volIter.setPosition(static_cast<Vector3DInt32>(v3dFloor)); 00072 Vector3DFloat gradFloor; 00073 switch(normalGenerationMethod) 00074 { 00075 case SOBEL_SMOOTHED: 00076 gradFloor = computeSmoothSobelGradient<uint8_t>(volIter); 00077 break; 00078 case CENTRAL_DIFFERENCE_SMOOTHED: 00079 gradFloor = computeSmoothCentralDifferenceGradient<uint8_t>(volIter); 00080 break; 00081 case SOBEL: 00082 gradFloor = computeSobelGradient<uint8_t>(volIter); 00083 break; 00084 case CENTRAL_DIFFERENCE: 00085 gradFloor = computeCentralDifferenceGradient<uint8_t>(volIter); 00086 break; 00087 } 00088 00089 if((v3dPos.getX() - v3dFloor.getX()) > 0.25) //The result should be 0.0 or 0.5 00090 { 00091 volIter.setPosition(static_cast<Vector3DInt32>(v3dFloor+Vector3DInt32(1,0,0))); 00092 } 00093 if((v3dPos.getY() - v3dFloor.getY()) > 0.25) //The result should be 0.0 or 0.5 00094 { 00095 volIter.setPosition(static_cast<Vector3DInt32>(v3dFloor+Vector3DInt32(0,1,0))); 00096 } 00097 if((v3dPos.getZ() - v3dFloor.getZ()) > 0.25) //The result should be 0.0 or 0.5 00098 { 00099 volIter.setPosition(static_cast<Vector3DInt32>(v3dFloor+Vector3DInt32(0,0,1))); 00100 } 00101 00102 Vector3DFloat gradCeil; 00103 switch(normalGenerationMethod) 00104 { 00105 case SOBEL_SMOOTHED: 00106 gradCeil = computeSmoothSobelGradient<uint8_t>(volIter); 00107 break; 00108 case CENTRAL_DIFFERENCE_SMOOTHED: 00109 gradCeil = computeSmoothCentralDifferenceGradient<uint8_t>(volIter); 00110 break; 00111 case SOBEL: 00112 gradCeil = computeSobelGradient<uint8_t>(volIter); 00113 break; 00114 case CENTRAL_DIFFERENCE: 00115 gradCeil = computeCentralDifferenceGradient<uint8_t>(volIter); 00116 break; 00117 } 00118 00119 v3dGradient = (gradFloor + gradCeil); 00120 if(v3dGradient.lengthSquared() < 0.0001) 00121 { 00122 //Operation failed - fall back on simple gradient estimation 00123 normalGenerationMethod = SIMPLE; 00124 } 00125 00126 if(normalGenerationMethod == SIMPLE) 00127 { 00128 volIter.setPosition(static_cast<Vector3DInt32>(v3dFloor)); 00129 const uint8_t uFloor = volIter.getVoxel() > 0 ? 1 : 0; 00130 if((v3dPos.getX() - v3dFloor.getX()) > 0.25) //The result should be 0.0 or 0.5 00131 { 00132 uint8_t uCeil = volIter.peekVoxel1px0py0pz() > 0 ? 1 : 0; 00133 v3dGradient = Vector3DFloat(static_cast<float>(uFloor - uCeil),0.0,0.0); 00134 } 00135 else if((v3dPos.getY() - v3dFloor.getY()) > 0.25) //The result should be 0.0 or 0.5 00136 { 00137 uint8_t uCeil = volIter.peekVoxel0px1py0pz() > 0 ? 1 : 0; 00138 v3dGradient = Vector3DFloat(0.0,static_cast<float>(uFloor - uCeil),0.0); 00139 } 00140 else if((v3dPos.getZ() - v3dFloor.getZ()) > 0.25) //The result should be 0.0 or 0.5 00141 { 00142 uint8_t uCeil = volIter.peekVoxel0px0py1pz() > 0 ? 1 : 0; 00143 v3dGradient = Vector3DFloat(0.0, 0.0,static_cast<float>(uFloor - uCeil)); 00144 } 00145 } 00146 return v3dGradient; 00147 }*/ 00148 }