It is currently Sat Aug 22, 2020 3:19 pm


All times are UTC




Post new topic Reply to topic  [ 128 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12, 13  Next
Author Message
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Fri Feb 10, 2012 1:48 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
Ok, thanks for the useful information David. I still have a crash on a very small region in Release mode - still a buffer overrun. I'm still hesitant to add any code until I figure out what is the root cause of it. I've only taken away code in hopes of it disappearing, but I don't have much code left to delete in my frame render function. It looks like so -

Code:
bool WorldCraft::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
   if(mKeyDevices.mWindow->isClosed())
       return false;
 
   if(mShutDown)
       return false;

   //Need to capture/update each device
   mKeyDevices.mKeyboard->capture();
   mKeyDevices.mMouse->capture();

   CEGUI::MouseCursor::getSingleton().setPosition(CEGUI::Point(mCamera->getViewport()->getActualWidth() / 2, mCamera->getViewport()->getActualHeight() / 2));

   if(!processUnbufferedInput(evt))
      return false;
   
   //The next 3 paragraphs display FPS info to screen
   float last;
   float avg;
   float best;
   float worst;
   mKeyDevices.mWindow->getStatistics(last,avg,best,worst);

   char tmp[32];
   sprintf(tmp, "FPS: %f", last);


   sprintf(tmp, "Avg FPS: %f", avg);


   // Update SkyX
   mSkyX->update(evt.timeSinceLastFrame);

   OIS::MouseState ms = mKeyDevices.mMouse->getMouseState();
   ms.Y.abs = mCamera->getViewport()->getActualHeight() / 2;
   ms.X.abs = mCamera->getViewport()->getActualWidth() / 2;

   Ogre::Ray ray =  mCamera->getCameraToViewportRay((float)ms.X.abs / (float)ms.width,  (float)ms.Y.abs / (float)ms.height);   
   Ogre::Vector3 pos = ray.getOrigin();   
   Ogre::Vector3 dir = ray.getDirection();   
   // Find the voxel we are looking at.       
   PolyVox::Vector3DFloat start(pos.x,pos.y,pos.z);   
   PolyVox::Vector3DFloat direction(dir.x, dir.y, dir.z);

      direction *= 1000.0f; //Casts ray of length 1000
   
   PolyVox::RaycastResult raycastResult;
   PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8>
   raycast(&volData, start, direction, raycastResult);
   raycast.execute();
   
   if(raycastResult.foundIntersection) {
      // Set marker node position
      mKeyDevices.mSceneMgr->getSceneNode("mEditNode")->setPosition(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ());
   }

   if (ms.buttonDown(OIS::MB_Left)){
      if(raycastResult.foundIntersection) {
         volData.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity);
      }
   }

   return true;
}


UPDATE: looks like I found the cause of the overrun, as it doesn't seem to crash after removing this piece from the framerender function ( ker's code) -
Code:
   PolyVox::Vector3DFloat sig(
            (dir.x < 0)?(-1.0f):((dir.x > 0)?(1.0f):(0)),
            (dir.y < 0)?(-1.0f):((dir.y > 0)?(1.0f):(0)),
            (dir.z < 0)?(-1.0f):((dir.z > 0)?(1.0f):(0))
            );


My function in full looked like so -

