Work on refactoring voxel types.

Expanded surface extractor test.
This commit is contained in:
unknown 2012-02-20 10:16:26 +01:00
parent ee17f72753
commit a20db7d7cf
10 changed files with 119 additions and 43 deletions

View File

@ -51,6 +51,7 @@ SET(CORE_INC_FILES
include/PolyVoxCore/MeshDecimator.h
include/PolyVoxCore/MeshDecimator.inl
include/PolyVoxCore/PolyVoxForwardDeclarations.h
include/PolyVoxCore/PrimitiveVoxelTypes.h
include/PolyVoxCore/RawVolume.h
include/PolyVoxCore/RawVolume.inl
include/PolyVoxCore/RawVolumeSampler.inl

View File

@ -98,6 +98,7 @@ namespace PolyVox
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = true;
static const bool HasMaterial = false;
static bool hasDensity() { return true; }

View File

@ -108,6 +108,7 @@ namespace PolyVox
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = false;
static const bool HasMaterial = true;
static bool hasDensity() { return false; }

View File

@ -91,6 +91,7 @@ namespace PolyVox
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = true;
static const bool HasMaterial = true;
static bool hasDensity() { return true; }
@ -104,6 +105,7 @@ namespace PolyVox
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = true;
static const bool HasMaterial = true;
static bool hasDensity() { return true; }
@ -111,12 +113,23 @@ namespace PolyVox
static MaterialDensityPair88::DensityType minDensity() { return 0; }
static MaterialDensityPair88::DensityType maxDensity() { return 255; }
};
}
#include "PolyVoxCore/SurfaceExtractor.h"
namespace PolyVox
{
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::MaterialType convertToMaterial(MaterialDensityPair44 voxel);
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType convertToMaterial(MaterialDensityPair88 voxel);
}
#endif

View File

