diff --git a/include/PolyVox/MarchingCubesSurfaceExtractor.h b/include/PolyVox/MarchingCubesSurfaceExtractor.h index 46003e8b..dde8acdf 100644 --- a/include/PolyVox/MarchingCubesSurfaceExtractor.h +++ b/include/PolyVox/MarchingCubesSurfaceExtractor.h @@ -163,19 +163,19 @@ namespace PolyVox // NOTE: These two functions are in the .h file rather than the .inl due to an apparent bug in VC2010. //See http://stackoverflow.com/questions/1484885/strange-vc-compile-error-c2244 for details. //////////////////////////////////////////////////////////////////////////////// - Vector3DFloat computeCentralDifferenceGradient(const typename VolumeType::Sampler& volIter) + Vector3DFloat computeCentralDifferenceGradient(const typename VolumeType::Sampler& volIter, ControllerType& controller) { //FIXME - Should actually use DensityType here, both in principle and because the maths may be //faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. //But watch out for when the DensityType is unsigned and the difference could be negative. - float voxel1nx = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz())); - float voxel1px = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz())); + float voxel1nx = static_cast(controller.convertToDensity(volIter.peekVoxel1nx0py0pz())); + float voxel1px = static_cast(controller.convertToDensity(volIter.peekVoxel1px0py0pz())); - float voxel1ny = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz())); - float voxel1py = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz())); + float voxel1ny = static_cast(controller.convertToDensity(volIter.peekVoxel0px1ny0pz())); + float voxel1py = static_cast(controller.convertToDensity(volIter.peekVoxel0px1py0pz())); - float voxel1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz())); - float voxel1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz())); + float voxel1nz = static_cast(controller.convertToDensity(volIter.peekVoxel0px0py1nz())); + float voxel1pz = static_cast(controller.convertToDensity(volIter.peekVoxel0px0py1pz())); return Vector3DFloat ( @@ -184,97 +184,9 @@ namespace PolyVox voxel1nz - voxel1pz ); } - - Vector3DFloat computeSobelGradient(const typename VolumeType::Sampler& 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} } }; - - //FIXME - Should actually use DensityType here, both in principle and because the maths may be - //faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. - //But watch out for when the DensityType is unsigned and the difference could be negative. - const float pVoxel1nx1ny1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1nz())); - const float pVoxel1nx1ny0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1ny0pz())); - const float pVoxel1nx1ny1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1pz())); - const float pVoxel1nx0py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx0py1nz())); - const float pVoxel1nx0py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz())); - const float pVoxel1nx0py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx0py1pz())); - const float pVoxel1nx1py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1py1nz())); - const float pVoxel1nx1py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1py0pz())); - const float pVoxel1nx1py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1nx1py1pz())); - - const float pVoxel0px1ny1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1ny1nz())); - const float pVoxel0px1ny0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz())); - const float pVoxel0px1ny1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1ny1pz())); - const float pVoxel0px0py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz())); - //const float pVoxel0px0py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px0py0pz())); - const float pVoxel0px0py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz())); - const float pVoxel0px1py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1py1nz())); - const float pVoxel0px1py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz())); - const float pVoxel0px1py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel0px1py1pz())); - - const float pVoxel1px1ny1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1ny1nz())); - const float pVoxel1px1ny0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1ny0pz())); - const float pVoxel1px1ny1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1ny1pz())); - const float pVoxel1px0py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px0py1nz())); - const float pVoxel1px0py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz())); - const float pVoxel1px0py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px0py1pz())); - const float pVoxel1px1py1nz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1py1nz())); - const float pVoxel1px1py0pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1py0pz())); - const float pVoxel1px1py1pz = static_cast(m_controller.convertToDensity(volIter.peekVoxel1px1py1pz())); - - 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); - } //////////////////////////////////////////////////////////////////////////////// // End of compiler bug workaroumd. //////////////////////////////////////////////////////////////////////////////// - - //Used to convert arbitrary voxel types in densities and materials. - ControllerType m_controller; }; // This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically. diff --git a/include/PolyVox/MarchingCubesSurfaceExtractor.inl b/include/PolyVox/MarchingCubesSurfaceExtractor.inl index fcccdbe3..e70b7374 100644 --- a/include/PolyVox/MarchingCubesSurfaceExtractor.inl +++ b/include/PolyVox/MarchingCubesSurfaceExtractor.inl @@ -35,8 +35,7 @@ namespace PolyVox { POLYVOX_THROW_IF(result == nullptr, std::invalid_argument, "Provided mesh cannot be null"); - m_controller = controller; - typename ControllerType::DensityType tThreshold = m_controller.getThreshold(); + typename ControllerType::DensityType tThreshold = controller.getThreshold(); Timer timer; result->clear(); @@ -107,7 +106,7 @@ namespace PolyVox // The last bit of our cube index is obtained by looking // at the relevant voxel and comparing it to the threshold typename VolumeType::VoxelType v111 = sampler.getVoxel(); - if (m_controller.convertToDensity(v111) < tThreshold) iCubeIndex |= 128; + if (controller.convertToDensity(v111) < tThreshold) iCubeIndex |= 128; // The current value becomes the previous value, ready for the next iteration. uPreviousCell = iCubeIndex; @@ -123,16 +122,16 @@ namespace PolyVox typename VolumeType::VoxelType v101 = sampler.peekVoxel0px1ny0pz(); typename VolumeType::VoxelType v011 = sampler.peekVoxel1nx0py0pz(); - const Vector3DFloat n000 = computeCentralDifferenceGradient(sampler); + const Vector3DFloat n000 = computeCentralDifferenceGradient(sampler, controller); /* Find the vertices where the surface intersects the cube */ if ((edgeTable[iCubeIndex] & 64) && (uXRegSpace > 0)) { sampler.moveNegativeX(); POLYVOX_ASSERT(v011 != v111, "Attempting to insert vertex between two voxels with the same value"); - const Vector3DFloat n100 = computeCentralDifferenceGradient(sampler); + const Vector3DFloat n100 = computeCentralDifferenceGradient(sampler, controller); - const float fInterp = static_cast(tThreshold - m_controller.convertToDensity(v011)) / static_cast(m_controller.convertToDensity(v111) - m_controller.convertToDensity(v011)); + const float fInterp = static_cast(tThreshold - controller.convertToDensity(v011)) / static_cast(controller.convertToDensity(v111) - controller.convertToDensity(v011)); const Vector3DFloat v3dPosition(static_cast(uXRegSpace - 1) + fInterp, static_cast(uYRegSpace), static_cast(uZRegSpace)); const Vector3DUint16 v3dScaledPosition(static_cast(v3dPosition.getX() * 256.0f), static_cast(v3dPosition.getY() * 256.0f), static_cast(v3dPosition.getZ() * 256.0f)); @@ -147,7 +146,7 @@ namespace PolyVox } // Allow the controller to decide how the material should be derived from the voxels. - const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v011, v111, fInterp); + const typename VolumeType::VoxelType uMaterial = controller.blendMaterials(v011, v111, fInterp); MarchingCubesVertex surfaceVertex; surfaceVertex.encodedPosition = v3dScaledPosition; @@ -163,9 +162,9 @@ namespace PolyVox { sampler.moveNegativeY(); POLYVOX_ASSERT(v101 != v111, "Attempting to insert vertex between two voxels with the same value"); - const Vector3DFloat n010 = computeCentralDifferenceGradient(sampler); + const Vector3DFloat n010 = computeCentralDifferenceGradient(sampler, controller); - const float fInterp = static_cast(tThreshold - m_controller.convertToDensity(v101)) / static_cast(m_controller.convertToDensity(v111) - m_controller.convertToDensity(v101)); + const float fInterp = static_cast(tThreshold - controller.convertToDensity(v101)) / static_cast(controller.convertToDensity(v111) - controller.convertToDensity(v101)); const Vector3DFloat v3dPosition(static_cast(uXRegSpace), static_cast(uYRegSpace - 1) + fInterp, static_cast(uZRegSpace)); const Vector3DUint16 v3dScaledPosition(static_cast(v3dPosition.getX() * 256.0f), static_cast(v3dPosition.getY() * 256.0f), static_cast(v3dPosition.getZ() * 256.0f)); @@ -180,7 +179,7 @@ namespace PolyVox } // Allow the controller to decide how the material should be derived from the voxels. - const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v101, v111, fInterp); + const typename VolumeType::VoxelType uMaterial = controller.blendMaterials(v101, v111, fInterp); MarchingCubesVertex surfaceVertex; surfaceVertex.encodedPosition = v3dScaledPosition; @@ -196,9 +195,9 @@ namespace PolyVox { sampler.moveNegativeZ(); POLYVOX_ASSERT(v110 != v111, "Attempting to insert vertex between two voxels with the same value"); - const Vector3DFloat n001 = computeCentralDifferenceGradient(sampler); + const Vector3DFloat n001 = computeCentralDifferenceGradient(sampler, controller); - const float fInterp = static_cast(tThreshold - m_controller.convertToDensity(v110)) / static_cast(m_controller.convertToDensity(v111) - m_controller.convertToDensity(v110)); + const float fInterp = static_cast(tThreshold - controller.convertToDensity(v110)) / static_cast(controller.convertToDensity(v111) - controller.convertToDensity(v110)); const Vector3DFloat v3dPosition(static_cast(uXRegSpace), static_cast(uYRegSpace), static_cast(uZRegSpace - 1) + fInterp); const Vector3DUint16 v3dScaledPosition(static_cast(v3dPosition.getX() * 256.0f), static_cast(v3dPosition.getY() * 256.0f), static_cast(v3dPosition.getZ() * 256.0f)); @@ -212,7 +211,7 @@ namespace PolyVox } // Allow the controller to decide how the material should be derived from the voxels. - const typename VolumeType::VoxelType uMaterial = m_controller.blendMaterials(v110, v111, fInterp); + const typename VolumeType::VoxelType uMaterial = controller.blendMaterials(v110, v111, fInterp); MarchingCubesVertex surfaceVertex; surfaceVertex.encodedPosition = v3dScaledPosition;