Page 1 of 1

PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Thu Nov 10, 2011 12:39 pm
by Virror
Posted this on the PolyVox forum and thought i could post it here as well if anyone wants to try out PolyVox.
This class can be used to instead of the standard SurfaceExtractor class to extract directly into a CDynamicMeshBuffer instead of converting it into a PolyVox mesh and than have to convert it into a Irrlicht mesh.
Should speed things up a bit and make integration easier.

PolyVox webside

Example:

Code: Select all

//Include files needed for PolyVox
#include "PolyVoxCore/MaterialDensityPair.h"
#include "PolyVoxCore/CubicSurfaceExtractorWithNormals.h"
#include "PolyVoxCore/SurfaceMesh.h"
#include "PolyVoxCore/SimpleVolume.h"
 
//Create the volume that contains the actual voxel data and make it 64x64x64
SimpleVolume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63)));
 
//This vector hold the position of the center of the volume
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
 
//Create a simple sphere
//This three-level for loop iterates over every voxel in the volume
for (int z = 0; z < volData.getWidth(); z++)
{
    for (int y = 0; y < volData.getHeight(); y++)
    {
        for (int x = 0; x < volData.getDepth(); x++)
        {
            //Store our current position as a vector...
            Vector3DFloat v3dCurrentPos(x,y,z);
 
            //And compute how far the current position is from the center of the volume
            float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();
 
            //If the current voxel is less than 'radius' units from the center then we make it solid.
            if(fDistToCenter <= fRadius)
            {
                //Our new density value
                uint8_t uDensity = MaterialDensityPair44::getMaxDensity();
                
                //Get the old voxel
                MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z);
 
                //Modify the density
                voxel.setDensity(uDensity);
 
                //Wrte the voxel value into the volume
                volData.setVoxelAt(x, y, z, voxel);
            }
        }
    }
}
 
//Create a new meshBuffer
CDynamicMeshBuffer *newBuffer = new CDynamicMeshBuffer(EVT_STANDARD, EIT_32BIT);
 
//Create a new mesh extractor for making a mesh out of the voxel data
IrrSurfaceExtractor<SimpleVolume, MaterialDensityPair44 > irrsurfaceExtractor(volData, volData->getEnclosingRegion(), newBuffer);
 
//Execute the extractor
irrsurfaceExtractor.execute();
 
//Create the scene node
SMesh * newMesh = new SMesh;
newMesh->addMeshBuffer(newBuffer);
newMesh->recalculateBoundingBox();
ISceneNode * newNode = SceneManager->addMeshSceneNode(newMesh, Parent, ID, Position, Rotation, Scale);
newMesh->drop();
newBuffer->drop();
Download link:
IrrSurfaceExtractor

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Thu Nov 10, 2011 3:35 pm
by serengeor
Download not working :\

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Thu Nov 10, 2011 5:01 pm
by Virror
Edit: Should be fixed now : )

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Thu Nov 17, 2011 5:28 pm
by christianclavet
Virror, is there an example to show how to use it?

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Thu Nov 17, 2011 5:40 pm
by Virror
Well, you should read the PolyVox example on how to use that part, then you can just use this one instead of the original SurfaceExtractor.
Note that if you are yousing the example, they use the cubicsurfaceextractor, so you need to change the include to "surfaceextractor.h" instead of "cubicsurfaceextractor.h"
Maybe i can make a short example later tonight, have to make food and stuff now : p

Edit: Copied the example from the PolyVox webpage and expanded it with some Irrlicht stuff, this should be all you need to get started i hope.
Just give me a tell or post here i you need any help.

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Sat Jan 14, 2012 3:53 pm
by stoertebecker
hey virror, if i use

Code: Select all

   PolyVox::IrrSurfaceExtractor<PolyVox::SimpleVolume, PolyVox::MaterialDensityPair44 > irrsurfaceExtractor(&volData,   volData.getEnclosingRegion(), newBuffer);
instead of

Code: Select all

   IrrSurfaceExtractor<SimpleVolume, MaterialDensityPair44 > irrsurfaceExtractor(volData, volData->getEnclosingRegion(), newBuffer);
and

Code: Select all

   irrsurfaceExtractor.execute();
   printf("%i ",newBuffer->getVertexCount());
   printf("%i ",newBuffer->getIndexCount());
   //Create the scene node
   SMesh * newMesh = new SMesh;
   newMesh->addMeshBuffer(newBuffer);
   newMesh->recalculateBoundingBox();
   ISceneNode * newNode = smgr->addMeshSceneNode(newMesh);
   ...
i get for a 2-radiussphereexample 78 vertices and 456 indices -
But the node isnt displayed (other nodes are displayed), whats the problem please?
trying to display the buffer with driver->drawMeshBuffer(newBuffer); the same, no display

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Sun Jan 15, 2012 10:37 am
by stoertebecker
hey virror ok i found my problem, wasnt your code, my irrlicht 1.7.2 was broken dont know why, with a fresh new from sourceforge it works.
thanks for your extractor.

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Mon Jan 16, 2012 8:57 am
by Virror
Nice that it works : )

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Sun Dec 01, 2013 3:43 am
by Cube_
Oh welp, sorry for the necropost but the link is dead.

