It is currently Sat Aug 22, 2020 4:30 am


All times are UTC




Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Thu Jan 03, 2013 8:41 pm 

Joined: Sat Mar 26, 2011 6:41 pm
Posts: 8
well i'm generating a mesh using a noise function to create variation in the density of the volume

the down side is that this generate several isolated group of polygon now what i'm wondering is if it would be possible to split these into separated mesh




also another question that just poped does the extractor extract the content of the volume with the center of the volme as 0,0,0 or with one of the corner as 0,0,0 cause i had some behaviour with irrlicht that sugest a decentered mesh


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Fri Jan 04, 2013 9:46 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
granyte wrote:
the down side is that this generate several isolated group of polygon now what i'm wondering is if it would be possible to split these into separated mesh


There is no easy way to do this. Actually I assume you don't know where the islands are until you see them, so you would first need a way of testing whether a given voxel was part of an island.

But why do you want to do this? Is it because you want to remove the floating islands, or you want them to somehow move seperatly from the rest of the scene?

granyte wrote:
also another question that just poped does the extractor extract the content of the volume with the center of the volme as 0,0,0 or with one of the corner as 0,0,0 cause i had some behaviour with irrlicht that sugest a decentered mesh


When you generate a mesh from a region the vertices range from a position of (0,0,0) up to the width/height/depth of the region. For example, imagine you have a Region(64,64,64, 95, 95,95). In this case the vertex position will range from (0,0,0) to (31,31,31) (or maybe (32,32,32)... it might depend on the extractor used). Before rendering you need to add the lower corner of the region (which in this case is (64,64,64) to the position of the vertices. ‌In practice you won't need to do this adding manually but you will instead set the transformation on some kind of node in your engine.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Fri Jan 04, 2013 11:51 am 

Joined: Sat Mar 26, 2011 6:41 pm
Posts: 8
Well at first i wanned to remove them and i have a quite good idea how to mod the noise i'm using to do it

but then i realised i could use them to have my entire asteroid field generated in one single shot by using instancing on the smaller other rock around multiplying them and having them move independantly.
I guess i could use some sort of flooding algorythm to test by picking one solid region flooding all that's connected to it then selecting an other region that was not flooded and so on until i have a discrete value distinguising every solid region.


Thanks well i'm better applying transformation to my vertex as otherwise is mess up the integrated animation system


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Sat Jan 05, 2013 8:06 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
If you can identify the bounds of each floating rock then yes, in theory you can run the surface extractor on just that region and get a seperate mesh for it. But in some cases you might find that two rocks are seperate but that thier bounds overlap so this might get more difficult.

And yes, I think a flooding algorithm would be a good approach to detecting them regardless of whether you want to remove them or generate a seperate mesh. Also, see slides 49-53 of this presentation.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Tue Feb 05, 2013 5:54 pm 
User avatar

Joined: Tue Feb 05, 2013 5:44 pm
Posts: 33
Hello, I've been attempting to get the voxel sphere demo to work in Irrlicht and for some reason getVertices().size() is zero.

Here is my code:

Code:
#include "include/irrlicht/irrlicht.h"
#include "include/PolyVoxCore/MaterialDensityPair.h"
#include "include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h"
#include "include/PolyVoxCore/MarchingCubesSurfaceExtractor.h"
#include "include/PolyVoxCore/SurfaceMesh.h"
#include "include/PolyVoxCore/SimpleVolume.h"
#include "include/PolyVoxCore/Vector.h"
#include "include/PolyVoxCore/VertexTypes.h"
#include "include/PolyVoxCore/Region.h"

/*
In the Irrlicht Engine, everything can be found in the namespace 'irr'. So if
you want to use a class of the engine, you have to write irr:: before the name
of the class. For example to use the IrrlichtDevice write: irr::IrrlichtDevice.
To get rid of the irr:: in front of the name of every class, we tell the
compiler that we use that namespace from now on, and we will not have to write
irr:: anymore.
*/
using namespace irr;

using namespace PolyVox;

/*
There are 5 sub namespaces in the Irrlicht Engine. Take a look at them, you can
read a detailed description of them in the documentation by clicking on the top
menu item 'Namespace List' or by using this link:
http://irrlicht.sourceforge.net/docu/namespaces.html
Like the irr namespace, we do not want these 5 sub namespaces now, to keep this
example simple. Hence, we tell the compiler again that we do not want always to
write their names.
*/
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;

/*
To be able to use the Irrlicht.DLL file, we need to link with the Irrlicht.lib.
We could set this option in the project settings, but to make it easy, we use a
pragma comment lib for VisualStudio. On Windows platforms, we have to get rid
of the console window, which pops up when starting a program with main(). This
is done by the second pragma. We could also use the WinMain method, though
losing platform independence then.
*/
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "PolyVoxCore.lib")
#endif


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());
   // This loop doesn't seem to be executed at all... in other words, vertices.size() == 0
   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();
      // Cubes should show up in bright green
      mb->getVertexBuffer()[i].Color = irr::video::SColor(255,0,255,0);
   }
   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;
}

