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


All times are UTC




Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: [Solved] Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 1:53 am 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
Ok where to start, first, let me say I've been working with Irrlicht a number of years now and I'm familiar with a lot of it's drawbacks and such AND that I've been trying desperately NOT to come asking questions here about anything if possible and ONLY after having searched for information FIRST. That being said I have finally gotten truely stuck.

Using ALL of the information that is still available since most of the examples for polyvox existed on thermite3D site that no longer exists (or at least I imagine). eh hem, anyways getting as far as I have so far outside of the obviously copied code wasn't easy and is of my own amaturistic design.

Now I've confused myself...

So here's the Relavent information and code:

1. I've built my own game engine. (if it can be called that) (not used here)
2. I'm attempting to create a sort of demo for my engine in the flesh of a simple minecraft-clone of sorts
3. I'm using Irrlicht. (obvious at this point)
4. I've used code off these and other related forums for my test-case basic framework yada yada.
5. I'm using the current develop branch on whatever git site you host it now (I forget) (bitbucket?)
6. I use bad grammar and parenthesis too much (sorry nazi's)
7. in my test I have an irrlicht FPS style camera, picking from dev branch PV, a very slow system of redrawing the entire mesh atm. (and other stuff I think, shrug)


The CODE: (forgive me it's ugly, I'm leaving in the out commented code to illistrate how difficult this has been... it's been nearly a week now. :((((((((((( )

Code:
#include "main.h"

class MyEventReceiver : public IEventReceiver
{
public:
   MyEventReceiver(SAppContext & context) : Context(context) { }

   virtual bool OnEvent(const SEvent& event)
   {
             // Remember the mouse state
      if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
      {
         switch(event.MouseInput.Event)
         {
            case EMIE_LMOUSE_PRESSED_DOWN:
            MouseState.LeftButtonDown = true;
            break;

         case EMIE_LMOUSE_LEFT_UP:
             {
                    pickBlock(volData,camera->getAbsolutePosition());
                    recalcMesh(volData);
                    //MouseState.LeftButtonDown = false;
                    break;
                }
            case EMIE_RMOUSE_PRESSED_DOWN:
//            MouseState.RightButtonDown = true;
            break;

         case EMIE_RMOUSE_LEFT_UP:
             {
                    //pickBlock(volData,camera);
                    //recalcMesh(volData);

                    camera->setPosition(core::vector3df(0,68,0));
                    //MouseState.RightButtonDown = false;
                    break;
                }

         case EMIE_MOUSE_MOVED:
            MouseState.Position.X = event.MouseInput.X;
            MouseState.Position.Y = event.MouseInput.Y;
            break;

         default:
            // We won't use the wheel
            break;
         }
      }


      if (event.EventType == EET_GUI_EVENT)
      {
         s32 id = event.GUIEvent.Caller->getID();
         //gui::IGUIEnvironment* env =
         Context.device->getGUIEnvironment();

         switch(event.GUIEvent.EventType)
         {


         /*
         If a button was clicked, it could be one of 'our'
         three buttons. If it is the first, we shut down the engine.
         If it is the second, we create a little window with some
         text on it. We also add a string to the list box to log
         what happened. And if it is the third button, we create
         a file open dialog, and add also this as string to the list box.
         That's all for the event receiver.
         */
         case gui::EGET_BUTTON_CLICKED:
            switch(id)
            {
            case GUI_ID_QUIT_BUTTON:
               Context.device->closeDevice();
               return true;



            default:
               return false;
            }
            break;

         default:
            break;
         }
      }

      return false;
   }

private:
   SAppContext & Context;
};


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,111,255,111);

   const std::vector<uint32_t>& indices = meshPoly.getIndices();
   const std::vector<PolyVox::PositionMaterialNormal>& vertices = meshPoly.getVertices();

   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(100,0,0,255);
   }

   buffer->getIndexBuffer().set_used(indices.size());
   for (size_t i = 0; i < indices.size(); ++i) {
        //if(!volData.getVoxelAt())
       buffer->getIndexBuffer().setValue(i, indices[i]);
   }

   //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);

    //for textures
    if(fabsf(normal.getX())>fabsf(normal.getY()) && fabsf(normal.getX())>fabsf(normal.getZ())) {
    mb->getVertexBuffer()[i].TCoords.X = position.getY();
    mb->getVertexBuffer()[i].TCoords.Y = position.getZ();
    }
    else if(fabsf(normal.getY())>fabsf(normal.getX()) && fabsf(normal.getY())>fabsf(normal.getZ())) {
    mb->getVertexBuffer()[i].TCoords.X = position.getX();
    mb->getVertexBuffer()[i].TCoords.Y = position.getZ();
    }
    else {
    mb->getVertexBuffer()[i].TCoords.X = position.getX();
    mb->getVertexBuffer()[i].TCoords.Y = position.getY();
    }


}

   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 createChunk(SimpleVolume<uint8_t>& volData)//, vector<>& chunk)
{
   // uint8_t uDensity = std::numeric_limits<uint8_t>::max();

    //This vector hold the position of the center of the volume
   //Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);
    Vector3DInt32 v3dVolEnd(volData.getWidth(), volData.getHeight(), volData.getDepth());
    int maxWidth = volData.getWidth()-1;
    int maxHeight = volData.getHeight()-1;
    int maxDepth = volData.getDepth()-1;
    //int x = 0;
    //int y = 0;

   //This three-level for loop iterates over every voxel in the volume
   for (int z = 1; z < maxDepth; z++)
   {
      for (int y = 1; y < maxHeight; y++)
      {
         for (int x = 1; x < maxWidth; x++)
         {
/*

   for (int z = 0; z < volData.getWidth(); z++)
   {
      for (int y = 0; y < volData.getHeight(); y++)
      {
         for (int x = 0; x < volData.getDepth(); x++)
         {*/
                uint8_t uDensity = std::numeric_limits<uint8_t>::max();
            //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(v3dCurrentPos < volData.getShortestSideLength())

            //if(fDistToCenter <= fRadius)
   //         {
                  // uDensity = 0;
                    //volData.setVoxelAt(x, y, z, uDensity);
                   // return;}
                //else{
                //volData.setVoxelAt(x, y, z, uDensity);


                if(y <= 60){
            volData.setVoxelAt(x, y, z, uDensity);//uDensity);
                }
                else{
                        volData.setVoxelAt(x, y, z, 0);//uDensity);
                }



                //volData.setVoxelAt(v3dVolCenter, uDensity);
           //     }
         }
      }
   }
/*
    uint8_t uDensity = std::numeric_limits<uint8_t>::max();
    volData.setVoxelAt(0,0,0, uDensity);
    v3dVolCenter.setX(v3dVolCenter.getX()+1);
    v3dVolCenter.setY(v3dVolCenter.getY()+1);
    v3dVolCenter.setZ(v3dVolCenter.getZ()+1);
    volData.setVoxelAt(v3dVolCenter, uDensity);*/
}
/*
void createSphereInVolume(SimpleVolume<uint8_t>& 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.getDepth(); z++)
   {
      for (int y = 0; y < volData.getHeight(); y++)
      {
         for (int x = 0; x < volData.getWidth(); 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(fDistToCenter <= fRadius)
            {
               //Our new density value
               //uint8_t uDensity = Density8::getmaxDensity()();
               uint8_t uDensity = std::numeric_limits<uint8_t>::max();

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

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

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

            //144 in the middle, (144 - 32) at the edges. Threshold of 128 is between these
            //volData.setVoxelAt(x, y, z, 144 - fDistToCenter);
         }
      }
   }
}
*/