Code:
bool WorldCraft::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
   if(mKeyDevices.mWindow->isClosed())
       return false;
 
   if(mShutDown)
       return false;

   //Need to capture/update each device
   mKeyDevices.mKeyboard->capture();
   mKeyDevices.mMouse->capture();

   CEGUI::MouseCursor::getSingleton().setPosition(CEGUI::Point(mCamera->getViewport()->getActualWidth() / 2, mCamera->getViewport()->getActualHeight() / 2));

   if(!processUnbufferedInput(evt))
      return false;
   
   //The next 3 paragraphs display FPS info to screen
   float last;
   float avg;
   float best;
   float worst;
   mKeyDevices.mWindow->getStatistics(last,avg,best,worst);

   char tmp[32];
   sprintf(tmp, "FPS: %f", last);
   //mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSinfo")->setText(tmp);

   sprintf(tmp, "Avg FPS: %f", avg);
   //mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSAvg")->setText(tmp);

   // Update SkyX
   mSkyX->update(evt.timeSinceLastFrame);

   OIS::MouseState ms = mKeyDevices.mMouse->getMouseState();
   ms.Y.abs = mCamera->getViewport()->getActualHeight() / 2;
   ms.X.abs = mCamera->getViewport()->getActualWidth() / 2;

   Ogre::Ray ray =  mCamera->getCameraToViewportRay((float)ms.X.abs / (float)ms.width,  (float)ms.Y.abs / (float)ms.height);   
   Ogre::Vector3 pos = ray.getOrigin();   
   Ogre::Vector3 dir = ray.getDirection();   
   // Find the voxel we are looking at.       
   PolyVox::Vector3DFloat start(pos.x,pos.y,pos.z);   
   PolyVox::Vector3DFloat direction(dir.x, dir.y, dir.z);

   /*
   PolyVox::Vector3DFloat sig(
            (dir.x < 0)?(-1.0f):((dir.x > 0)?(1.0f):(0)),
            (dir.y < 0)?(-1.0f):((dir.y > 0)?(1.0f):(0)),
            (dir.z < 0)?(-1.0f):((dir.z > 0)?(1.0f):(0))
            );
         */

      direction *= 1000.0f; //Casts ray of length 1000
   
   PolyVox::RaycastResult raycastResult;
   PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8>
   raycast(&volData, start, direction, raycastResult);
   raycast.execute();
   /*

   PolyVox::Vector3DFloat r = (PolyVox::Vector3DFloat(raycastResult.previousVoxel) + sig*float(0.5) - start)/direction;

   // grabbed from my source, it shows the point the mouse points at inside the world
   // and its normal
   PolyVox::Vector3DFloat m_vecMousePointPosition;
   PolyVox::Vector3DFloat m_vecMousePointNormal;

   if(r.getX() < r.getY() && r.getX() < r.getZ()) {
     m_vecMousePointPosition = start + direction*r.getX();
     m_vecMousePointNormal.setX(-sig.getX());
     m_vecMousePointNormal.setY(0);
     m_vecMousePointNormal.setZ(0);

   } else if(r.getY() < r.getZ()) {
     m_vecMousePointPosition = start + direction*r.getY();
     m_vecMousePointNormal.setX(0);
     m_vecMousePointNormal.setY(-sig.getY());
     m_vecMousePointNormal.setZ(0);
   } else {
     m_vecMousePointPosition = start + direction*r.getZ();
         m_vecMousePointNormal.setX(0);
     m_vecMousePointNormal.setY(0);
     m_vecMousePointNormal.setZ(-sig.getZ());
   }


   */

   
   // Find the voxel we are looking at.
   
   //PolyVox::Vector3DFloat start(100,100,100);
   //PolyVox::Vector3DFloat direction(0, -1, 0);

   //direction.normalise();

   
   if(raycastResult.foundIntersection) {
      // Update stats
      /*
      mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSinfo")->setText(Ogre::StringConverter::toString(Vector3(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ())).c_str());

      sprintf(tmp, "Previous: %f",Ogre::StringConverter::toString(Vector3(raycastResult.previousVoxel.getX(), raycastResult.previousVoxel.getY(), raycastResult.previousVoxel.getZ())));
      mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSAvg")->setText(tmp);
      */
      // Set marker node position
      mKeyDevices.mSceneMgr->getSceneNode("mEditNode")->setPosition(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ());
   }

   if (ms.buttonDown(OIS::MB_Left)){
      if(raycastResult.foundIntersection) {
         volData.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity);
      }
   }

   return true;
}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Fri Feb 10, 2012 2:06 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
This doesn't quite make sense to me... you've shown the declaration of 'sig' is now commented out but you are still using the variable 'sig' later on in the code. That shouldn't even compile...

More generally, I think you should not use ker's code. I believe it does work, but you're probably not using it correctly and I don't think it is applicable to your scenario anyway.

Lastly, it seems a bit strange to me that you are performing tasks like raycasting in the 'frameRenderingQueued' function. I'm not really that knowledgeable about Ogre but I would expect to see this in the game loop somewhere and to have only rendering related code in 'frameRenderingQueued'. Not sure if it's actually a problem, but some reorganisation but be useful.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Fri Feb 10, 2012 2:42 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
David Williams wrote:
This doesn't quite make sense to me... you've shown the declaration of 'sig' is now commented out but you are still using the variable 'sig' later on in the code. That shouldn't even compile...


All sig uses are commented out, I think you may have trouble reading where the comments are e.g. (/*, */)

David Williams wrote:
More generally, I think you should not use ker's code. I believe it does work, but you're probably not using it correctly and I don't think it is applicable to your scenario anyway.

You're right, I don't think I need it either.