void createSphereInVolume(SimpleVolume<MaterialDensityPair44>& 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);

   //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)
            {
               // This portion seems to be working correctly
               //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);
            }
         }
      }
   }
}

int main()
{
   IrrlichtDevice *device = createDevice(video::EDT_OPENGL, dimension2d<u32>(640, 480), 32, false, false, false, 0);

   if (!device)
      return 1;

   /*
   Get a pointer to the VideoDriver, the SceneManager and the graphical
   user interface environment, so that we do not always have to write
   device->getVideoDriver(), device->getSceneManager(), or
   device->getGUIEnvironment().
   */
   IVideoDriver* driver = device->getVideoDriver();
   ISceneManager* smgr = device->getSceneManager();
   IGUIEnvironment* guienv = device->getGUIEnvironment();

   //Create an empty volume and then place a sphere in it
   SimpleVolume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 31, 31)));
   createSphereInVolume(volData, 10.0F);

   SurfaceMesh<PositionMaterialNormal> mesh;

   // Extract the mesh
   CubicSurfaceExtractorWithNormals<SimpleVolume<MaterialDensityPair44>> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
   surfaceExtractor.execute();

   // Convert the mesh and hand it to Irrlicht
   SMesh* testMesh = new SMesh;
   IMeshBuffer * testBuffer = convertMesh(mesh);
   testMesh->addMeshBuffer(testBuffer);
   testMesh->recalculateBoundingBox();
   ISceneNode* testNode= smgr->addMeshSceneNode(testMesh, 0, 0, vector3df(0, 0, 0), vector3df(0, 0, 0),vector3df(1.0F, 1.0F, 1.0F));

   /*
   To look at the mesh, we place a camera into 3d space
   */
   ICameraSceneNode* camera = smgr->addCameraSceneNode(0, vector3df(0,0,0), vector3df(0,0,0));

   float pos = 0;

   /*
   Ok, now we have set up the scene, lets draw everything: We run the
   device in a while() loop, until the device does not want to run any
   more. This would be when the user closes the window or presses ALT+F4
   (or whatever keycode closes a window).
   */
   while(device->run())
   {
      /*
      Anything can be drawn between a beginScene() and an endScene()
      call. The beginScene() call clears the screen with a color and
      the depth buffer, if desired. Then we let the Scene Manager and
      the GUI Environment draw their content. With the endScene()
      call everything is presented on the screen.
      */
      camera->setPosition(vector3df(pos, 0.0F, 0.0F));
      driver->beginScene(true, true, SColor(255,100,101,140));

      smgr->drawAll();
      guienv->drawAll();

      driver->endScene();

      // Slowly move the camera away
      pos += 0.1F;
   }

   /*
   After we are done with the render loop, we have to delete the Irrlicht
   Device created before with createDevice(). In the Irrlicht Engine, you
   have to delete all objects you created with a method or function which
   starts with 'create'. The object is simply deleted by calling ->drop().
   See the documentation at irr::IReferenceCounted::drop() for more
   information.
   */
   device->drop();

   return 0;
}