void pickBlock(SimpleVolume<uint8_t>& volData,core::vector3df v3d)
{
    //camera->updateAbsolutePosition();

    Vector3DFloat rayOrigin;
    rayOrigin.setX(v3d.X);
    rayOrigin.setY(v3d.Y);
    rayOrigin.setZ(v3d.Z);

    core::vector3df target = (camera->getTarget() - camera->getPosition());

    Vector3DFloat rayDir;
    rayDir.setX(target.X);
    rayDir.setY(target.Y);
    rayDir.setZ(target.Z);

   Vector3DFloat start(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ());
   Vector3DFloat direction(rayDir.getX(), rayDir.getY(), rayDir.getZ());
    //start.normalise();
   direction.normalise();
   direction *= 9999.0f; //Casts ray of length 1000
    std::cout << start << direction << std::endl;

//    const int32_t uVolumeSideLength = 32;
   const int8_t emptyVoxelExample = 0; //A voxel value of zero will represent empty space.
   //PolyVox::PickResult resultHit = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength, 0, 0), emptyVoxelExample);
   PolyVox::PickResult resultHit = pickVoxel(&volData, start, direction, emptyVoxelExample);

   if(resultHit.didHit)
   {
       //resultHit.hitVoxel.normalise();
        volData.setVoxelAt(resultHit.hitVoxel,emptyVoxelExample);
       recalcMesh(volData);
   }
}