David Williams wrote:
Lastly, it seems a bit strange to me that you are performing tasks like raycasting in the 'frameRenderingQueued' function. I'm not really that knowledgeable about Ogre but I would expect to see this in the game loop somewhere and to have only rendering related code in 'frameRenderingQueued'. Not sure if it's actually a problem, but some reorganisation but be useful.


AFAIK that's where the main loop is and where the work should be done. I've never really seen real-time editing done anywhere else.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Fri Feb 10, 2012 2:52 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
drwbns wrote:
All sig uses are commented out, I think you may have trouble reading where the comments are e.g. (/*, */)


Sorry, you are right, I couldn't read the comments without syntax highlighting.

drwbns wrote:
AFAIK that's where the main loop is and where the work should be done. I've never really seen real-time editing done anywhere else.


Ok, maybe it's fine then. I don't really know enough about Ogre to be sure about this.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Fri Feb 10, 2012 3:47 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I made a function that creates or redraws the voxel region. The problem is that it takes about 2 seconds to complete an update on a 513 x 513 x 256 volume with basically all of the time being dedicated to surface extraction. I still need a quicker solution for real time updating. This can update in real time on a very small volume. I thought I'd post it just in case someone wants a redraw method. Sorry for the commented code I've been using for testing...

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

   // Reduced mesh - use for non-smooth mesh
   /*
   Region reducedRegion = volData.getEnclosingRegion();
   reducedRegion.shiftLowerCorner(Vector3DInt32(2,2,2));
   reducedRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2));
   PolyVox::CubicSurfaceExtractorWithNormals<SimpleVolume, Density8> surf(&volData, reducedRegion, &mesh);
      
   
   // Smooth using a lowpassfilter
   
   Region fullRegion = volData.getEnclosingRegion();
   //fullRegion.shiftLowerCorner(Vector3DInt32(2,2,2));
   //fullRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2));

   SimpleVolume<Density8> resultVolume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(myTerrainHM.getWidth(),256,myTerrainHM.getHeight())));

   Region fullRegion2 = resultVolume.getEnclosingRegion();
   fullRegion2.shiftLowerCorner(Vector3DInt32(2,2,2));
   fullRegion2.shiftUpperCorner(Vector3DInt32(-2,-2,-2));

   LowPassFilter<SimpleVolume, SimpleVolume, Density8> pass1(&volData, fullRegion2, &resultVolume, fullRegion2, 5);

   pass1.execute();
*/
   // Extract the surface
   //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing
   //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&volData, volData.getEnclosingRegion(), &mesh); // Use for semi-smooth surface
   PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(&volData, volData.getEnclosingRegion(), &mesh); // Use if not smoothing

   surf.execute();

   //Optional in release mode - simplify (decimate) the mesh
   //PolyVox::MeshDecimator<PolyVox::PositionMaterialNormal> decim(&mesh, &mesh2);
   //decim.execute();
   
   // Change mesh to mesh2 if using decimation
   const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices();
   const std::vector<uint32_t>& vecIndices = mesh.getIndices();

      // create something to draw the PolyVox stuff to
   /*
   if(ogreMesh != NULL) {
      ogreNode->detachObject(ogreMesh);
      mKeyDevices.mSceneMgr->destroyManualObject(ogreMesh);
      ogreMesh = NULL;
   }
   */
   if(ogreMesh == NULL) {
      ogreMesh = mKeyDevices.mSceneMgr->createManualObject("PolyVox Mesh");
      // YES we do intend to change the mesh later -.-
      ogreMesh->setDynamic(true);
      ogreMesh->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST);
   } else ogreMesh->beginUpdate(0);

   if(ogreMesh != NULL) {
      /*
      if ( ogreNode != NULL) {
         mKeyDevices.mSceneMgr->destroySceneNode(ogreNode);
         ogreNode = NULL;
      }
      */
      if (ogreNode == NULL) {

         ogreNode = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode("testnode1", Ogre::Vector3(0, 0, 0));
      }
   
      // 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();
         const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal();
         //const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength);
         const PolyVox::Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner());
         ogreMesh->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ());
         ogreMesh->normal(v3dVertexNormal.getX(), v3dVertexNormal.getY(), v3dVertexNormal.getZ());
         uint8_t mat = vertex.getMaterial() + 0.5;
         uint8_t red = mat & 0xF0;
         uint8_t green = mat & 0x03;
         uint8_t blue = mat & 0x0C;
         ogreMesh->colour(red*2, green*4, blue*4);// just some random colors, I'm too lazy for hsv
      }

      // end writing
      ogreMesh->end();

      //atach object to node
      if (mMeshAttached == false)
         ogreNode->attachObject(ogreMesh);
         mMeshAttached = true;
   }
}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Tue Feb 14, 2012 7:47 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I changed my function to take a structure, but it's crashing during the same Raycast that worked fine before and I'm not really sure why. The crash happens in simpleVolumeSampler.inl in this block of code with an Access Violation.

