Volumes Of Fun
http://www.volumesoffun.com/phpBB3/

Realtime Ogre 1.8 Terrain Component manipulation
http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=312
Page 10 of 13

Author:  David Williams [ Mon Feb 20, 2012 7:46 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

I don't know how/where you are storing your 'PolyMesh' objects, but in my case I store them in a 3D array. So if my volume was 256x256x256, and each mesh was 64x64x64, then I would be able to fit four meshes along each axis. So I would declare a 3D array of PolyMesh objects:

Code:
PolyMesh myMeshes[4][4][4];


Now if I have voxel position (10, 100, 200) then I can do the integer division by 64 to get (0, 1, 3), which are the array indices. From the PolyMesh object you have access to all the components you need.

Author:  drwbns [ Mon Feb 20, 2012 6:59 pm ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

That makes sense - I'll try that David, thank you. I was holding my Polymesh object in a vector, I'll try your 3 dimensional array method.

Author:  David Williams [ Tue Feb 21, 2012 8:26 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

Yep, give it a try. There is no right and wrong solution to this as different applications have different needs (which is why PolyVox doesn't handle it for you). For example, if you want infinite terrain then obviously a fixed size array has some limitations. Perhaps then you would use an std::map or something.

But for you purposes it should work quite well, and you can always change it later of course.

Author:  drwbns [ Tue Feb 21, 2012 7:51 pm ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

Hmm, I'm having trouble figuring out where I'm getting a "vector subscript out of range" error with my volume splitter function. As far as I can tell, I've allocated 9 elements(8 blocks + 1 remainder) and I'm trying to insert the 9th(remainder) element (w2 = 8). Thanks for any help.

Code:
void WorldCraft::volumeSplitter(){
   int volumeLength, volumeWidth, volumeHeight;
   volumeLength = volume.getDepth();
   volumeHeight = volume.getHeight();
   volumeWidth = volume.getWidth();

   lengthSegs = volume.getDepth() / 64;
   lengthRemainder = volume.getDepth() % 64;

   widthSegs = volume.getWidth() / 64;
   widthRemainder = volume.getWidth() % 64;

   heightSegs = volume.getHeight() / 64;
   heightRemainder = volume.getHeight() % 64;
   Vector3 position = Vector3(0,0,0);
   Polymesh p;

   // Set up array sizes.
   if(heightRemainder > 0)
      polyMeshes.resize(heightSegs + 1);
   else
      polyMeshes.resize(heightSegs);

   for (int i = 0; i < heightSegs; ++i) {
      if(widthRemainder > 0)
         polyMeshes[i].resize(widthSegs + 1);
      else
         polyMeshes[i].resize(widthSegs);

      for (int j = 0; j < widthSegs; ++j) {
         if(lengthRemainder > 0)
            polyMeshes[i][j].resize(lengthSegs + 1);
         else
            polyMeshes[i][j].resize(lengthSegs);
      }
   }

   int w2,l2,h2;

   // Iterate over volume - split into regions

   for (int l = 0; l < volume.getDepth(); l+=64){
      for (int w = 0; w < volume.getWidth(); w+=64){
         for (int h = 0; h < volume.getHeight(); h+=64){


            if(l + 64 <= volume.getDepth() && w + 64 <= volume.getWidth() && h + 64 <= volume.getHeight()){
               // region is a block (64 x 64 x 64 voxels)
               p.region = Region(Vector3DInt32(w,h,l),Vector3DInt32(w+64,h+64,l+64));
               p.position = position;
               
               w2 = (w !=0 ? w/ 64 : w);
                  h2 = (h!=0 ? h / 64 : h);
                  l2 = (l!=0 ? l/ 64 : l);

               polyMeshes[h2][w2][l2] = p;
            }
            else {
               // region is a remainder
               p.region = Region(Vector3DInt32(w,h,l),Vector3DInt32(w + widthRemainder,h + heightRemainder,l + lengthRemainder));
               p.position = position;

               w2 = (w !=0 ? w/ 64 : w);
                  h2 = (h!=0 ? h / 64 : h);
                  l2 = (l!=0 ? l/ 64 : l);

               polyMeshes[h2][w2][l2] = p;
            }
            position.y += 64;
         }
         position.y = 0;
         position.x += 64;
      }
      position.x = 0;
      position.z += 64;
   }

}

Author:  David Williams [ Wed Feb 22, 2012 9:55 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

I'm afraid it's rathert difficult to debug that by eye. Can you step through with the dubegger to find out what is going on? It will let you check how big you vectors are, which element you are accessing, etc?

Author:  drwbns [ Fri Feb 24, 2012 8:14 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

I found where I was accesing an ivalid index, but I now want to extend this futher. Is there any way I can dynamically resize my volume in all directions? Does the voxel volume support negative indices? I've ran into a crash where I tried to access a negative index using intersection.previousVoxel and figured PolyVox doesn't support negative indices...I'd like to find some way to create space in all directions.

Author:  ker [ Fri Feb 24, 2012 9:11 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

use LargeVolume. it allows for any 32bit signed positions (Vector3DInt32), and arbitrary resizing during runtime (as it has infinite size)
as David said, you'll need to use a std::map<Vector3DInt32, YourMesh> for accessing your meshes, a fixed size vector won't do anymore.

Author:  drwbns [ Fri Feb 24, 2012 7:58 pm ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

Ok, I've changed back to a LargeVolume and now I have my map of polyMeshes like so-

Code:
std::map<Vector3DInt32, Polymesh> polyMeshes;

but when I try to find my voxel region like so -

Code:
         it = polyMeshes.find(Vector3DInt32(intersect.getY(),intersect.getX(),intersect.getZ()));
         volume.setVoxelAt(newVoxel,VoxelTypeTraits<Density8>::MinDensity);
         volume.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity);
         PolyvoxMeshtoManual(it->second);


I get a map not dereferencable error. My polyMeshes map looks just fine in Debug but my iterator doesn't contain the correct element, why?

I'm storing my regions like before but now in a map now like so -

Code:
   for (int h = 0; h < totalHSegs; h++){
      for (int w = 0; w < totalWSegs; w++){
         for (int l = 0; l < totalLSegs; l++){
            if(l2 + divisor <= volume.getDepth() && w2 + divisor <= volume.getWidth() && h2 + divisor <= volume.getHeight()){
               // region is a block (divisor x divisor x divisor voxels)
               p.region = Region(Vector3DInt32(w2,h2,l2),Vector3DInt32(w2+divisor,h2+divisor,l2+divisor));
               p.position = position;

               polyMeshes.insert(pair<Vector3DInt32,Polymesh>(Vector3DInt32(w,h,l),p));
               //polyMeshes[h][w][l] = p;
            }
            else {
               // region is a remainder
               p.region = Region(Vector3DInt32(w2,h2,l2),Vector3DInt32(w2 + widthRemainder,h2 + heightRemainder,l2 + lengthRemainder));
               p.position = position;

               polyMeshes.insert(pair<Vector3DInt32,Polymesh>(Vector3DInt32(w,h,l),p));
               //polyMeshes[h][w][l] = p;
            }
            l2 += divisor;
            position.z += divisor;
         }
         w2 += divisor;
         l2 = 0;
         position.z = 0;
         position.x += divisor;
      }
      h2 += divisor;
      w2 = 0;
      position.x = 0;
      position.y += divisor;
   }


In my test run, I could plainly see that element [89]in polyMeshes is region 2,6,1, but it didn't point to it....help please

Author:  ker [ Sat Feb 25, 2012 11:39 am ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

first: what is the type of PolyMesh? is it your own class? is it a pointer?

second: for readability i propose you use
Code:
polyMeshes[vecPosition] = yourPolyMesh;

for assignment, but still use find to retrieve elements.

also, if you use find, ALWAYS check
Code:
assert(it != polyMeshes.end())

or a less terminal version of this ;)

Author:  drwbns [ Sat Feb 25, 2012 6:25 pm ]
Post subject:  Re: Realtime Ogre 1.8 Terrain Component manipulation

Polymesh is a struct -

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){}
};


isn't it supposed to be -

Code:
assert(it == polyMeshes.end());


?

I added

Code:
if(it != polyMeshes.end()))


and that seems to resolve the error, but if I try to access a voxel outside the volume, I still get an assert thrown in LargeVolume.inl at -

Code:
   bool LargeVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
   {
      assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));


is there a specific way to resize the volume on the fly?

Also, I'm having trouble getting regions to refresh which are initially empty, but valid. The vertex indices seem to be there but the mesh itself won't show, also the bounding box won't show either. But modifying the underlying voxels works just fine.

Page 10 of 13 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/