void calcMesh(SimpleVolume<uint8_t>& volData)
{
    //Transform voxel into 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();

   //Extract the surface
   //SurfaceMesh<PositionMaterialNormal> meshLowLOD;
   //MarchingCubesSurfaceExtractor< RawVolume<uint8_t> > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD);
   //surfaceExtractor.execute();
   //meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f);

   //Extract the surface
   //SurfaceMesh<PositionMaterialNormal> meshHighLOD;
   //MarchingCubesSurfaceExtractor< SimpleVolume<uint8_t> > surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD);
   //surfaceExtractorHigh.execute();
   //meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0));

    //Transform mesh into irrlicht mesh
    //irr::scene::IMeshSceneNode* levelMesh =
    device->getSceneManager()->addMeshSceneNode(convertPolyMesh(mesh),0,26);
}


void recalcMesh(SimpleVolume<uint8_t>& volData)
{
    scene::ISceneNode* SNP = device->getSceneManager()->getSceneNodeFromId(26);
    SNP->removeAll();

//    PolyVox::VolumeResampler<> vlrs = resampleSameSize()
    calcMesh(volData);
    //createChunk(volData);
}


int main(int argc, char**argv)
{
   // ask user for driver
   //video::E_DRIVER_TYPE driverType = video::EDT_OPENGL; // video::driverChoiceConsole();   if (driverType==video::EDT_COUNT)
      //return 1;

   // create device and exit if creation failed

   device =
      //createDevice(driverType, core::dimension2d<u32>(640, 480));
        createDevice(video::EDT_OPENGL, core::dimension2d<u32>(800, 600));

   if (device == 0)
      return 1; // could not create selected driver.

   /*
   Set the caption of the window to some nice text. Note that there is an
   'L' in front of the string. The Irrlicht Engine uses wide character
   strings when displaying text.
   */

   device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");

   /*
   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().
   */

   irr::video::IVideoDriver* driver = device->getVideoDriver();
   irr::scene::ISceneManager* smgr = device->getSceneManager();
   irr::gui::IGUIEnvironment* guienv = device->getGUIEnvironment();

    SKeyMap keyMap[9];
    keyMap[0].Action = EKA_MOVE_FORWARD;
    keyMap[0].KeyCode = KEY_UP;
    keyMap[1].Action = EKA_MOVE_FORWARD;
    keyMap[1].KeyCode = KEY_KEY_W;

    keyMap[2].Action = EKA_MOVE_BACKWARD;
    keyMap[2].KeyCode = KEY_DOWN;
    keyMap[3].Action = EKA_MOVE_BACKWARD;
    keyMap[3].KeyCode = KEY_KEY_S;

    keyMap[4].Action = EKA_STRAFE_LEFT;
    keyMap[4].KeyCode = KEY_LEFT;
    keyMap[5].Action = EKA_STRAFE_LEFT;
    keyMap[5].KeyCode = KEY_KEY_A;

    keyMap[6].Action = EKA_STRAFE_RIGHT;
    keyMap[6].KeyCode = KEY_RIGHT;
    keyMap[7].Action = EKA_STRAFE_RIGHT;
    keyMap[7].KeyCode = KEY_KEY_D;

    keyMap[8].Action = EKA_JUMP_UP;
    keyMap[8].KeyCode = KEY_KEY_J;

    camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.01f, -1, keyMap, 9, false, 3.f);

    //camera = smgr->addCameraSceneNodeFPS();
    smgr->setAmbientLight(video::SColorf(1.0f,1.0f,1.0f));

   /*
   We add a hello world label to the window, using the GUI environment.
   The text is placed at the position (10,10) as top left corner and
   (260,22) as lower right corner.
   */

   guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
      irr::core::rect<s32>(10,10,260,22), true);

   //Create and show the Qt OpenGL window
   //QApplication app(argc, argv);
   //OpenGLWidget openGLWidget(0);
   //openGLWidget.show();

    // region-rings-factor formula
    // an = 1-9-16-24-32-40-48
    // sf = 1-3-5-7-9-11-13-15-17-19-21
    // an = (sf x 4) + 4 // +4 corners ;)

    //createVol();
    camera->setPosition(core::vector3df(0,70,0));
    camera->updateAbsolutePosition();
   //createSphereInVolume(volData, 28);
   // place a chunk in it
   createChunk(volData);
   calcMesh(volData);

   //createChunk(createVol());
    //camera->setTarget(levelMesh->getAbsolutePosition());