Raycast is like so -

Code:
   PolyVox::RaycastResult raycastResult;
   PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8> raycast(&pMesh.volume, start, direction, raycastResult);
   raycast.execute();


crash stops here-

Code:
   template <typename VoxelType>
   VoxelType SimpleVolume<VoxelType>::Sampler::getVoxel(void) const
   {
      return *mCurrentVoxel;
   }


my custom stucture to hold volume, node data -

Code:
struct Polymesh {
   PolyVox::SimpleVolume<Density8> volume;
   Ogre::SceneNode * node;
   Ogre::ManualObject * meshOBJ;
   Vector3 position;
   Polymesh():volume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(100,256,100))), node(NULL), meshOBJ(NULL){}
};


function that takes Polymesh structure and renders a mesh from it -

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

   // Reduced mesh - use for non-smooth mesh
   /*
   Region reducedRegion = volData.getEnclosingRegion();
   reducedRegion.shiftLowerCorner(Vector3DInt32(2,2,2));
   reducedRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2));
   PolyVox::CubicSurfaceExtractorWithNormals<SimpleVolume, Density8> surf(&volData, reducedRegion, &mesh);
      
   
   // Smooth using a lowpassfilter
   
   Region fullRegion = volData.getEnclosingRegion();
   //fullRegion.shiftLowerCorner(Vector3DInt32(2,2,2));
   //fullRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2));

   SimpleVolume<Density8> resultVolume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(myTerrainHM.getWidth(),256,myTerrainHM.getHeight())));

   Region fullRegion2 = resultVolume.getEnclosingRegion();
   fullRegion2.shiftLowerCorner(Vector3DInt32(2,2,2));
   fullRegion2.shiftUpperCorner(Vector3DInt32(-2,-2,-2));

   LowPassFilter<SimpleVolume, SimpleVolume, Density8> pass1(&volData, fullRegion2, &resultVolume, fullRegion2, 5);

   pass1.execute();
*/
   // Extract the surface
   //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing
   PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&pMesh.volume, pMesh.volume.getEnclosingRegion(), &mesh); // Use for semi-smooth surface
   //PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(pMesh.volume, pMesh.volume->getEnclosingRegion(), &mesh); // Use if not smoothing

   surf.execute();

   //Optional in release mode - simplify (decimate) the mesh
   //PolyVox::MeshDecimator<PolyVox::PositionMaterialNormal> decim(&mesh, &mesh2);
   //decim.execute();
   
   // Change mesh to mesh2 if using decimation
   const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices();
   const std::vector<uint32_t>& vecIndices = mesh.getIndices();

      // create something to draw the PolyVox stuff to
   /*
   if(ogreMesh != NULL) {
      ogreNode->detachObject(ogreMesh);
      mKeyDevices.mSceneMgr->destroyManualObject(ogreMesh);
      ogreMesh = NULL;
   }
   */
   if(pMesh.meshOBJ == NULL) {
      pMesh.meshOBJ = mKeyDevices.mSceneMgr->createManualObject();
      // YES we do intend to change the mesh later -.-
      pMesh.meshOBJ->setDynamic(true);
      pMesh.meshOBJ->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST);
   } else pMesh.meshOBJ->beginUpdate(0);

   if(pMesh.meshOBJ != NULL) {
      /*
      if ( ogreNode != NULL) {
         mKeyDevices.mSceneMgr->destroySceneNode(ogreNode);
         ogreNode = NULL;
      }
      */
      if (pMesh.node == NULL) {

         pMesh.node = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode(pMesh.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();
         const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal();
         //const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength);
         const PolyVox::Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner());
         pMesh.meshOBJ->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ());
         pMesh.meshOBJ->normal(v3dVertexNormal.getX(), v3dVertexNormal.getY(), v3dVertexNormal.getZ());
         uint8_t mat = vertex.getMaterial() + 0.5;
         uint8_t red = mat & 0xF0;
         uint8_t green = mat & 0x03;
         uint8_t blue = mat & 0x0C;
         pMesh.meshOBJ->colour(red*2, green*4, blue*4);// just some random colors, I'm too lazy for hsv
      }

      // end writing
      pMesh.meshOBJ->end();

      //atach object to node
      pMesh.node->attachObject(pMesh.meshOBJ);
   }
}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Wed Feb 15, 2012 9:29 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm not sure if it is the problem, but it appears you are creating a seperate volume for each mesh. You shouldn't do this - instead you should have a single volume for your whole world. You should then create multiple meshes from this single volume, where each mesh corresponds to a different part of the volume. You can do this by passing a Region to the surface extractor, and so each mesh will be generated from the same volume but using a different region.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Sat Feb 18, 2012 7:22 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I've switched everything to use a single volume and I'm now splitting the volume into 64 x 64 x 64 regions and extracting a mesh for each region, then attaching the mesh to a seperate node but I'm having trouble raycasting to the correct node. I seem to only be able to get 1 node when using the following code -