Also I read in a change log that polyvox no longer uses density to check if voxels exist or not. What is used now if density is no longer used?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Tue Feb 05, 2013 7:34 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
You're working with the CubicSurfaceExtractor, and basically this now makes use of a callback function to determine whether to generate a face between any pair of adjacent voxels. A default callback is provided for all the built in types and in the case of the MaterialDensityPair (which is the voxel type you are using) it looks like this:

Code:
template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits>
class DefaultIsQuadNeeded< MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> >
{
public:
   bool operator()(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> back, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> front, uint32_t& materialToUse)
   {
      if((back.getMaterial() > 0) && (front.getMaterial() == 0)) // <-- This is the important line
      {
         materialToUse = static_cast<uint32_t>(back.getMaterial());
         return true;
      }
      else
      {
         return false;
      }
   }
};


As you can see, it only makes use of the matieral values to decide whether to generate a face. A face is generated when one voxel has material zero and the other does not. In your createSphereInVolume() function you should set the material to non-zero if inside the sphere. Something like this (untested):

Code:
//Get the old voxel
MaterialDensityPair44 voxel = volData.getVoxelAt(x,y,z);

//Modify the density
voxel.setDensity(uDensity);

//Modify the material
voxel.setMaterial(1); //        <-- Add this line

//Wrte the voxel value into the volume
volData.setVoxelAt(x, y, z, voxel);


Generally speaking I don't think it makes sense to use the MaterialDensityPair class for cubic terrain. You should just use Material, or even just an integer as is now done in the BasicExample.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Tue Feb 05, 2013 8:53 pm 
User avatar

Joined: Tue Feb 05, 2013 5:44 pm
Posts: 33
Excellent! It works now.

I was looking through the list of default voxel types for the one I need, but didn't find what I was looking for. I assume that I'll just go ahead and build a custom type for my needs at this point.

Two more questions: Why are positions for PositionMaterial stored in Vector3DFloat and not in Vector3DInteger? Why are the materials floats? I assume that the materials property works best for voxels that are textured, which is not what I am trying to achieve.

The voxel type that I need would probably have a position, and color (they are solid colored voxels). Is there a built in type for this sort of thing? I can't think of any sane way to represent a color in a single floating point value.

Edit:
Also most voxel tutorials that I've read suggest that you store data in chunks. However, polyvox recommends that you keep everything in a giant volume. Does this mean that the chunks should be split by the code that creates the meshes? Or something else?

Edit2: I've implemented a custom class that holds custom value colors, block health, and position. Anyway, the mesh only seems to contain position data and no information about colors. When the mesh is converted to an Irrlicht mesh, it needs to get the color information associated with the block. There doesn't seem to be a good way that I can think of to retrieve this information, since the only data you can get is the position of the vertices and not those of the block. All of the data is stuck in the SimpleVolume.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Wed Feb 06, 2013 9:17 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Dynasty wrote:
Why are positions for PositionMaterial stored in Vector3DFloat and not in Vector3DInteger?


Actually the positions are not integers (they are 'integers +/- 0.5') but I agree an integer could be used and the 0.5 offset applied separately. It's partly just because PositionMaterialNormal uses floats (the the Marching Cubes meshes are not integers) and partly because on the GPU using floats for positions is more widely supported (I think?).

Dynasty wrote:
Why are the materials floats?


This makes a bit less sense, but again it's because older versions of OpenGL/Direct3D only support passing floats as vertex data. Actually I'm not even sure if that is true :-S But the idea was that you can just do a memcpy() from the data generated by PolyVox into your APIs vertex buffer.

Anyway, I agree it's a bit odd, and on our experimental branch we've actually started templatising the PositionMaterial class on the material type, so that the vertices can get the same material information that was in the voxel. You can see it here:

https://bitbucket.org/volumesoffun/poly ... sion#cl-39

But I think it will be a while before this change gets merged back into the main branch.

Dynasty wrote:
I assume that the materials property works best for voxels that are textured, which is not what I am trying to achieve.


Basically yes, it was designed to pass a material identifier in which case a single numerical value (even in a float) is sufficient.