/*
    PolyVox::RaycastResults::RaycastResult rs;
    PolyVox::raycastWithDirection(volData,camera->getAbsolutePosition(),camera->getTarget());
    if(rs->Interupted())
    {
        volData->getVoxelAt(camera->getTarget());
    }
*/

   //QCOMPARE(resultHit.previousVoxel, Vector3DInt32((uVolumeSideLength / 2), uVolumeSideLength / 2, uVolumeSideLength / 2));

   //PickResult resultMiss = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength / 2, uVolumeSideLength, uVolumeSideLength), emptyVoxelExample);

   //QCOMPARE(resultMiss.didHit, false);

    //RaycastResult raycastTestFunctor;
    /*class raycastTestFunctor
    {
        public:
        void operator()()
        {
            // true, 1 if a < b, false otherwise
            return;
        }
    };*/

   //RaycastResult rcResult = PolyVox::raycastWithDirection(&volData, start, direction, raycastTestFunctor);

//RaycastResult result = raycastWithDirection(
    //&volData, start, direction, raycastTestFunctor);
/*
if(rcResult == RaycastResults::Interupted)
{

    //iend
//SceneMgr->getSceneNode("mEditNode")->setPosition(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ());
//   volData.getVoxelAt();
}
*/
   //if(rcResult == RaycastResult::Interupted)
   //{
   //}

   //Smooth the data - should reimplement this using LowPassFilter
   //smoothRegion<SimpleVolume, Density8>(volData, volData.getEnclosingRegion());
   //smoothRegion<SimpleVolume, Density8>(volData, volData.getEnclosingRegion());
   //smoothRegion<SimpleVolume, Density8>(volData, volData.getEnclosingRegion());

   //RawVolume<uint8_t> volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31)));
   //VolumeResampler<SimpleVolume<uint8_t>, RawVolume<uint8_t> > volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
   //volumeResampler.execute();


   // Store the appropriate data in a context structure.
   SAppContext context;
   context.device = device;
   //context.counter = 0;
   //context.listbox = listbox;

   // Then create the event receiver, giving it that context structure.
   MyEventReceiver receiver(context);

   // And tell the device to use our custom event receiver.
   device->setEventReceiver(&receiver);

    if(MouseState.LeftButtonDown)
    {
    }

   while(device->run() && driver)
   {
      // Catch focus changes (workaround until Irrlicht has events for this)
   //   bool focused = device->isWindowFocused();
      //if ( hasFocus && !focused )
      //   onKillFocus();
      //hasFocus = focused;

      if (device->isWindowActive())
      {
         driver->beginScene(true, true, video::SColor(150,50,50,50));

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

         driver->endScene();

      }
      else
         device->yield();
   }

   //Pass the surface to the OpenGL window
   //openGLWidget.setSurfaceMeshToRender(meshHighLOD);
   //openGLWidget.setSurfaceMeshToRenderLowLOD(meshLowLOD);

   //Run the message pump.
   //return app.exec();

    device->drop();
    return 0;
}





And now for the actually issue. Everything "sort of" works, the picking is currently working in odd ways but it works. but the problem is the surface extraction. If I pick and extract and redraw the mesh the original giant cube of voxel cubes doesn't change at all, as though surface extraction is giving me bad index references.

Perhaps this is all the information you need to explain your voxel engine. So for now I'll just post this bad thread on your wonderful forum and pray for a fix. If you have trouble understanding my problem I can post video or screenshots if you like rather than anyone having to build my example.

Thanks in advance. Any constructive criticism, help, ideas, or code would be greatly appreciated as well.

[update] little edit, I've fixed up the code a little bit to decrease the page resizing so large and removed some of the more completely irrelavent code for easier reading and comprehension.

Edited this again, this time I've added an image to help explain the problem

Image


Last edited by Midnight on Tue May 27, 2014 1:24 am, edited 1 time in total.

Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 6:46 am 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
I've been analyzing the code and the affects of the picker in game or whatever whilst trying to take some screen shots.

