diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index 309b0eda..5f4de9ab 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -23,7 +23,7 @@ freely, subject to the following restrictions: #include "OpenGLWidget.h" -#include "PolyVoxCore/MaterialDensityPair.h" +#include "PolyVoxCore/Material.h" #include "PolyVoxCore/CubicSurfaceExtractorWithNormals.h" #include "PolyVoxCore/SurfaceMesh.h" #include "PolyVoxCore/SimpleVolume.h" @@ -33,7 +33,7 @@ freely, subject to the following restrictions: //Use the PolyVox namespace using namespace PolyVox; -void createSphereInVolume(SimpleVolume& volData, float fRadius) +void createSphereInVolume(SimpleVolume& volData, float fRadius) { //This vector hold the position of the center of the volume Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2); @@ -50,22 +50,19 @@ void createSphereInVolume(SimpleVolume& volData, float fR //And compute how far the current position is from the center of the volume float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); - uint8_t uDensity = 0; uint8_t uMaterial = 0; //If the current voxel is less than 'radius' units from the center then we make it solid. if(fDistToCenter <= fRadius) { //Our new density value - uDensity = VoxelTypeTraits::maxDensity(); uMaterial = 1; } //Get the old voxel - MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z); + Material8 voxel = volData.getVoxelAt(x,y,z); //Modify the density and material - voxel.setDensity(uDensity); voxel.setMaterial(uMaterial); //Wrte the voxel value into the volume @@ -83,12 +80,12 @@ int main(int argc, char *argv[]) openGLWidget.show(); //Create an empty volume and then place a sphere in it - SimpleVolume volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63))); + SimpleVolume volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63))); createSphereInVolume(volData, 30); //Extract the surface SurfaceMesh mesh; - CubicSurfaceExtractorWithNormals surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); + CubicSurfaceExtractorWithNormals surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh, Material8::isQuadNeeded); surfaceExtractor.execute(); //Pass the surface to the OpenGL window diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h index dfba9482..ced5b677 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h @@ -35,11 +35,13 @@ namespace PolyVox class CubicSurfaceExtractorWithNormals { public: - CubicSurfaceExtractorWithNormals(VolumeType* volData, Region region, SurfaceMesh* result); + CubicSurfaceExtractorWithNormals(VolumeType* volData, Region region, SurfaceMesh* result, polyvox_function funcIsQuadNeededCallback); void execute(); private: + polyvox_function m_funcIsQuadNeededCallback; + //The volume data and a sampler to access it. VolumeType* m_volData; typename VolumeType::Sampler m_sampVolume; diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl index bf47a80b..f1955e94 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl @@ -24,12 +24,14 @@ freely, subject to the following restrictions: namespace PolyVox { template< template class VolumeType, typename VoxelType> - CubicSurfaceExtractorWithNormals::CubicSurfaceExtractorWithNormals(VolumeType* volData, Region region, SurfaceMesh* result) + CubicSurfaceExtractorWithNormals::CubicSurfaceExtractorWithNormals(VolumeType* volData, Region region, SurfaceMesh* result, polyvox_function funcIsQuadNeededCallback) :m_volData(volData) ,m_sampVolume(volData) ,m_meshCurrent(result) ,m_regSizeInVoxels(region) + ,m_funcIsQuadNeededCallback(funcIsQuadNeededCallback) { + assert(m_funcIsQuadNeededCallback); } template< template class VolumeType, typename VoxelType> @@ -48,12 +50,11 @@ namespace PolyVox float regY = static_cast(y - m_regSizeInVoxels.getLowerCorner().getY()); float regZ = static_cast(z - m_regSizeInVoxels.getLowerCorner().getZ()); - int currentVoxel = m_volData->getVoxelAt(x,y,z).getMaterial() != 0; + float material = 0.0f; - int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getMaterial() != 0; - if(currentVoxel > plusXVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x,y,z), m_volData->getVoxelAt(x+1,y,z), material)) { - float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material)); @@ -63,9 +64,9 @@ namespace PolyVox m_meshCurrent->addTriangleCubic(v0,v2,v1); m_meshCurrent->addTriangleCubic(v1,v2,v3); } - if(currentVoxel < plusXVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x+1,y,z), m_volData->getVoxelAt(x,y,z), material)) { - float material = static_cast(m_volData->getVoxelAt(x+1,y,z).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x+1,y,z).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material)); @@ -77,9 +78,9 @@ namespace PolyVox } int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getMaterial() != 0; - if(currentVoxel > plusYVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x,y,z), m_volData->getVoxelAt(x,y+1,z), material)) { - float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material)); @@ -89,9 +90,9 @@ namespace PolyVox m_meshCurrent->addTriangleCubic(v0,v1,v2); m_meshCurrent->addTriangleCubic(v1,v3,v2); } - if(currentVoxel < plusYVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x,y+1,z), m_volData->getVoxelAt(x,y,z), material)) { - float material = static_cast(m_volData->getVoxelAt(x,y+1,z).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x,y+1,z).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material)); @@ -103,9 +104,9 @@ namespace PolyVox } int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getMaterial() != 0; - if(currentVoxel > plusZVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x,y,z), m_volData->getVoxelAt(x,y,z+1), material)) { - float material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x,y,z).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material)); @@ -115,9 +116,9 @@ namespace PolyVox m_meshCurrent->addTriangleCubic(v0,v2,v1); m_meshCurrent->addTriangleCubic(v1,v2,v3); } - if(currentVoxel < plusZVoxel) + if(m_funcIsQuadNeededCallback(m_volData->getVoxelAt(x,y,z+1), m_volData->getVoxelAt(x,y,z), material)) { - float material = static_cast(m_volData->getVoxelAt(x,y,z+1).getMaterial()); + material = static_cast(m_volData->getVoxelAt(x,y,z+1).getMaterial()); uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material)); uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material)); diff --git a/library/PolyVoxCore/include/PolyVoxCore/Material.h b/library/PolyVoxCore/include/PolyVoxCore/Material.h index 30e47f09..407cb540 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Material.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Material.h @@ -96,6 +96,19 @@ namespace PolyVox //static DensityType getminDensity()() throw() { return 0; } static DensityType getThreshold() throw() { return 1; } + static bool isQuadNeeded(Material from, Material to, float& materialToUse) + { + if((from.getMaterial() > 0) && (to.getMaterial() == 0)) + { + materialToUse = static_cast(from.getMaterial()); + return true; + } + else + { + return false; + } + } + private: MaterialType m_uMaterial; }; diff --git a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h index 93a5c8a3..86d1d95f 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h @@ -78,6 +78,19 @@ namespace PolyVox //static DensityType getminDensity()() throw() { return 0; } static DensityType getThreshold() throw() {return 0x01 << (NoOfDensityBits - 1);} + static bool isQuadNeeded(MaterialDensityPair from, MaterialDensityPair to, float& materialToUse) + { + if((from.getMaterial() > 0) && (to.getMaterial() == 0)) + { + materialToUse = static_cast(from.getMaterial()); + return true; + } + else + { + return false; + } + } + private: MaterialType m_uMaterial : NoOfMaterialBits; DensityType m_uDensity : NoOfDensityBits; diff --git a/library/PolyVoxCore/source/SimpleInterface.cpp b/library/PolyVoxCore/source/SimpleInterface.cpp index 3a61a51f..9925e5a2 100644 --- a/library/PolyVoxCore/source/SimpleInterface.cpp +++ b/library/PolyVoxCore/source/SimpleInterface.cpp @@ -31,7 +31,7 @@ namespace PolyVox { void extractCubicMesh(Volume& volume, const Region& region, Mesh& resultMesh) { - CubicSurfaceExtractorWithNormals surfaceExtractor(&volume, region, &resultMesh); + CubicSurfaceExtractorWithNormals surfaceExtractor(&volume, region, &resultMesh, MaterialDensityPair88::isQuadNeeded); surfaceExtractor.execute(); } diff --git a/tests/TestCubicSurfaceExtractor.cpp b/tests/TestCubicSurfaceExtractor.cpp index 6435c78a..1b289ee1 100644 --- a/tests/TestCubicSurfaceExtractor.cpp +++ b/tests/TestCubicSurfaceExtractor.cpp @@ -94,7 +94,7 @@ void testForType(SurfaceMesh& result) } } - CubicSurfaceExtractorWithNormals extractor(&volData, volData.getEnclosingRegion(), &result, 50); + CubicSurfaceExtractorWithNormals extractor(&volData, volData.getEnclosingRegion(), &result, VoxelType::isQuadNeeded); extractor.execute(); }