Re: PolyVox Surface extractor for Irrlicht mesh buffer.

Posted: Tue Jan 07, 2014 10:42 pm
by Neirdan
I played a bit with polyvox before making my homebrew voxel engine (polyvox's performances were shitty regarding surfaces batching):

Here are two things I used:
I think commented stuff is for 16 bits buffer.

Code: Select all

 
irr::scene::SMesh* convertPolyMesh(const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& meshPoly) {
   //irr::scene::SMeshBuffer* buffer =new irr::scene::SMeshBuffer();
   irr::scene::IDynamicMeshBuffer* buffer =new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_32BIT);
   irr::video::SColor clr(255,255,255,255);
 
   const std::vector<uint32_t>& indices = meshPoly.getIndices();
   const std::vector<PolyVox::PositionMaterialNormal>& vertices = meshPoly.getVertices();
 
   // Create indices
   //buffer->Indices.set_used(indices.size());
//    for (size_t i=0; i<indices.size(); ++i) {
//        buffer->Indices[i] = indices[i];
//    }
   buffer->getIndexBuffer().set_used(indices.size());
   for (size_t i = 0; i < indices.size(); ++i) {
       buffer->getIndexBuffer().setValue(i, indices[i]);
   }
 
   // Create vertices
//    buffer->Vertices.reallocate(vertices.size());
//    for (size_t i = 0; i < vertices.size(); ++i) {
//        const PolyVox::Vector3DFloat& position = vertices[i].getPosition();
//        const PolyVox::Vector3DFloat& normal = vertices[i].getNormal();
//        buffer->Vertices.push_back(irr::video::S3DVertex(position.getX(),position.getY(),position.getZ(),normal.getX(),normal.getY(),normal.getZ(), clr, 0, 0));
//    }
   buffer->getVertexBuffer().set_used(vertices.size());
   for (size_t i = 0; i < vertices.size(); ++i) {
       const PolyVox::Vector3DFloat& position = vertices[i].getPosition();
       const PolyVox::Vector3DFloat& normal = vertices[i].getNormal();
       buffer->getVertexBuffer()[i].Pos.X = position.getX();
       buffer->getVertexBuffer()[i].Pos.Y = position.getY();
       buffer->getVertexBuffer()[i].Pos.Z = position.getZ();
       buffer->getVertexBuffer()[i].Normal.X = normal.getX();
       buffer->getVertexBuffer()[i].Normal.Y = normal.getY();
       buffer->getVertexBuffer()[i].Normal.Z = normal.getZ();
       buffer->getVertexBuffer()[i].Color = irr::video::SColor(255,255,255,255);
   }
 
   // Recalculate bounding box
   buffer->recalculateBoundingBox();
//    buffer->BoundingBox.reset(0,0,0);
//    for (u32 i=0; i<vertices.size(); ++i) {
//        buffer->BoundingBox.addInternalPoint(buffer->Vertices[i].Pos);
//    }
   //Create mesh
   irr::scene::SMesh* mesh =new irr::scene::SMesh;
   //irr::video::SMaterial mat;
   //buffer->Material=mat;
   mesh->addMeshBuffer(buffer);
   buffer->drop();
 
   mesh->recalculateBoundingBox();
   return mesh;
}
 
irr::scene::IMeshBuffer* ConvertMesh(const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& mesh) {
   const std::vector<uint32_t>& indices = mesh.getIndices();
   const std::vector<PolyVox::PositionMaterialNormal>& vertices = mesh.getVertices();
 
   irr::scene::IDynamicMeshBuffer *mb = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_32BIT);
 
   mb->getVertexBuffer().set_used(vertices.size());
   for (size_t i = 0; i < vertices.size(); ++i) {
       const PolyVox::Vector3DFloat& position = vertices[i].getPosition();
       const PolyVox::Vector3DFloat& normal = vertices[i].getNormal();
       mb->getVertexBuffer()[i].Pos.X = position.getX();
       mb->getVertexBuffer()[i].Pos.Y = position.getY();
       mb->getVertexBuffer()[i].Pos.Z = position.getZ();
       mb->getVertexBuffer()[i].Normal.X = normal.getX();
       mb->getVertexBuffer()[i].Normal.Y = normal.getY();
       mb->getVertexBuffer()[i].Normal.Z = normal.getZ();
       mb->getVertexBuffer()[i].Color = irr::video::SColor(255,0,200,200);
   }
 
   mb->getIndexBuffer().set_used(indices.size());
   for (size_t i = 0; i < indices.size(); ++i) {
       mb->getIndexBuffer().setValue(i, indices[i]);
   }
   mb->recalculateBoundingBox();
   return mb;
}
 
Used like this:

Code: Select all

 
//Transform voxel into mesh
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> mesh;
PolyVox::CubicSurfaceExtractorWithNormals< PolyVox::SimpleVolume<uint8_t> > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
//PolyVox::MarchingCubesSurfaceExtractor< PolyVox::SimpleVolume<uint8_t> > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();
 
//Transform mesh into irrlicht mesh
irr::scene::IMeshSceneNode* levelMesh=sceneManager->addMeshSceneNode(convertPolyMesh(mesh));