I'm noticing that when I set a voxel density empty (remove a voxel) that not all sides are rendered inside and out. It appears to be rendering them inside and out at first but when another is beside it creating some sort of polygon paradox and canceling out some of the sides. very strange behavior.

I'm not sure if I've done this right at all at this point. Perhaps the code I've used just isn't rendering it correctly to begin with. But how do I even go about this? If the extractor isn't giving me the right indices and I only can test volData for an empty voxel then how do I convert the mesh by rendering all the vertex/indices manually based on the volData? very confused here.

It's hard to keep track of which examples are current code around the forum. I'd like to make some sort of irrlicht example you could use with the engine as it should technically have one imho.

I'm also very curious why the picker is only picking correct while the camera is inside (or above?) the volume. I'm not even positive that it's working correctly.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 7:37 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I think I do need some screenshots to understand the problem you are describing here. At any rate you should probably break the problem down - for example it will be hard to debug the picking if you are not sure that the rendering is working correctly. Leave chunking aside for now and come to that when other aspects are working. Rather than picking, just let spacebar remove a voxel at a known position, etc.

Also, be aware that the 'CubicSurfaceExtractorWithNormals' is removed from the very latest version of the code. 'CubicSurfaceExtractor' remains but you need to find your own normals (e.g. compute them in the fragment shader as is now done by the example).

See this thread for some discussion of other incoming changes (most code on the forums will no longer work as-is): http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=591


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 2:16 pm 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
I thought you might go that route. I'm pretty good at debugging, although you have some good suggestions. I'm wondering why you avoided talking about the extractor, have you done this yourself yet?

As for shaders, irrlicht has none, and I'm not interested in using Qt, it's a shame that's the only example you offer. I'm surprised you lack a minecraft-like picking demo, seems like that's what inspired the voxel craze and only seems natural to mimic.

At any rate I was looking for insight into how your engine works, am I going about this correctly? It's not a problem with the normals but the data the extractor is (or rather isn't) providing. I thought I was being concise about that. shrug.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 2:30 pm 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
let me explain, because I'm getting nowhere with this.

Code:
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,111,255,111);

   const std::vector<uint32_t>& indices = meshPoly.getIndices();
   const std::vector<PolyVox::PositionMaterialNormal>& vertices = meshPoly.getVertices();

   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(100,0,0,255);
   }

   buffer->getIndexBuffer().set_used(indices.size());
   for (size_t i = 0; i < indices.size(); ++i) {
        //if(!volData.getVoxelAt())
       buffer->getIndexBuffer().setValue(i, indices[i]);
   }

   //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;
}


The problem is here, notice I get the indices from the extracted surface template-class and then simply draw them.

Normals aren't an issue yet. Nor is chunking there is only 1. the picking works fine for the current issue. I'm 99.9% sure my code isn't breaking this. In fact if there were a working example I'm sure I could make it work with any graphics lib I wanted. I just simply don't understand templated classes very well, especially this deeply nested. I'm still learning but not a total nuby.

It boils down to a simple question. does the surface extractor provide the correct indices? because according to this the answer is no, and there is no way to figure that out easily without writing what I'd consider spaghetti code.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Mon May 19, 2014 7:18 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm afraid that I don't fully understand your problem. Let's leave aside picking, because it seems you are initially concerned with the rendering not being correct because the indices are bad. However, you also say that the mesh shows up to start with, but doesn't get updated after you modify the volume data? Are you creating a new surface extractor object each time you perform extraction (probably better than reusing the old one)?

If I'm not correct in the above, can you try an illustrate with screenshots what the problem is?

To answer your specific question, the indices do work and are used by the examples. Can you view the indices in the debugger or print them out to verify that they are sensible? If you set just a single voxel to be solid the you shouldn't get too much index/vertex data here.

Nothing is obviously wrong in the short code snippet you pasted, but I'm not familiar with Irrlicht.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Tue May 20, 2014 12:40 am 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
Yes as you can see if you look at that huge code file I make a new surface extractor each time the mouse has been clicked.

What I really needed to know is if a test case or proof of concept rather actually existed with a picking extraction like this. That's the first thing I wanted to establish, incase there were known bugs and such, I'm only vaguely familiar with polyvox as of yet.