@ -0,0 +1,34 @@
/*******************************************************************************
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_PrimitiveVoxelTypes_H__
#define __PolyVox_PrimitiveVoxelTypes_H__
#include "PolyVoxCore/Voxel.h"
namespace PolyVox
{
}
#endif //__PolyVox_PrimitiveVoxelTypes_H__

View File

@ -32,6 +32,26 @@ freely, subject to the following restrictions:
namespace PolyVox
{
template<>
class VoxelTypeTraits< uint8_t >
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = true;
static const bool HasMaterial = false;
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static uint8_t minDensity() { return 0; }
static uint8_t maxDensity() { return 255; }
};
template<typename VoxelType>
typename VoxelTypeTraits<VoxelType>::MaterialType convertToMaterial(VoxelType voxel)
{
return 1;
}
template< template<typename> class VolumeType, typename VoxelType>
class SurfaceExtractor
{

View File

@ -391,28 +391,6 @@ namespace PolyVox
}
}
template<typename VoxelType, bool HasMaterialInType = true>
struct getMaterialFromVoxel;
template<typename VoxelType>
struct getMaterialFromVoxel<VoxelType, true>
{
static uint32_t run(VoxelType voxel)
{
return voxel.getMaterial();
}
};
template<typename VoxelType>
struct getMaterialFromVoxel<VoxelType, false>
{
static uint32_t run(VoxelType voxel)
{
return 0;
}
};
template< template<typename> class VolumeType, typename VoxelType>
void SurfaceExtractor<VolumeType, VoxelType>::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask,
Array2DInt32& m_pCurrentVertexIndicesX,
@ -465,8 +443,8 @@ 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.
uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
uint32_t uMaterial100 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v100);
uint32_t uMaterial000 = convertToMaterial(v000);
uint32_t uMaterial100 = convertToMaterial(v100);
uint32_t uMaterial = (std::max)(uMaterial000, uMaterial100);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
@ -491,8 +469,8 @@ 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.
uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
uint32_t uMaterial010 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v010);
uint32_t uMaterial000 = convertToMaterial(v000);
uint32_t uMaterial010 = convertToMaterial(v010);
uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));
@ -517,8 +495,8 @@ 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.
uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000);
uint32_t uMaterial001 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v001);
uint32_t uMaterial000 = convertToMaterial(v000);
uint32_t uMaterial001 = convertToMaterial(v001);
uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001);
PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial));

View File

@ -47,6 +47,7 @@ namespace PolyVox
{
public:
typedef uint8_t DensityType;
typedef uint8_t MaterialType;
static const bool HasDensity = false;
static const bool HasMaterial = false;
@ -66,19 +67,6 @@ namespace PolyVox
{
return voxel;
}
template<>
class VoxelTypeTraits< uint8_t >
{
public:
typedef uint8_t DensityType;
static const bool HasDensity = true;
static const bool HasMaterial = false;
static bool hasDensity() { return true; }
static bool hasMaterial() { return false; }
static uint8_t minDensity() { return 0; }
static uint8_t maxDensity() { return 255; }
};
}
#endif //__PolyVox_Voxel_H__

View File

@ -36,4 +36,16 @@ namespace PolyVox
{
return voxel.getDensity();
}
template<>
typename VoxelTypeTraits<MaterialDensityPair44>::MaterialType convertToMaterial(MaterialDensityPair44 voxel)
{
return voxel.getMaterial();
}
template<>
typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType convertToMaterial(MaterialDensityPair88 voxel)
{
return voxel.getMaterial();
}
}

View File

@ -35,7 +35,7 @@ using namespace PolyVox;
// These 'writeDensityValueToVoxel' functions provide a unified interface for writting densities to primative and class voxel types.
// They are conceptually the inverse of the 'convertToDensity' function used by the SurfaceExtractor. They probably shouldn't be part
// of PolyVox, but they might be usful to other tests so we cold move them into a 'Tests.h' or something in tthe future.
// of PolyVox, but they might be usful to other tests so we cold move them into a 'Tests.h' or something in the future.
template<typename VoxelType>
void writeDensityValueToVoxel(typename VoxelTypeTraits<VoxelType>::DensityType valueToWrite, VoxelType& voxel)
{
@ -54,6 +54,19 @@ void writeDensityValueToVoxel(typename VoxelTypeTraits<MaterialDensityPair88>::D
voxel.setDensity(valueToWrite);
}
template<typename VoxelType>
void writeMaterialValueToVoxel(typename VoxelTypeTraits<VoxelType>::MaterialType valueToWrite, VoxelType& voxel)
{
//Most types don't have a material
return;
}
template<>
void writeMaterialValueToVoxel(typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType valueToWrite, MaterialDensityPair88& voxel)
{
voxel.setMaterial(valueToWrite);
}
// Runs the surface extractor for a given type.
template <typename VoxelType>
void testForType(SurfaceMesh<PositionMaterialNormal>& result)
@ -69,9 +82,11 @@ void testForType(SurfaceMesh<PositionMaterialNormal>& result)
{
for (int32_t x = 0; x < uVolumeSideLength; x++)
{
//Create a density field which changes throughout the volume.
VoxelType voxelValue;
//Create a density field which changes throughout the volume.
writeDensityValueToVoxel<VoxelType>(x + y + z, voxelValue);
//Two different materials in two halves of the volume
writeMaterialValueToVoxel<VoxelType>(z > uVolumeSideLength / 2 ? 42 : 79, voxelValue);
volData.setVoxelAt(x, y, z, voxelValue);
}
}
@ -85,48 +100,61 @@ void TestSurfaceExtractor::testExecute()
{
const static uint32_t uExpectedVertices = 4731;
const static uint32_t uExpectedIndices = 12810;
const static uint32_t uMaterialToCheck = 3000;
const static float fExpectedMaterial = 42.0f;
const static float fNoMaterial = 1.0f;
SurfaceMesh<PositionMaterialNormal> mesh;
testForType<int8_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint8_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int16_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint16_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int32_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint32_t>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<float>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<double>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<Density8>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<MaterialDensityPair88>(mesh);
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial);
}
QTEST_MAIN(TestSurfaceExtractor)