Added SurfaceExtractionController and modified SurfaceExtractor to use it.

This commit is contained in:
unknown 2012-06-26 15:02:07 +02:00
parent 85c5b7abf0
commit af5a351b45
9 changed files with 149 additions and 99 deletions

View File

@ -65,6 +65,7 @@ SET(CORE_INC_FILES
include/PolyVoxCore/SimpleVolume.inl
include/PolyVoxCore/SimpleVolumeBlock.inl
include/PolyVoxCore/SimpleVolumeSampler.inl
include/PolyVoxCore/SurfaceExtractionController.h
include/PolyVoxCore/SurfaceExtractor.h
include/PolyVoxCore/SurfaceExtractor.inl
include/PolyVoxCore/SurfaceMesh.h

View File

@ -24,6 +24,7 @@ freely, subject to the following restrictions:
#ifndef __PolyVox_Density_H__
#define __PolyVox_Density_H__
#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here
#include "PolyVoxCore/Voxel.h"
#include "PolyVoxImpl/TypeDef.h"
@ -102,6 +103,24 @@ namespace PolyVox
static Density8::DensityType minDensity() { return std::numeric_limits<Density8::DensityType>::min(); }
static Density8::DensityType maxDensity() { return std::numeric_limits<Density8::DensityType>::max(); }
};
template <typename Type>
class SurfaceExtractionController< Density<Type> >
{
public:
typedef Type DensityType;
typedef float MaterialType;
DensityType convertToDensity(Density<Type> voxel)
{
return voxel.getDensity();
}
MaterialType convertToMaterial(Density<Type> voxel)
{
return 1;
}
};
}
#include "PolyVoxCore/SurfaceExtractor.h" //VERY UGLY THAT WE NEED THIS!!! TO BE CONSIDERED...
@ -110,15 +129,6 @@ namespace PolyVox
{
template<>
VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel);
template<>
class ConvertToDensity<Density8>
{
public:
typedef uint8_t DensityType;
DensityType operator()(Density8 voxel);
};
}
#endif //__PolyVox_Density_H__

View File

@ -24,6 +24,7 @@ freely, subject to the following restrictions:
#ifndef __PolyVox_Material_H__
#define __PolyVox_Material_H__
#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here
#include "PolyVoxCore/Voxel.h"
#include "PolyVoxImpl/TypeDef.h"
@ -116,6 +117,24 @@ namespace PolyVox
typedef Material<uint8_t> Material8;
typedef Material<uint16_t> Material16;
template <typename Type>
class SurfaceExtractionController< Material<Type> >
{
public:
typedef int32_t DensityType;
typedef float MaterialType;
DensityType convertToDensity(Material<Type> voxel)
{
return voxel.getDensity();
}
MaterialType convertToMaterial(Material<Type> voxel)
{
return voxel.getMaterial();
}
};
template<>
class VoxelTypeTraits< Material8 >
{

View File

@ -24,6 +24,7 @@ freely, subject to the following restrictions:
#ifndef __PolyVox_MaterialDensityPair_H__
#define __PolyVox_MaterialDensityPair_H__
#include "PolyVoxCore/SurfaceExtractionController.h" //We'll specialise the controller contained in here
#include "PolyVoxCore/Voxel.h"
#include "PolyVoxImpl/TypeDef.h"
@ -96,6 +97,24 @@ namespace PolyVox
DensityType m_uDensity : NoOfDensityBits;
};
template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
class SurfaceExtractionController< MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> >
{
public:
typedef Type DensityType;
typedef Type MaterialType;
DensityType convertToDensity(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> voxel)
{
return voxel.getDensity();
}
MaterialType convertToMaterial(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> voxel)
{
return voxel.getMaterial();
}
};
typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44;
typedef MaterialDensityPair<uint16_t, 8, 8> MaterialDensityPair88;
@ -130,24 +149,6 @@ namespace PolyVox
template<>
VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel);
template<>
class ConvertToDensity<MaterialDensityPair44>
{
public:
typedef uint32_t DensityType;
DensityType operator()(MaterialDensityPair44 voxel);
};
template<>
class ConvertToDensity<MaterialDensityPair88>
{
public:
typedef uint32_t DensityType;
DensityType operator()(MaterialDensityPair88 voxel);
};
template<>
class ConvertToMaterial<MaterialDensityPair44>
{

View File

@ -0,0 +1,48 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __PolyVox_SurfaceExtractionController_H__
#define __PolyVox_SurfaceExtractionController_H__
namespace PolyVox
{
template<typename VoxelType>
class SurfaceExtractionController
{
public:
typedef VoxelType DensityType;
typedef float MaterialType;
DensityType convertToDensity(VoxelType voxel)
{
return voxel;
}
MaterialType convertToMaterial(VoxelType voxel)
{
return 1;
}
};
}
#endif

View File

@ -29,6 +29,7 @@ freely, subject to the following restrictions:
#include "PolyVoxCore/Array.h"
#include "PolyVoxCore/SurfaceMesh.h"
#include "PolyVoxCore/SurfaceExtractionController.h"
namespace PolyVox
{
@ -42,17 +43,6 @@ namespace PolyVox
static uint8_t maxDensity() { return 255; }
};
template<typename VoxelType>
class ConvertToDensity
{
public:
typedef VoxelType DensityType;
DensityType operator()(VoxelType voxel)
{
return voxel;
}
};
template<typename VoxelType>
class ConvertToMaterial
{
@ -240,6 +230,9 @@ namespace PolyVox
//Our threshold value
typename VoxelTypeTraits<typename VolumeType::VoxelType>::DensityType m_tThreshold;
//Used to convert arbitrary voxel types in densities and materials.
SurfaceExtractionController<typename VolumeType::VoxelType> m_controller;
};
}