Code:
   if (ms.buttonDown(OIS::MB_Left)){
      if(raycastResult.foundIntersection) {
         volume.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity);
         float distance, oldDistance = 0.0;
         Polymesh p;
            for( std::vector<Polymesh>::iterator i = polyMeshes.begin(); i != polyMeshes.end(); i ++){
            if((*i).meshOBJ->getBoundingBox().contains(Vector3( raycastResult.intersectionVoxel.getX() ,raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ())))
               p = (*i);            
         }
         PolyvoxMeshtoManual(p);
         //PolyvoxMeshtoManual(reg);
      }
   }


my Polymesh struct looks almost the same as before -

Code:
struct Polymesh {
   Region region;
   SceneNode * node;
   ManualObject * meshOBJ;
   Vector3 position;
   bool mMeshAttached;
   Polymesh():node(NULL), meshOBJ(NULL), position(Vector3(0,0,0)), mMeshAttached(false){}
};


and my mesh rendering function -

Code:
void WorldCraft::PolyvoxMeshtoManual(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<SimpleVolume, 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

   surf.execute();
   
   // Change mesh to mesh2 if using decimation
   const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices();
   const std::vector<uint32_t>& vecIndices = mesh.getIndices();

   if(p.meshOBJ == NULL) {
      p.meshOBJ = mKeyDevices.mSceneMgr->createManualObject();
      // YES we do intend to change the mesh later -.-
      p.meshOBJ->setDynamic(true);
      p.meshOBJ->estimateIndexCount(17000);
      p.meshOBJ->estimateVertexCount(17000);
      p.meshOBJ->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST);
   } else p.meshOBJ->beginUpdate(0);

   if(p.meshOBJ != NULL) {
      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();
         const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal();
         //const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength);
         const PolyVox::Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner());
         p.meshOBJ->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ());
         p.meshOBJ->normal(v3dVertexNormal.getX(), v3dVertexNormal.getY(), v3dVertexNormal.getZ());
         uint8_t mat = vertex.getMaterial() + 0.5;
         uint8_t red = mat & 0xF0;
         uint8_t green = mat & 0x03;
         uint8_t blue = mat & 0x0C;
         p.meshOBJ->colour(red*2, green*4, blue*4);
      }

      // end writing
      p.meshOBJ->end();

       if (p.mMeshAttached == false){
          p.node->attachObject(p.meshOBJ);
          p.mMeshAttached = true;
          p.node->showBoundingBox(true);
       }
       else {
          if (p.node->getShowBoundingBox() == true)
             p.node->showBoundingBox(false);
          else
             p.node->showBoundingBox(true);
       }
   }
}


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Sun Feb 19, 2012 8:56 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I'm not certain, but you may find that all your nodes have the same bounding box (e.g. (0,0,0) to (64, 64, 64)) and that you also need to take into account the position of the node (which might be something like (64, 128, 128)) in order to get the real bounding box. E.g. the Ogre bounding box may be local to that node and you may need to transform it into world space.

However, you don't actually need to use the bounding boxes to determine which node a voxel is in. Thinking in one dimension, let's say we have a range from 0 to 255 which is broken up unto chunks of 64 (0-63, 64-127, 128-191, 192-255). If we have position 150, we do not need to check each of the ranges to see if it within them. Instead we just use integer division: 150 / 64 = 2 tells us it is in the second range (where we consider them to be numbered starting from zero).

Integer division and modulus operation are very useful in voxel worlds.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Realtime Ogre 1.8 Terrain Component manipulation
PostPosted: Sun Feb 19, 2012 6:33 pm 

Joined: Wed Jan 11, 2012 7:33 pm
Posts: 109
I'm not really sure I understand your method of finding a node based off division. Sure that gets a number, but how does a "range" determine which node a voxel is in?


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 128 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12, 13  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