Work on gradient estimators. Added CENTRAL_DIFFERENCE_SMOOTHED and SOBEL_SMOOTHED.
This commit is contained in:
parent
34c41cd32e
commit
31c0b24a27
@ -26,9 +26,11 @@ namespace PolyVox
|
||||
{
|
||||
enum NormalGenerationMethod
|
||||
{
|
||||
SIMPLE,
|
||||
SIMPLE, //Fastest
|
||||
CENTRAL_DIFFERENCE,
|
||||
SOBEL
|
||||
SOBEL,
|
||||
CENTRAL_DIFFERENCE_SMOOTHED,
|
||||
SOBEL_SMOOTHED //Smoothest
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,11 @@ namespace PolyVox
|
||||
|
||||
template <typename VoxelType>
|
||||
Vector3DFloat computeSobelGradient(const BlockVolumeIterator<VoxelType>& volIter);
|
||||
template <typename VoxelType>
|
||||
Vector3DFloat computeSmoothSobelGradient(BlockVolumeIterator<VoxelType>& volIter);
|
||||
|
||||
POLYVOX_API void computeNormalsForVertices(BlockVolume<uint8>* volumeData, IndexedSurfacePatch& isp, NormalGenerationMethod normalGenerationMethod);
|
||||
POLYVOX_API Vector3DFloat computeNormal(BlockVolume<uint8>* volumeData, const Vector3DFloat& position, NormalGenerationMethod normalGenerationMethod);
|
||||
POLYVOX_API Vector3DFloat computeNormal(BlockVolume<uint8>* volumeData, const Vector3DFloat& v3dPos, NormalGenerationMethod normalGenerationMethod);
|
||||
}
|
||||
|
||||
#include "GradientEstimators.inl"
|
||||
|
@ -182,4 +182,121 @@ namespace PolyVox
|
||||
//For our normals we want the the other way around, so we switch the components as we return them.
|
||||
return Vector3DFloat(static_cast<float>(-xGrad),static_cast<float>(-yGrad),static_cast<float>(-zGrad));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
Vector3DFloat computeSmoothSobelGradient(BlockVolumeIterator<VoxelType>& volIter)
|
||||
{
|
||||
static const int weights[3][3][3] = { { {2,3,2}, {3,6,3}, {2,3,2} }, {
|
||||
{3,6,3}, {6,0,6}, {3,6,3} }, { {2,3,2}, {3,6,3}, {2,3,2} } };
|
||||
|
||||
uint16 initialX = volIter.getPosX();
|
||||
uint16 initialY = volIter.getPosY();
|
||||
uint16 initialZ = volIter.getPosZ();
|
||||
|
||||
volIter.setPosition(initialX-1, initialY-1, initialZ-1); const float pVoxel1nx1ny1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY-1, initialZ ); const float pVoxel1nx1ny0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY-1, initialZ+1); const float pVoxel1nx1ny1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY , initialZ-1); const float pVoxel1nx0py1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY , initialZ ); const float pVoxel1nx0py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY , initialZ+1); const float pVoxel1nx0py1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY+1, initialZ-1); const float pVoxel1nx1py1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY+1, initialZ ); const float pVoxel1nx1py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX-1, initialY+1, initialZ+1); const float pVoxel1nx1py1pz = computeSmoothedVoxel(volIter);
|
||||
|
||||
volIter.setPosition(initialX , initialY-1, initialZ-1); const float pVoxel0px1ny1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY-1, initialZ ); const float pVoxel0px1ny0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY-1, initialZ+1); const float pVoxel0px1ny1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY , initialZ-1); const float pVoxel0px0py1nz = computeSmoothedVoxel(volIter);
|
||||
//volIter.setPosition(initialX , initialY , initialZ ); const float pVoxel0px0py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY , initialZ+1); const float pVoxel0px0py1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY+1, initialZ-1); const float pVoxel0px1py1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY+1, initialZ ); const float pVoxel0px1py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX , initialY+1, initialZ+1); const float pVoxel0px1py1pz = computeSmoothedVoxel(volIter);
|
||||
|
||||
volIter.setPosition(initialX+1, initialY-1, initialZ-1); const float pVoxel1px1ny1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY-1, initialZ ); const float pVoxel1px1ny0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY-1, initialZ+1); const float pVoxel1px1ny1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY , initialZ-1); const float pVoxel1px0py1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY , initialZ ); const float pVoxel1px0py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY , initialZ+1); const float pVoxel1px0py1pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY+1, initialZ-1); const float pVoxel1px1py1nz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY+1, initialZ ); const float pVoxel1px1py0pz = computeSmoothedVoxel(volIter);
|
||||
volIter.setPosition(initialX+1, initialY+1, initialZ+1); const float pVoxel1px1py1pz = computeSmoothedVoxel(volIter);
|
||||
|
||||
/*const VoxelType pVoxel1nx1ny1nz = volIter.peekVoxel1nx1ny1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx1ny0pz = volIter.peekVoxel1nx1ny0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx1ny1pz = volIter.peekVoxel1nx1ny1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx0py1nz = volIter.peekVoxel1nx0py1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx0py0pz = volIter.peekVoxel1nx0py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx0py1pz = volIter.peekVoxel1nx0py1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx1py1nz = volIter.peekVoxel1nx1py1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx1py0pz = volIter.peekVoxel1nx1py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1nx1py1pz = volIter.peekVoxel1nx1py1pz() > 0 ? 1: 0;
|
||||
|
||||
const VoxelType pVoxel0px1ny1nz = volIter.peekVoxel0px1ny1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px1ny0pz = volIter.peekVoxel0px1ny0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px1ny1pz = volIter.peekVoxel0px1ny1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px0py1nz = volIter.peekVoxel0px0py1nz() > 0 ? 1: 0;
|
||||
//const VoxelType pVoxel0px0py0pz = volIter.peekVoxel0px0py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px0py1pz = volIter.peekVoxel0px0py1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px1py1nz = volIter.peekVoxel0px1py1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px1py0pz = volIter.peekVoxel0px1py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel0px1py1pz = volIter.peekVoxel0px1py1pz() > 0 ? 1: 0;
|
||||
|
||||
const VoxelType pVoxel1px1ny1nz = volIter.peekVoxel1px1ny1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px1ny0pz = volIter.peekVoxel1px1ny0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px1ny1pz = volIter.peekVoxel1px1ny1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px0py1nz = volIter.peekVoxel1px0py1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px0py0pz = volIter.peekVoxel1px0py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px0py1pz = volIter.peekVoxel1px0py1pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px1py1nz = volIter.peekVoxel1px1py1nz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px1py0pz = volIter.peekVoxel1px1py0pz() > 0 ? 1: 0;
|
||||
const VoxelType pVoxel1px1py1pz = volIter.peekVoxel1px1py1pz() > 0 ? 1: 0;*/
|
||||
|
||||
const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
|
||||
weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
|
||||
pVoxel1nx1ny1pz - weights[0][1][0] * pVoxel1nx0py1nz -
|
||||
weights[1][1][0] * pVoxel1nx0py0pz - weights[2][1][0] *
|
||||
pVoxel1nx0py1pz - weights[0][2][0] * pVoxel1nx1py1nz -
|
||||
weights[1][2][0] * pVoxel1nx1py0pz - weights[2][2][0] *
|
||||
pVoxel1nx1py1pz + weights[0][0][2] * pVoxel1px1ny1nz +
|
||||
weights[1][0][2] * pVoxel1px1ny0pz + weights[2][0][2] *
|
||||
pVoxel1px1ny1pz + weights[0][1][2] * pVoxel1px0py1nz +
|
||||
weights[1][1][2] * pVoxel1px0py0pz + weights[2][1][2] *
|
||||
pVoxel1px0py1pz + weights[0][2][2] * pVoxel1px1py1nz +
|
||||
weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
|
||||
pVoxel1px1py1pz);
|
||||
|
||||
const float yGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
|
||||
weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
|
||||
pVoxel1nx1ny1pz + weights[0][2][0] * pVoxel1nx1py1nz +
|
||||
weights[1][2][0] * pVoxel1nx1py0pz + weights[2][2][0] *
|
||||
pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz -
|
||||
weights[1][0][1] * pVoxel0px1ny0pz - weights[2][0][1] *
|
||||
pVoxel0px1ny1pz + weights[0][2][1] * pVoxel0px1py1nz +
|
||||
weights[1][2][1] * pVoxel0px1py0pz + weights[2][2][1] *
|
||||
pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz -
|
||||
weights[1][0][2] * pVoxel1px1ny0pz - weights[2][0][2] *
|
||||
pVoxel1px1ny1pz + weights[0][2][2] * pVoxel1px1py1nz +
|
||||
weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
|
||||
pVoxel1px1py1pz);
|
||||
|
||||
const float zGrad(- weights[0][0][0] * pVoxel1nx1ny1nz +
|
||||
weights[2][0][0] * pVoxel1nx1ny1pz - weights[0][1][0] *
|
||||
pVoxel1nx0py1nz + weights[2][1][0] * pVoxel1nx0py1pz -
|
||||
weights[0][2][0] * pVoxel1nx1py1nz + weights[2][2][0] *
|
||||
pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz +
|
||||
weights[2][0][1] * pVoxel0px1ny1pz - weights[0][1][1] *
|
||||
pVoxel0px0py1nz + weights[2][1][1] * pVoxel0px0py1pz -
|
||||
weights[0][2][1] * pVoxel0px1py1nz + weights[2][2][1] *
|
||||
pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz +
|
||||
weights[2][0][2] * pVoxel1px1ny1pz - weights[0][1][2] *
|
||||
pVoxel1px0py1nz + weights[2][1][2] * pVoxel1px0py1pz -
|
||||
weights[0][2][2] * pVoxel1px1py1nz + weights[2][2][2] *
|
||||
pVoxel1px1py1pz);
|
||||
|
||||
//Note: The above actually give gradients going from low density to high density.
|
||||
//For our normals we want the the other way around, so we switch the components as we return them.
|
||||
return Vector3DFloat(-xGrad,-yGrad,-zGrad);
|
||||
}
|
||||
}
|
||||
|
@ -20,51 +20,13 @@ namespace PolyVox
|
||||
BlockVolumeIterator<uint8> volIter(*volumeData);
|
||||
|
||||
//Check all corners are within the volume, allowing a boundary for gradient estimation
|
||||
bool lowerCornerInside = volumeData->containsPoint(v3dFloor,1);
|
||||
bool upperCornerInside = volumeData->containsPoint(v3dFloor+Vector3DInt32(1,1,1),1);
|
||||
bool lowerCornerInside = volumeData->containsPoint(v3dFloor,2);
|
||||
bool upperCornerInside = volumeData->containsPoint(v3dFloor+Vector3DInt32(1,1,1),2);
|
||||
|
||||
if(lowerCornerInside && upperCornerInside) //If this test fails the vertex will be left as it was
|
||||
{
|
||||
Vector3DFloat v3dGradient; //To store the result
|
||||
|
||||
if(normalGenerationMethod == SOBEL)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor));
|
||||
const Vector3DFloat gradFloor = computeSobelGradient(volIter);
|
||||
if((v3dPos.getX() - v3dFloor.getX()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(1,0,0)));
|
||||
}
|
||||
if((v3dPos.getY() - v3dFloor.getY()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,1,0)));
|
||||
}
|
||||
if((v3dPos.getZ() - v3dFloor.getZ()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,0,1)));
|
||||
}
|
||||
const Vector3DFloat gradCeil = computeSobelGradient(volIter);
|
||||
v3dGradient = (gradFloor + gradCeil);
|
||||
}
|
||||
if(normalGenerationMethod == CENTRAL_DIFFERENCE)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor));
|
||||
const Vector3DFloat gradFloor = computeCentralDifferenceGradient(volIter);
|
||||
if((v3dPos.getX() - v3dFloor.getX()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(1,0,0)));
|
||||
}
|
||||
if((v3dPos.getY() - v3dFloor.getY()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,1,0)));
|
||||
}
|
||||
if((v3dPos.getZ() - v3dFloor.getZ()) > 0.001)
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,0,1)));
|
||||
}
|
||||
const Vector3DFloat gradCeil = computeCentralDifferenceGradient(volIter);
|
||||
v3dGradient = (gradFloor + gradCeil);
|
||||
}
|
||||
Vector3DFloat v3dGradient = computeNormal(volumeData, v3dPos, normalGenerationMethod);
|
||||
|
||||
if(v3dGradient.lengthSquared() > 0.0001)
|
||||
{
|
||||
//If we got a normal of significant length then update it.
|
||||
@ -77,97 +39,89 @@ namespace PolyVox
|
||||
}
|
||||
}
|
||||
|
||||
Vector3DFloat computeNormal(BlockVolume<uint8>* volumeData, const Vector3DFloat& position, NormalGenerationMethod normalGenerationMethod)
|
||||
Vector3DFloat computeNormal(BlockVolume<uint8>* volumeData, const Vector3DFloat& v3dPos, NormalGenerationMethod normalGenerationMethod)
|
||||
{
|
||||
const float posX = position.getX();
|
||||
const float posY = position.getY();
|
||||
const float posZ = position.getZ();
|
||||
Vector3DFloat v3dGradient; //To store the result
|
||||
|
||||
const uint16 floorX = static_cast<uint16>(posX);
|
||||
const uint16 floorY = static_cast<uint16>(posY);
|
||||
const uint16 floorZ = static_cast<uint16>(posZ);
|
||||
BlockVolumeIterator<uint8> volIter(*volumeData);
|
||||
|
||||
//Check all corners are within the volume, allowing a boundary for gradient estimation
|
||||
bool lowerCornerInside = volumeData->containsPoint(Vector3DInt32(floorX, floorY, floorZ),1);
|
||||
bool upperCornerInside = volumeData->containsPoint(Vector3DInt32(floorX+1, floorY+1, floorZ+1),1);
|
||||
if((!lowerCornerInside) || (!upperCornerInside))
|
||||
{
|
||||
normalGenerationMethod = SIMPLE;
|
||||
}
|
||||
const Vector3DInt32 v3dFloor = static_cast<Vector3DInt32>(v3dPos);
|
||||
|
||||
Vector3DFloat result;
|
||||
|
||||
BlockVolumeIterator<uint8> volIter(*volumeData); //FIXME - save this somewhere - could be expensive to create?
|
||||
|
||||
|
||||
if(normalGenerationMethod == SOBEL)
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY),static_cast<uint16>(posZ));
|
||||
const Vector3DFloat gradFloor = computeSobelGradient(volIter);
|
||||
if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX+1.0),static_cast<uint16>(posY),static_cast<uint16>(posZ));
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor));
|
||||
Vector3DFloat gradFloor;
|
||||
switch(normalGenerationMethod)
|
||||
{
|
||||
case SOBEL_SMOOTHED:
|
||||
gradFloor = computeSmoothSobelGradient(volIter);
|
||||
break;
|
||||
case CENTRAL_DIFFERENCE_SMOOTHED:
|
||||
gradFloor = computeSmoothCentralDifferenceGradient(volIter);
|
||||
break;
|
||||
case SOBEL:
|
||||
gradFloor = computeSobelGradient(volIter);
|
||||
break;
|
||||
case CENTRAL_DIFFERENCE:
|
||||
gradFloor = computeCentralDifferenceGradient(volIter);
|
||||
break;
|
||||
}
|
||||
if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5
|
||||
|
||||
if((v3dPos.getX() - v3dFloor.getX()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY+1.0),static_cast<uint16>(posZ));
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(1,0,0)));
|
||||
}
|
||||
if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5
|
||||
if((v3dPos.getY() - v3dFloor.getY()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY),static_cast<uint16>(posZ+1.0));
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,1,0)));
|
||||
}
|
||||
const Vector3DFloat gradCeil = computeSobelGradient(volIter);
|
||||
result = ((gradFloor + gradCeil) * -1.0f);
|
||||
if(result.lengthSquared() < 0.0001)
|
||||
if((v3dPos.getZ() - v3dFloor.getZ()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor+Vector3DInt32(0,0,1)));
|
||||
}
|
||||
|
||||
Vector3DFloat gradCeil;
|
||||
switch(normalGenerationMethod)
|
||||
{
|
||||
case SOBEL_SMOOTHED:
|
||||
gradCeil = computeSmoothSobelGradient(volIter);
|
||||
break;
|
||||
case CENTRAL_DIFFERENCE_SMOOTHED:
|
||||
gradCeil = computeSmoothCentralDifferenceGradient(volIter);
|
||||
break;
|
||||
case SOBEL:
|
||||
gradCeil = computeSobelGradient(volIter);
|
||||
break;
|
||||
case CENTRAL_DIFFERENCE:
|
||||
gradCeil = computeCentralDifferenceGradient(volIter);
|
||||
break;
|
||||
}
|
||||
|
||||
v3dGradient = (gradFloor + gradCeil);
|
||||
if(v3dGradient.lengthSquared() < 0.0001)
|
||||
{
|
||||
//Operation failed - fall back on simple gradient estimation
|
||||
normalGenerationMethod = SIMPLE;
|
||||
}
|
||||
}
|
||||
if(normalGenerationMethod == CENTRAL_DIFFERENCE)
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY),static_cast<uint16>(posZ));
|
||||
const Vector3DFloat gradFloor = computeCentralDifferenceGradient(volIter);
|
||||
if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX+1.0),static_cast<uint16>(posY),static_cast<uint16>(posZ));
|
||||
}
|
||||
if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY+1.0),static_cast<uint16>(posZ));
|
||||
}
|
||||
if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY),static_cast<uint16>(posZ+1.0));
|
||||
}
|
||||
const Vector3DFloat gradCeil = computeCentralDifferenceGradient(volIter);
|
||||
result = ((gradFloor + gradCeil) * -1.0f);
|
||||
if(result.lengthSquared() < 0.0001)
|
||||
|
||||
if(normalGenerationMethod == SIMPLE)
|
||||
{
|
||||
//Operation failed - fall back on simple gradient estimation
|
||||
normalGenerationMethod = SIMPLE;
|
||||
volIter.setPosition(static_cast<Vector3DInt16>(v3dFloor));
|
||||
const uint8 uFloor = volIter.getVoxel() > 0 ? 1 : 0;
|
||||
if((v3dPos.getX() - v3dFloor.getX()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel1px0py0pz() > 0 ? 1 : 0;
|
||||
v3dGradient = Vector3DFloat(static_cast<float>(uFloor - uCeil),0.0,0.0);
|
||||
}
|
||||
else if((v3dPos.getY() - v3dFloor.getY()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel0px1py0pz() > 0 ? 1 : 0;
|
||||
v3dGradient = Vector3DFloat(0.0,static_cast<float>(uFloor - uCeil),0.0);
|
||||
}
|
||||
else if((v3dPos.getZ() - v3dFloor.getZ()) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel0px0py1pz() > 0 ? 1 : 0;
|
||||
v3dGradient = Vector3DFloat(0.0, 0.0,static_cast<float>(uFloor - uCeil));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(normalGenerationMethod == SIMPLE)
|
||||
{
|
||||
volIter.setPosition(static_cast<uint16>(posX),static_cast<uint16>(posY),static_cast<uint16>(posZ));
|
||||
const uint8 uFloor = volIter.getVoxel() > 0 ? 1 : 0;
|
||||
if((posX - floorX) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel1px0py0pz() > 0 ? 1 : 0;
|
||||
result = Vector3DFloat(static_cast<float>(uFloor - uCeil),0.0,0.0);
|
||||
}
|
||||
else if((posY - floorY) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel0px1py0pz() > 0 ? 1 : 0;
|
||||
result = Vector3DFloat(0.0,static_cast<float>(uFloor - uCeil),0.0);
|
||||
}
|
||||
else if((posZ - floorZ) > 0.25) //The result should be 0.0 or 0.5
|
||||
{
|
||||
uint8 uCeil = volIter.peekVoxel0px0py1pz() > 0 ? 1 : 0;
|
||||
result = Vector3DFloat(0.0, 0.0,static_cast<float>(uFloor - uCeil));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return v3dGradient;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user