From a20db7d7cf5c3309077f35c0bb77f7fdf3c7d294 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Feb 2012 10:16:26 +0100 Subject: [PATCH] Work on refactoring voxel types. Expanded surface extractor test. --- library/PolyVoxCore/CMakeLists.txt | 1 + .../PolyVoxCore/include/PolyVoxCore/Density.h | 1 + .../include/PolyVoxCore/Material.h | 1 + .../include/PolyVoxCore/MaterialDensityPair.h | 13 +++++++ .../include/PolyVoxCore/PrimitiveVoxelTypes.h | 34 +++++++++++++++++++ .../include/PolyVoxCore/SurfaceExtractor.h | 20 +++++++++++ .../include/PolyVoxCore/SurfaceExtractor.inl | 34 ++++--------------- .../PolyVoxCore/include/PolyVoxCore/Voxel.h | 14 +------- .../source/MaterialDensityPair.cpp | 12 +++++++ tests/TestSurfaceExtractor.cpp | 32 +++++++++++++++-- 10 files changed, 119 insertions(+), 43 deletions(-) create mode 100644 library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 02e1ac56..7439a78c 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -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 diff --git a/library/PolyVoxCore/include/PolyVoxCore/Density.h b/library/PolyVoxCore/include/PolyVoxCore/Density.h index b6826319..11864da4 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Density.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Density.h @@ -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; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/Material.h b/library/PolyVoxCore/include/PolyVoxCore/Material.h index 8b905a0b..c50b3092 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Material.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Material.h @@ -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; } diff --git a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h index 7fb8bd74..a7ff429c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h @@ -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::DensityType convertToDensity(MaterialDensityPair44 voxel); template<> typename VoxelTypeTraits::DensityType convertToDensity(MaterialDensityPair88 voxel); + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair44 voxel); + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair88 voxel); } #endif \ No newline at end of file diff --git a/library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h b/library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h new file mode 100644 index 00000000..bf1552ca --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/PrimitiveVoxelTypes.h @@ -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__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h index ec8d9b0c..aa42dc53 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.h @@ -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 VoxelTypeTraits::MaterialType convertToMaterial(VoxelType voxel) + { + return 1; + } + template< template class VolumeType, typename VoxelType> class SurfaceExtractor { diff --git a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl index 736dcd57..29302aa0 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SurfaceExtractor.inl @@ -391,28 +391,6 @@ namespace PolyVox } } - template - struct getMaterialFromVoxel; - - template - struct getMaterialFromVoxel - { - static uint32_t run(VoxelType voxel) - { - return voxel.getMaterial(); - } - }; - - template - struct getMaterialFromVoxel - { - static uint32_t run(VoxelType voxel) - { - return 0; - } - }; - - template< template class VolumeType, typename VoxelType> void SurfaceExtractor::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::HasMaterial>::run(v000); - uint32_t uMaterial100 = getMaterialFromVoxel::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(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::HasMaterial>::run(v000); - uint32_t uMaterial010 = getMaterialFromVoxel::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(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::HasMaterial>::run(v000); - uint32_t uMaterial001 = getMaterialFromVoxel::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(uMaterial)); diff --git a/library/PolyVoxCore/include/PolyVoxCore/Voxel.h b/library/PolyVoxCore/include/PolyVoxCore/Voxel.h index 48a8f406..2bf47a7b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Voxel.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Voxel.h @@ -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__ diff --git a/library/PolyVoxCore/source/MaterialDensityPair.cpp b/library/PolyVoxCore/source/MaterialDensityPair.cpp index ee3515cf..374fff2f 100644 --- a/library/PolyVoxCore/source/MaterialDensityPair.cpp +++ b/library/PolyVoxCore/source/MaterialDensityPair.cpp @@ -36,4 +36,16 @@ namespace PolyVox { return voxel.getDensity(); } + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair44 voxel) + { + return voxel.getMaterial(); + } + + template<> + typename VoxelTypeTraits::MaterialType convertToMaterial(MaterialDensityPair88 voxel) + { + return voxel.getMaterial(); + } } \ No newline at end of file diff --git a/tests/TestSurfaceExtractor.cpp b/tests/TestSurfaceExtractor.cpp index 77e403e7..2f633d76 100644 --- a/tests/TestSurfaceExtractor.cpp +++ b/tests/TestSurfaceExtractor.cpp @@ -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 void writeDensityValueToVoxel(typename VoxelTypeTraits::DensityType valueToWrite, VoxelType& voxel) { @@ -54,6 +54,19 @@ void writeDensityValueToVoxel(typename VoxelTypeTraits::D voxel.setDensity(valueToWrite); } +template +void writeMaterialValueToVoxel(typename VoxelTypeTraits::MaterialType valueToWrite, VoxelType& voxel) +{ + //Most types don't have a material + return; +} + +template<> +void writeMaterialValueToVoxel(typename VoxelTypeTraits::MaterialType valueToWrite, MaterialDensityPair88& voxel) +{ + voxel.setMaterial(valueToWrite); +} + // Runs the surface extractor for a given type. template void testForType(SurfaceMesh& result) @@ -69,9 +82,11 @@ void testForType(SurfaceMesh& 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(x + y + z, voxelValue); + //Two different materials in two halves of the volume + writeMaterialValueToVoxel(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 mesh; testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); testForType(mesh); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); + QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial); } QTEST_MAIN(TestSurfaceExtractor)