I have found some code however and located the "example" you mentioned. I'm assuming you're talking about the python example with the develop branch. That is the only one I've noticed any vertex shader, or fragment shader.. I've yet to dive into shader coding much.

I took one screenshot.. as to have two requires the same test and the picker chooses funny.. BECAUSE I haven't enabled debugging info in irrlicht yet. I had begun doing that shortly before taking this;

Image

Ok so this is inside and down looking upwards of the mesh. I'll be calling the cube of voxels the mesh. The volume is 1 voxel size larger on all sides to accommodate the rendering of the mesh outsides, or mesh normals.

If the camera were outside of the mesh, you would see no changes.

If the camera were inside one of those so-called-empty-voxels you would see 6 inside normals/mesh/tris. It's extremely difficult to tell what's actually being rendered but I'm not the least bit concerned with that. It shouldn't be.... It just suddenly dawned on me that you said I need to compute my own normals. Makes sense I suppose.

I have an idea.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Tue May 20, 2014 7:37 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm sorry that I can't review your code in detail, but it's too long and I can't clearly see which bits are commented out. But your screenshot does look very strange.

So this is the screenshot when you first run the application? If you have two solid voxels next to each other then you should not get a quad generated in between them, which appears to be happening in your screenshot. But it does look like the index data is correct because the quads are at least not just random polygons.

Perhaps the initial volume data is incorrect... try just drawing the same sphere that the BasicExample uses. Leave it centered in the volume (behaviour is subtly different at the edges of volumes/regions).

Or you have done some picking here? If so, did you delete the previous mesh from Irrlicht or are you just drawing the meshes on top of each other? Did you clear any old index data from the buffer before inserting the new index data (in case the new index data is shorter than the old index data)? But really we need to see a correctly rendered mesh before we think about picking.

To answer your questions, we do not have an example of picking but I think there is a unit test (I forget what is it is called, just search the code base for 'picking'). We do use the picking code in Cubiquity so it should work if everything is set up right. But when testing this just print out the picked positions rather than changing the volume data.

You are right that we can ignore the issue of normals and shaders for now - let's get the shape correct first. But actually the latest develop version of the BasicExample does make use of a shader embedded as a string in the C++ code. The examples are generally messy and we hope to clean them up soon, but they will still use Qt.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Sat May 24, 2014 7:57 am 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
David Williams wrote:
I'm sorry that I can't review your code in detail, but it's too long and I can't clearly see which bits are commented out. But your screenshot does look very strange.

So this is the screenshot when you first run the application? If you have two solid voxels next to each other then you should not get a quad generated in between them, which appears to be happening in your screenshot. But it does look like the index data is correct because the quads are at least not just random polygons.

Perhaps the initial volume data is incorrect... try just drawing the same sphere that the BasicExample uses. Leave it centered in the volume (behaviour is subtly different at the edges of volumes/regions).


Yes I had done picking on those spots which is only visible on the inside of the surfaced mesh.

Image

A sphere, which I think parts of picking may be working on.

David Williams wrote:
Or you have done some picking here? If so, did you delete the previous mesh from Irrlicht or are you just drawing the meshes on top of each other? Did you clear any old index data from the buffer before inserting the new index data (in case the new index data is shorter than the old index data)? But really we need to see a correctly rendered mesh before we think about picking.

To answer your questions, we do not have an example of picking but I think there is a unit test (I forget what is it is called, just search the code base for 'picking'). We do use the picking code in Cubiquity so it should work if everything is set up right. But when testing this just print out the picked positions rather than changing the volume data.

You are right that we can ignore the issue of normals and shaders for now - let's get the shape correct first. But actually the latest develop version of the BasicExample does make use of a shader embedded as a string in the C++ code. The examples are generally messy and we hope to clean them up soon, but they will still use Qt.


I'm taking your suggestions and trying things on my own. Not giving up. I'll add more lights and see what's really happening here.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Another Irrlicht + Polyvox Help Thread
PostPosted: Sat May 24, 2014 8:51 am 
User avatar

Joined: Sun May 18, 2014 10:52 pm
Posts: 43
Added lighting, and tried to clear indice and vertex stl vectors and I can see what is happening, unfortunately it's as expected the outer mesh is rendered regardless.


But at least it looks pretty :P :roll:
Image
Image
and a cube ;) starting to get the idea?
Image
Image

Hey at least I can drag my light around for free, it's already better than minecraft. :D


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