Dynasty wrote:
The voxel type that I need would probably have a position, and color (they are solid colored voxels). Is there a built in type for this sort of thing?


I would question why the voxel type needs to contain a position? The position is kind of implicit, in the same way that if you have a 2D bitmap then you don't store a position for each pixel, you just store a list of colours. So if you call myVolume->getVoxelAt(x, y, z) you never need to check the position of the resulting voxel because you know you just retrieved it from (x, y, z).

Dynasty wrote:
I can't think of any sane way to represent a color in a single floating point value.


I'm not sure it's sane but I do do it. CPU side I have the colour as a 16 bit integer (4-bits for R, G, B, and A) which I cast directly to a float:

Code:
Colour colour = vecVertices[i].getMaterial();
uint16_t colourAsUint = (colour.getRed() << 12) | (colour.getGreen() << 8) | (colour.getBlue() << 4) | (colour.getAlpha());
*ptr = static_cast<float>(colourAsUint); ptr++;


Edit: Just to be clear, Colour is my own type and is not part of PolyVox. For me a Colour is returned by getMaterial() because this is using the new templatised version of PositionMaterial as mentioned above.

Then GPU side I convert this float back to RGBA values:

Code:
vec4 floatToRGBA(float inputVal)
{       
        //Store the input in each component
        vec4 inputVec = vec4(inputVal, inputVal, inputVal, inputVal);
       
        //Convert each component to a value in the range 0-15
        vec4 result = floor(inputVec / vec4(4096.0, 256.0, 16.0, 1.0));
        vec4 shiftedResult = vec4(0.0, result.rgb) * 16.0;     
        result -= shiftedResult;
       
        //Convert to range 0-1
        result /= 15.0;
       
        //return the result     
        return result;
}


I would have to describe it as a temporary solution though... and it may not work if you want more precision per colour channel. I think a better solution will come once we have the VertexTypes properly templatised on Material type.

Dynasty wrote:
Also most voxel tutorials that I've read suggest that you store data in chunks. However, polyvox recommends that you keep everything in a giant volume. Does this mean that the chunks should be split by the code that creates the meshes? Or something else?


The SimpleVolume and LargeVolume internally store data as chunks (they call them blocks) for memory management purposes, so you don't need to worry about this. For mesh extraction and rendering purposes you do need to manually control the size of the meshes and you can do this by passing a Region as a parameter to the surface extractors. There is no need for the blocks which are used internal memory management to match up with the Regions which are used for mesh management, though most voxel tutorials do tend to lump these two concepts together.

Dynasty wrote:
Edit2: I've implemented a custom class that holds custom value colors, block health, and position. Anyway, the mesh only seems to contain position data and no information about colors. When the mesh is converted to an Irrlicht mesh, it needs to get the color information associated with the block. There doesn't seem to be a good way that I can think of to retrieve this information, since the only data you can get is the position of the vertices and not those of the block. All of the data is stuck in the SimpleVolume.


I think I've covered this with my talk on positions and colours above... but let me know if you need more clarification.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Wed Feb 06, 2013 3:59 pm 
User avatar

Joined: Tue Feb 05, 2013 5:44 pm
Posts: 33
David Williams wrote:
Anyway, I agree it's a bit odd, and on our experimental branch we've actually started templatising the PositionMaterial class on the material type, so that the vertices can get the same material information that was in the voxel. You can see it here:

https://bitbucket.org/volumesoffun/poly ... sion#cl-39

But I think it will be a while before this change gets merged back into the main branch.


Will the new template version also be able to store any arbitrary data stored in the voxel? For instance, in the future I may want to add a luminosity property to the voxels to allow different voxels to glow with different levels of intensity. This property would of course be completely separate from the color property.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: polyvox integration to irrlicht
PostPosted: Thu Feb 07, 2013 9:59 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I think it's definitely something we should keep in mind when designing the new vertex formats. I've created an issue for this on BitBucket: https://bitbucket.org/volumesoffun/poly ... ex-formats

I don't think it will get done before the next release though.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3, 4, 5  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