It is currently Sat Aug 22, 2020 5:02 am


All times are UTC




Post new topic Reply to topic  [ 33 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
 Post subject: Polyvox to Ogre Mesh
PostPosted: Thu Apr 26, 2012 6:58 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
Hi guys, Ive recently switched from using a manualObject due to it's glitchy graphics when updated constantly so now Im using the Vertex and Index buffers to recreate the voxels but the generated meshes aren't in the shapes of voxels like they're suppsoed to be. I thought maybe my vertex declaration was wrong or my vertices wern't in the expected order. I'm not sure. Any thoughts?

Code:
void WorldCraft::PolyMeshToMesh(Polymesh &p)
{
   // ************ start mesh build code
   // Make a surfaceMesh from the voxelData
   SurfaceMesh<PositionMaterialNormal> mesh;
   SurfaceMesh<PositionMaterialNormal> mesh2;

   // Extract the surface
   //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing
   PolyVox::SurfaceExtractor<LargeVolume, Density8> surf(&volume, p.region, &mesh); // Use for semi-smooth surface
   //PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(pMesh.volume, pMesh.volume->getEnclosingRegion(), &mesh); // Use if not smoothing
   try {
      surf.execute();
   }
   catch(...) {
      cout << "Failed execute Surface Extractor" << endl;
   }
   
   // Change mesh to mesh2 if using decimation
   const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices();
   const std::vector<uint32_t>& vecIndices = mesh.getIndices();

   if( vecVertices.size() > 0 && vecIndices.size() > 0) {
      if (p.mMeshAttached == true){
         
         if(p.entity != NULL) {
            if(p.entity->isAttached()) {
               p.node->detachObject(p.entity);
               mKeyDevices.mSceneMgr->destroyEntity(p.entity);
            }
         }
         p.entity = mKeyDevices.mSceneMgr->createEntity("Polymesh");
         p.entity->setMaterialName("Worldcraft/Greengrass");
         p.node->attachObject(p.entity);
      }
      /// Create the mesh via the MeshManager
      p.meshOBJ = MeshManager::getSingleton().createManual("Polymesh", "General");
 
      /// Create one submesh
      p.submeshOBJ = p.meshOBJ->createSubMesh();

      // We first create a VertexData
      Ogre::VertexData* vertexData = new Ogre::VertexData();
      // Then, we link it to our Mesh/SubMesh :
      #ifdef SHARED_GEOMETRY
         mMesh->sharedVertexData = data;
      #else
         p.submeshOBJ->useSharedVertices = false; // This value is 'true' by default
         p.submeshOBJ->vertexData = vertexData;
      #endif

      // We have to provide the number of vertices we'll put into this Mesh/SubMesh
      vertexData->vertexCount = vecVertices.size();

      // Then we can create our VertexDeclaration
      Ogre::VertexDeclaration* decl = vertexData->vertexDeclaration;

      // define the vertex format
      VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
      size_t currOffset = 0;
      // positions
      vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
      //currOffset += VertexElement::getTypeSize(VET_FLOAT3);
      // normals
      //vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
      //currOffset += VertexElement::getTypeSize(VET_FLOAT3);
 
      // allocate the vertex buffer
      HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
      VertexBufferBinding* binding = vertexData->vertexBufferBinding;
      binding->setBinding(0, vBuf);
      float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

      // allocate index buffer
      Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
            Ogre::HardwareIndexBuffer::IT_16BIT,        // You can use several different value types here
            vecIndices.size(),                                  // The number of indices you'll put in that buffer
            Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY // Properties
         );

      unsigned short* pIndices = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
      
      if (p.node == NULL) {

         p.node = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode(p.position);
      }
   
      // Begin writing to manualObject
      unsigned int uLodLevel = 0;

      for(int index = 0; index < vecIndices.size(); index++) {
         const PolyVox::PositionMaterialNormal& vertex = vecVertices[vecIndices[index]];
         const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition();
         *pVertex++ = v3dVertexPos.getX();
         *pVertex++ = v3dVertexPos.getY();
         *pVertex++ = v3dVertexPos.getZ();

         *pIndices++ = vecIndices[index];

         //const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal();
         //*pVertex++ = v3dVertexNormal.getX();
         //*pVertex++ = v3dVertexNormal.getY();
         //*pVertex++ = v3dVertexNormal.getZ();
      }
      vBuf->unlock();
      ibuf->unlock();

      /// Set parameters of the submesh
      p.submeshOBJ->indexData->indexBuffer = ibuf;
      p.submeshOBJ->indexData->indexCount = vecIndices.size();
      p.submeshOBJ->indexData->indexStart = 0;
 
      /// Set bounding information (for culling)
      p.meshOBJ->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100));
      p.meshOBJ->_setBoundingSphereRadius(Math::Sqrt(3*100*100));
 
      /// Notify -Mesh object that it has been loaded
      p.meshOBJ->load();

      if (p.mMeshAttached == false){
         p.entity = mKeyDevices.mSceneMgr->createEntity("Polymesh");
         p.entity->setMaterialName("Worldcraft/Greengrass");
         p.node->attachObject(p.entity);
         p.mMeshAttached = true;
      }
   }
   // Deleted voxel area
   else {
      if(p.entity != NULL) {
         if(p.entity->isAttached()) {
            p.node->detachObject(p.entity);
            mKeyDevices.mSceneMgr->destroyEntity(p.entity);
         }
      }
   }
}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Fri Apr 27, 2012 4:38 pm 