View File

@ -206,8 +206,6 @@ namespace PolyVox
typename VolumeType::VoxelType v011;
typename VolumeType::VoxelType v111;
ConvertToDensity<typename VolumeType::VoxelType> DensityConverter;
if(isPrevZAvail)
{
if(isPrevYAvail)
@ -232,7 +230,7 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ;
if (DensityConverter(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
else //previous X not available
{
@ -250,8 +248,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ;
if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
}
else //previous Y not available
@ -272,8 +270,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ;
if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
else //previous X not available
{
@ -286,10 +284,10 @@ namespace PolyVox
uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace];
iCubeIndex = iPreviousCubeIndexZ >> 4;
if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
}
}
@ -314,8 +312,8 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY;
if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
else //previous X not available
{
@ -332,10 +330,10 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexY;
if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
}
else //previous Y not available
@ -355,10 +353,10 @@ namespace PolyVox
iCubeIndex = iPreviousCubeIndexX;
if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
else //previous X not available
{
@ -372,14 +370,14 @@ namespace PolyVox
v011 = m_sampVolume.peekVoxel0px1py1pz();
v111 = m_sampVolume.peekVoxel1px1py1pz();
if (convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1;
if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
if (m_controller.convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1;
if (m_controller.convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;
if (m_controller.convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4;
if (m_controller.convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8;
if (m_controller.convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16;
if (m_controller.convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32;
if (m_controller.convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64;
if (m_controller.convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128;
}
}
}
@ -399,8 +397,6 @@ namespace PolyVox
Array2DInt32& m_pCurrentVertexIndicesY,
Array2DInt32& m_pCurrentVertexIndicesZ)
{
ConvertToMaterial<typename VolumeType::VoxelType> converter;
int32_t iZVolSpace = m_regSliceCurrent.getLowerCorner().getZ();
const uint32_t uZRegSpace = iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ();
@ -437,7 +433,7 @@ namespace PolyVox
const typename VolumeType::VoxelType v100 = m_sampVolume.getVoxel();
const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume);
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v100) - convertToDensity(v000));
float fInterp = static_cast<float>(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast<float>(m_controller.convertToDensity(v100) - m_controller.convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()) + fInterp, static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(iZVolSpace - m_regSizeInCells.getLowerCorner().getZ()));
@ -447,9 +443,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of
//material IDs does not make sense). We take the largest, so that if we are working on a material-only
//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial000 = converter(v000);
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial100 = converter(v100);
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial100);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial000 = m_controller.convertToMaterial(v000);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial100 = m_controller.convertToMaterial(v100);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial100);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -463,7 +459,7 @@ namespace PolyVox
const typename VolumeType::VoxelType v010 = m_sampVolume.getVoxel();
const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume);
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v010) - convertToDensity(v000));
float fInterp = static_cast<float>(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast<float>(m_controller.convertToDensity(v010) - m_controller.convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()) + fInterp, static_cast<float>(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ()));
@ -473,9 +469,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of
//material IDs does not make sense). We take the largest, so that if we are working on a material-only
//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial000 = converter(v000);
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial010 = converter(v010);
uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial000 = m_controller.convertToMaterial(v000);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial010 = m_controller.convertToMaterial(v010);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial010);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);
@ -489,7 +485,7 @@ namespace PolyVox
const typename VolumeType::VoxelType v001 = m_sampVolume.getVoxel();
const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume);
float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v001) - convertToDensity(v000));
float fInterp = static_cast<float>(m_tThreshold - m_controller.convertToDensity(v000)) / static_cast<float>(m_controller.convertToDensity(v001) - m_controller.convertToDensity(v000));
const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ()) + fInterp);
@ -499,9 +495,9 @@ namespace PolyVox
//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of
//material IDs does not make sense). We take the largest, so that if we are working on a material-only
//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component.
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial000 = converter(v000);
typename ConvertToMaterial<typename VolumeType::VoxelType>::MaterialType uMaterial001 = converter(v001);
uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial000 = m_controller.convertToMaterial(v000);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial001 = m_controller.convertToMaterial(v001);
typename SurfaceExtractionController<typename VolumeType::VoxelType>::MaterialType uMaterial = (std::max)(uMaterial000, uMaterial001);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex);

View File

@ -30,10 +30,4 @@ namespace PolyVox
{
return voxel.getDensity();
}
//template<>
ConvertToDensity<Density8>::DensityType ConvertToDensity<Density8>::operator()(Density8 voxel)
{
return voxel.getDensity();
}
}

View File

@ -37,18 +37,6 @@ namespace PolyVox
return voxel.getDensity();
}
//template<>
ConvertToDensity<MaterialDensityPair44>::DensityType ConvertToDensity<MaterialDensityPair44>::operator()(MaterialDensityPair44 voxel)
{
return voxel.getDensity();
}
//template<>
ConvertToDensity<MaterialDensityPair88>::DensityType ConvertToDensity<MaterialDensityPair88>::operator()(MaterialDensityPair88 voxel)
{
return voxel.getDensity();
}
//template<>
ConvertToMaterial<MaterialDensityPair44>::MaterialType ConvertToMaterial<MaterialDensityPair44>::operator()(MaterialDensityPair44 voxel)
{