diff --git a/PolyVoxCore/include/IndexedSurfacePatch.h b/PolyVoxCore/include/IndexedSurfacePatch.h index 42fb0e91..65b4c26d 100644 --- a/PolyVoxCore/include/IndexedSurfacePatch.h +++ b/PolyVoxCore/include/IndexedSurfacePatch.h @@ -36,7 +36,7 @@ namespace PolyVox class POLYVOX_API IndexedSurfacePatch { public: - IndexedSurfacePatch(bool allowDuplicateVertices); + IndexedSurfacePatch(); ~IndexedSurfacePatch(); void addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2); @@ -52,20 +52,6 @@ namespace PolyVox public: std::vector m_vecTriangleIndices; std::vector m_vecVertices; - - static std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - static std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - static std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - - static std::int32_t noOfVerticesSubmitted; - static std::int32_t noOfVerticesAccepted; - static std::int32_t noOfTrianglesSubmitted; - - std::int32_t getIndexFor(const Vector3DFloat& pos); - void setIndexFor(const Vector3DFloat& pos, std::int32_t newIndex); - - public: - bool m_AllowDuplicateVertices; }; } diff --git a/PolyVoxCore/include/SurfaceExtractors.h b/PolyVoxCore/include/SurfaceExtractors.h index 748ad877..ad36f35d 100644 --- a/PolyVoxCore/include/SurfaceExtractors.h +++ b/PolyVoxCore/include/SurfaceExtractors.h @@ -45,6 +45,9 @@ namespace PolyVox POLYVOX_API void generateRoughVerticesForSlice(BlockVolumeIterator& volIter, Region& regSlice, const Vector3DFloat& offset, std::uint8_t* bitmask, IndexedSurfacePatch* singleMaterialPatch,std::int32_t vertexIndicesX[],std::int32_t vertexIndicesY[],std::int32_t vertexIndicesZ[]); POLYVOX_API void generateReferenceMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch); + + std::int32_t getIndexFor(const Vector3DFloat& pos, std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]); + void setIndexFor(const Vector3DFloat& pos, std::int32_t newIndex, std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]); } #endif diff --git a/PolyVoxCore/source/IndexedSurfacePatch.cpp b/PolyVoxCore/source/IndexedSurfacePatch.cpp index 747fbde7..00a863ce 100644 --- a/PolyVoxCore/source/IndexedSurfacePatch.cpp +++ b/PolyVoxCore/source/IndexedSurfacePatch.cpp @@ -25,19 +25,8 @@ using namespace std; namespace PolyVox { - int32_t IndexedSurfacePatch::noOfVerticesSubmitted = 0; - int32_t IndexedSurfacePatch::noOfVerticesAccepted = 0; - int32_t IndexedSurfacePatch::noOfTrianglesSubmitted = 0; - int32_t IndexedSurfacePatch::vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - int32_t IndexedSurfacePatch::vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - int32_t IndexedSurfacePatch::vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; - - IndexedSurfacePatch::IndexedSurfacePatch(bool allowDuplicateVertices) - :m_AllowDuplicateVertices(allowDuplicateVertices) + IndexedSurfacePatch::IndexedSurfacePatch() { - memset(vertexIndicesX,0xFF,sizeof(vertexIndicesX)); //0xFF is -1 as two's complement - this may not be portable... - memset(vertexIndicesY,0xFF,sizeof(vertexIndicesY)); - memset(vertexIndicesZ,0xFF,sizeof(vertexIndicesZ)); } IndexedSurfacePatch::~IndexedSurfacePatch() @@ -45,64 +34,13 @@ namespace PolyVox } void IndexedSurfacePatch::addTriangle(const SurfaceVertex& v0,const SurfaceVertex& v1,const SurfaceVertex& v2) - { - noOfTrianglesSubmitted++; - noOfVerticesSubmitted += 3; - if(!m_AllowDuplicateVertices) - { - int32_t index = getIndexFor(v0.getPosition()); - if(index == -1) - { - m_vecVertices.push_back(v0); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - setIndexFor(v0.getPosition(), m_vecVertices.size()-1); - - noOfVerticesAccepted++; - } - else - { - m_vecTriangleIndices.push_back(index); - } - - index = getIndexFor(v1.getPosition()); - if(index == -1) - { - m_vecVertices.push_back(v1); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - setIndexFor(v1.getPosition(), m_vecVertices.size()-1); - - noOfVerticesAccepted++; - } - else - { - m_vecTriangleIndices.push_back(index); - } - - index = getIndexFor(v2.getPosition()); - if(index == -1) - { - m_vecVertices.push_back(v2); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - setIndexFor(v2.getPosition(), m_vecVertices.size()-1); - - noOfVerticesAccepted++; - } - else - { - m_vecTriangleIndices.push_back(index); - } - } - else - { - m_vecVertices.push_back(v0); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - m_vecVertices.push_back(v1); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - m_vecVertices.push_back(v2); - m_vecTriangleIndices.push_back(m_vecVertices.size()-1); - - noOfVerticesAccepted += 3; - } + { + m_vecVertices.push_back(v0); + m_vecTriangleIndices.push_back(m_vecVertices.size()-1); + m_vecVertices.push_back(v1); + m_vecTriangleIndices.push_back(m_vecVertices.size()-1); + m_vecVertices.push_back(v2); + m_vecTriangleIndices.push_back(m_vecVertices.size()-1); } void IndexedSurfacePatch::fillVertexAndIndexData(std::vector& vecVertices, std::vector& vecIndices) @@ -120,71 +58,6 @@ namespace PolyVox }*/ } - std::int32_t IndexedSurfacePatch::getIndexFor(const Vector3DFloat& pos) - { - assert(pos.getX() >= 0.0f); - assert(pos.getY() >= 0.0f); - assert(pos.getZ() >= 0.0f); - assert(pos.getX() <= POLYVOX_REGION_SIDE_LENGTH); - assert(pos.getY() <= POLYVOX_REGION_SIDE_LENGTH); - assert(pos.getZ() <= POLYVOX_REGION_SIDE_LENGTH); - - float xIntPart; - float xFracPart = std::modf(pos.getX(), &xIntPart); - float yIntPart; - float yFracPart = std::modf(pos.getY(), &yIntPart); - float zIntPart; - float zFracPart = std::modf(pos.getZ(), &zIntPart); - - //Of all the fractional parts, two should be zero and one should have a value. - if(xFracPart > 0.000001f) - { - return vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; - } - if(yFracPart > 0.000001f) - { - return vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; - } - if(zFracPart > 0.000001f) - { - return vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; - } - while(true); - } - - void IndexedSurfacePatch::setIndexFor(const Vector3DFloat& pos, std::int32_t newIndex) - { - assert(pos.getX() >= 0.0f); - assert(pos.getY() >= 0.0f); - assert(pos.getZ() >= 0.0f); - assert(pos.getX() <= POLYVOX_REGION_SIDE_LENGTH); - assert(pos.getY() <= POLYVOX_REGION_SIDE_LENGTH); - assert(pos.getZ() <= POLYVOX_REGION_SIDE_LENGTH); - - assert(newIndex < 10000); - - float xIntPart; - float xFracPart = std::modf(pos.getX(), &xIntPart); - float yIntPart; - float yFracPart = std::modf(pos.getY(), &yIntPart); - float zIntPart; - float zFracPart = std::modf(pos.getZ(), &zIntPart); - - //Of all the fractional parts, two should be zero and one should have a value. - if(xFracPart > 0.000001f) - { - vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; - } - if(yFracPart > 0.000001f) - { - vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; - } - if(zFracPart > 0.000001f) - { - vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; - } - } - const std::vector& IndexedSurfacePatch::getVertices(void) const { return m_vecVertices; diff --git a/PolyVoxCore/source/SurfaceExtractors.cpp b/PolyVoxCore/source/SurfaceExtractors.cpp index 1c04ba41..dbb82fba 100644 --- a/PolyVoxCore/source/SurfaceExtractors.cpp +++ b/PolyVoxCore/source/SurfaceExtractors.cpp @@ -27,12 +27,12 @@ namespace PolyVox { //Generate the surface RegionGeometry regionGeometry; - regionGeometry.m_patchSingleMaterial = new IndexedSurfacePatch(false); + regionGeometry.m_patchSingleMaterial = new IndexedSurfacePatch(); regionGeometry.m_v3dRegionPosition = iterChangedRegions->getLowerCorner(); - //generateDecimatedMeshDataForRegion(volume.getVolumeData(), 0, *iterChangedRegions, regionGeometry.m_patchSingleMaterial); + generateDecimatedMeshDataForRegion(volume.getVolumeData(), 1, *iterChangedRegions, regionGeometry.m_patchSingleMaterial); - generateReferenceMeshDataForRegion(volume.getVolumeData(), *iterChangedRegions, regionGeometry.m_patchSingleMaterial); + //generateReferenceMeshDataForRegion(volume.getVolumeData(), *iterChangedRegions, regionGeometry.m_patchSingleMaterial); //for(int ct = 0; ct < 2; ct++) Vector3DInt32 temp = regionGeometry.m_v3dRegionPosition; @@ -578,6 +578,14 @@ namespace PolyVox void generateReferenceMeshDataForRegion(BlockVolume* volumeData, Region region, IndexedSurfacePatch* singleMaterialPatch) { + static std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + static std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + static std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]; + + memset(vertexIndicesX,0xFF,sizeof(vertexIndicesX)); //0xFF is -1 as two's complement - this may not be portable... + memset(vertexIndicesY,0xFF,sizeof(vertexIndicesY)); + memset(vertexIndicesZ,0xFF,sizeof(vertexIndicesZ)); + //When generating the mesh for a region we actually look one voxel outside it in the // back, bottom, right direction. Protect against access violations by cropping region here Region regVolume = volumeData->getEnclosingRegion(); @@ -778,26 +786,113 @@ namespace PolyVox const uint8_t material2 = vertMaterials[triTable[iCubeIndex][i+2]]; //If all the materials are the same, we just need one triangle for that material with all the alphas set high. - SurfaceVertex surfaceVertex0Alpha1(vertex0, normal0, material0 + 0.1f); - SurfaceVertex surfaceVertex1Alpha1(vertex1, normal1, material1 + 0.1f); - SurfaceVertex surfaceVertex2Alpha1(vertex2, normal2, material2 + 0.1f); - singleMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); + SurfaceVertex v0(vertex0, normal0, material0 + 0.1f); + SurfaceVertex v1(vertex1, normal1, material1 + 0.1f); + SurfaceVertex v2(vertex2, normal2, material2 + 0.1f); + + //singleMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); + + int32_t index = getIndexFor(v0.getPosition(), vertexIndicesX, vertexIndicesY, vertexIndicesZ); + if(index == -1) + { + singleMaterialPatch->m_vecVertices.push_back(v0); + singleMaterialPatch->m_vecTriangleIndices.push_back(singleMaterialPatch->m_vecVertices.size()-1); + setIndexFor(v0.getPosition(), singleMaterialPatch->m_vecVertices.size()-1, vertexIndicesX, vertexIndicesY, vertexIndicesZ); + } + else + { + singleMaterialPatch->m_vecTriangleIndices.push_back(index); + } + + index = getIndexFor(v1.getPosition(), vertexIndicesX, vertexIndicesY, vertexIndicesZ); + if(index == -1) + { + singleMaterialPatch->m_vecVertices.push_back(v1); + singleMaterialPatch->m_vecTriangleIndices.push_back(singleMaterialPatch->m_vecVertices.size()-1); + setIndexFor(v1.getPosition(), singleMaterialPatch->m_vecVertices.size()-1, vertexIndicesX, vertexIndicesY, vertexIndicesZ); + } + else + { + singleMaterialPatch->m_vecTriangleIndices.push_back(index); + } + + index = getIndexFor(v2.getPosition(), vertexIndicesX, vertexIndicesY, vertexIndicesZ); + if(index == -1) + { + singleMaterialPatch->m_vecVertices.push_back(v2); + singleMaterialPatch->m_vecTriangleIndices.push_back(singleMaterialPatch->m_vecVertices.size()-1); + setIndexFor(v2.getPosition(), singleMaterialPatch->m_vecVertices.size()-1, vertexIndicesX, vertexIndicesY, vertexIndicesZ); + } + else + { + singleMaterialPatch->m_vecTriangleIndices.push_back(index); + } }//For each triangle }//For each cell + } - //FIXME - can it happen that we have no vertices or triangles? Should exit early? + std::int32_t getIndexFor(const Vector3DFloat& pos, std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]) + { + assert(pos.getX() >= 0.0f); + assert(pos.getY() >= 0.0f); + assert(pos.getZ() >= 0.0f); + assert(pos.getX() <= POLYVOX_REGION_SIDE_LENGTH); + assert(pos.getY() <= POLYVOX_REGION_SIDE_LENGTH); + assert(pos.getZ() <= POLYVOX_REGION_SIDE_LENGTH); + float xIntPart; + float xFracPart = std::modf(pos.getX(), &xIntPart); + float yIntPart; + float yFracPart = std::modf(pos.getY(), &yIntPart); + float zIntPart; + float zFracPart = std::modf(pos.getZ(), &zIntPart); - //for(std::map::iterator iterPatch = surfacePatchMapResult.begin(); iterPatch != surfacePatchMapResult.end(); ++iterPatch) - /*{ + //Of all the fractional parts, two should be zero and one should have a value. + if(xFracPart > 0.000001f) + { + return vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + if(yFracPart > 0.000001f) + { + return vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + if(zFracPart > 0.000001f) + { + return vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + while(true); + } - std::vector::iterator iterSurfaceVertex = singleMaterialPatch->getVertices().begin(); - while(iterSurfaceVertex != singleMaterialPatch->getVertices().end()) - { - Vector3DFloat tempNormal = computeNormal(volumeData, static_cast(iterSurfaceVertex->getPosition() + offset), CENTRAL_DIFFERENCE); - const_cast(*iterSurfaceVertex).setNormal(tempNormal); - ++iterSurfaceVertex; - } - }*/ + void setIndexFor(const Vector3DFloat& pos, std::int32_t newIndex, std::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1], std::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1][POLYVOX_REGION_SIDE_LENGTH+1]) + { + assert(pos.getX() >= 0.0f); + assert(pos.getY() >= 0.0f); + assert(pos.getZ() >= 0.0f); + assert(pos.getX() <= POLYVOX_REGION_SIDE_LENGTH); + assert(pos.getY() <= POLYVOX_REGION_SIDE_LENGTH); + assert(pos.getZ() <= POLYVOX_REGION_SIDE_LENGTH); + + assert(newIndex < 10000); + + float xIntPart; + float xFracPart = std::modf(pos.getX(), &xIntPart); + float yIntPart; + float yFracPart = std::modf(pos.getY(), &yIntPart); + float zIntPart; + float zFracPart = std::modf(pos.getZ(), &zIntPart); + + //Of all the fractional parts, two should be zero and one should have a value. + if(xFracPart > 0.000001f) + { + vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } + if(yFracPart > 0.000001f) + { + vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } + if(zFracPart > 0.000001f) + { + vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } } } diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 4337a6ed..41d1b882 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -150,7 +150,7 @@ void main ( int argc, char** argv ) // Create Main Function For Bringing It Al { for(uint16_t uRegionX = 0; uRegionX < g_uVolumeSideLengthInRegions; ++uRegionX) { - g_ispRegionSurfaces[uRegionX][uRegionY][uRegionZ] = new IndexedSurfacePatch(false); + g_ispRegionSurfaces[uRegionX][uRegionY][uRegionZ] = new IndexedSurfacePatch(); IndexedSurfacePatch* ispCurrent = g_ispRegionSurfaces[uRegionX][uRegionY][uRegionZ]; Vector3DInt32 regLowerCorner(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength); Vector3DInt32 regUpperCorner((uRegionX + 1) * g_uRegionSideLength, (uRegionY + 1) * g_uRegionSideLength, (uRegionZ + 1) * g_uRegionSideLength);