Joined: Sun Jan 08, 2012 10:00 am
Posts: 31
Location: Germany
excuse im not sure but this looks for me not correct, cause you get the vertex through the indices and i think in this way you get some vertices multiple times. you should use two forloops for vertices and indices?:
Code:
for(int index = 0; index < vecIndices.size(); index++) {
         const PolyVox::PositionMaterialNormal& vertex = vecVertices[vecIndices[index]];
         const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition();
         *pVertex++ = v3dVertexPos.getX();
         *pVertex++ = v3dVertexPos.getY();
         *pVertex++ = v3dVertexPos.getZ();

         *pIndices++ = vecIndices[index];

}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Fri Apr 27, 2012 7:01 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
Hmm, I tried like this without much better results -

Code:
      // Indices ( faces )
      for(int index = 0; index < vecIndices.size(); index++) {
         *pIndices++ = vecIndices[index];
      }
      // Vertices ( verts )
      for(int index = 0; index < vecVertices.size(); index++) {
         const PolyVox::PositionMaterialNormal& vertex = vecVertices[index];
         const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition();
         *pVertex++ = v3dVertexPos.getX();
         *pVertex++ = v3dVertexPos.getY();
         *pVertex++ = v3dVertexPos.getZ();


      }


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sat Apr 28, 2012 10:30 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
The code is quite long so it's not obvious to me what the problem is, but does it appear to be a problem with PolyVox? For example, if you bypass PolyVox and just pass in hardcoded position and index values then does the mesh show up where you expect?

Switching to wireframe might also help identify the problem?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sat Jun 09, 2012 2:00 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I've revamped my code but I still have trouble getting the entire mesh to display. Sometimes - especially when trying to display multiple PolyMeshes which is just the voxel representation of that region. You'll see what I mean by the picture - the mesh should have a top and full sides, but it doesn't. If I click to add to the top, then the top will show for some reason. Here's my updated code also -

Code:
// RECENT PolyMeshToMesh
bool WorldCraft::PolyMeshToMesh(Polymesh &p)
{
   // ************ start mesh build code
   // Make a surfaceMesh from the voxelData


   // Extract the surface
   //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing
   PolyVox::CubicSurfaceExtractorWithNormals<LargeVolume, Density8> surf(&volume, p.region, &mesh); // Use for semi-smooth surface
   //PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(pMesh.volume, pMesh.volume->getEnclosingRegion(), &mesh); // Use if not smoothing
   try {
      surf.execute();
   }
   catch(...) {
      cout << "Failed execute Surface Extractor" << endl;
   }
   vertsAppended = false;
   indicesAppended = false;
   if (p.mMeshAttached == true){
         //p.meshOBJ->unload();
            // Destroy all the attached objects
         SceneNode::ObjectIterator itObject = p.node->getAttachedObjectIterator();
         while (itObject.hasMoreElements() )
         {
           Entity * pObject = static_cast<Entity *>(itObject.getNext());
           String name = pObject->getName();
           if (name.compare(0,10,"nodeMarker") != 0) {
              pObject->detachFromParent();
              mKeyDevices.mSceneMgr->destroyEntity( pObject );
           }
         }
         p.entity = NULL;
         Ogre::MeshManager::getSingleton().remove("CustomMesh"+ Ogre::StringConverter::toString(p.position / divisor));

   }
   if( vecVertices.size() > 0 && vecIndices.size() > 0) {

      /// Create the mesh via the MeshManager
       Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = MeshManager::getSingleton().createOrRetrieve("CustomMesh"+ Ogre::StringConverter::toString(p.position / divisor), "General", true,tfm,0,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,false,false);
       p.meshOBJ = result.first;
         
         /// Create one submesh
         p.submeshOBJ = p.meshOBJ->createSubMesh();      
         // We first create a VertexData
         // Then, we link it to our Mesh/SubMesh :
         #ifdef SHARED_GEOMETRY
            mMesh->sharedVertexData = data;
         #else
            p.submeshOBJ->useSharedVertices = false; // This value is 'true' by default
            p.submeshOBJ->vertexData =  new Ogre::VertexData();
         #endif



      // We have to provide the number of vertices we'll put into this Mesh/SubMesh
      p.submeshOBJ->vertexData->vertexCount = vecVertices.size();

      // Then we can create our VertexDeclaration
      Ogre::VertexDeclaration* decl = p.submeshOBJ->vertexData->vertexDeclaration;

      // define the vertex format
      VertexDeclaration* vertexDecl = p.submeshOBJ->vertexData->vertexDeclaration;
      size_t currOffset = 0;
      // positions
      vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
 
      // allocate the vertex buffer
      HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), p.submeshOBJ->vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false);
      VertexBufferBinding* binding = p.submeshOBJ->vertexData->vertexBufferBinding;
      binding->setBinding(0, vBuf);
      float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

      // allocate index buffer
      Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
            Ogre::HardwareIndexBuffer::IT_16BIT,        // You can use several different value types here
            vecIndices.size(),                                  // The number of indices you'll put in that buffer
            Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE // Properties
         );

      unsigned short* pIndices = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
      
      // Create new Scene Node
      if (p.node == NULL) {

         p.node = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode(p.position);
      }

      // Print debug info to gui windows
      showDebugStats(p);

      // Begin writing to manualObject
      unsigned int uLodLevel = 0;
      for(int v = 0; v < vecVertices.size(); v++)
      {
         PolyVox::PositionMaterialNormal vertex = vecVertices[v];
         const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition();
         *pVertex++ = v3dVertexPos.getX();
         *pVertex++ = v3dVertexPos.getY();
         *pVertex++ = v3dVertexPos.getZ();
      }
      for(int index = 0; index < vecIndices.size(); index++)
      {
         *pIndices++ = vecIndices.at(index);
      }

      vBuf->unlock();
      ibuf->unlock();

      /// Set parameters of the submesh
      p.submeshOBJ->indexData->indexBuffer = ibuf;
      p.submeshOBJ->indexData->indexCount = vecIndices.size();
      p.submeshOBJ->indexData->indexStart = 0;
 
      /// Set bounding information (for culling)
      AxisAlignedBox aabox = AxisAlignedBox(0, 0, 0, divisor, divisor, divisor);
      p.meshOBJ->_setBounds(aabox);
      p.meshOBJ->_setBoundingSphereRadius((aabox.getMaximum()-aabox.getMinimum()).length()/2.0);

      /// Notify -Mesh object that it has been loaded
      if(p.mMeshAttached == false) p.meshOBJ->load();
      p.entity = mKeyDevices.mSceneMgr->createEntity("CustomMesh"+ Ogre::StringConverter::toString(p.position / divisor));
      p.entity->setMaterialName("Worldcraft/Greengrass");
      p.node->attachObject(p.entity);

      if (p.mMeshAttached == false) p.mMeshAttached = true;
      return true;
   }
   return false;
}


Attachments:
partial-mesh.gif
partial-mesh.gif [ 82.09 KiB | Viewed 7010 times ]
Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sat Jun 09, 2012 2:38 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
Video showing some meshes not showing all sides. I wanted to add that it seems that this usually occurs when the face that's missing is exactly on a mesh region seam. My PolyMesh regions are split by 32 x 32 x 32 voxels.
http://www.youtube.com/watch?v=sclXcaDl2-4&feature=youtu.be

This could be a Polyvox problem, but to me it seems as though the missing verts and faces were never sent to the buffer somehow. Which seems wrong considering they are the face of the region / mesh.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sat Jun 09, 2012 6:05 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I notice you're not actually using the normal... so can you try the CubicSurfaceExtractor rather than the CubicSurfaceExtractorWithNormals? Does the problem still occur? There are/were some issues with the 'WithNormals' version but I forget the details.

Also (at least with the CubicSurfaceExtractor) the descision whether to create a quad can depend on voxels outside of the region you are extracting. Imagine you have a solid voxel on the edge of your region, and the next voxel (just outside your region) is also solid. In this case no quad should be generated between the two voxels because they are both solid. I'm not sure if this is the situation you are facing though.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sun Jun 10, 2012 2:32 am 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I tried it and the results are pretty much the same. It's much more noticable and reoccuring if I try to fill a large area filling in multiple regions


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Sun Jun 10, 2012 6:49 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
When you modify a particular voxel, which regions do you then regenerate the mesh for? I'm guessing you are only regenerating the mesh for the region which contains the voxel you modified? Actually, if the voxel lies on the edge of a region then you need to update the neighbouring region's mesh as well. Does that make sense?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Polyvox to Ogre Mesh
PostPosted: Mon Jun 11, 2012 5:17 am 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I'm only updating neighboring regions if I'm adding multiple voxels using a radius value - because I could be modifying voxels in neighboring regions. Yes, it makes sense, but why would I update a neighboring region for a single voxel?


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 33 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net