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

Voxel Picking
http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=464
Page 1 of 1

Author:  markkurt [ Thu Nov 29, 2012 12:33 pm ]
Post subject:  Voxel Picking

Hi, I'm pretty new to PolyVox and curious if anyone has experience doing 3d picking - basically I am trying to figure out which voxel is hit, and then modifying the density to be 0 for that voxel - which I assume should have the effect of "eroding" my voxel terrain.

I do a raycastWithDirection from my eye point, in the direction of the projected 2D touch point (I'm doing this on iOS):
Code:
    VoxelPickerRaycastCallback voxelPickerRaycastCallback;
    RaycastResult intersection=raycastWithDirection(volData, start, direction, voxelPickerRaycastCallback);


Inside my VoxelPickerRaycastCallback, I keep track of the intersection points (I am suspicious of whether this is correct):

Code:
    bool operator()(const SimpleVolume<MaterialDensityPair88>::Sampler& sampler) {
      MaterialDensityPair88 voxel=sampler.getVoxel();
      Vector3DInt32 position=sampler.getPosition();
      intersectPoints.push_back(position);
      return true;
    }


And then finally I go through the intersect points and modify the density:

Code:
    if (intersection==RaycastResult::Completed) {
      NSLog(@"Found Intersection");
      vector<Vector3DInt32>::iterator i=voxelPickerRaycastCallback.intersectPoints.begin();
     
      while (i!=voxelPickerRaycastCallback.intersectPoints.end()) {
        //NSLog(@"Hit At:%d, %d, %d", (*i).getX(), (*i).getY(), (*i).getZ());
       
        //update the voxel data and rebuild the
        MaterialDensityPair88 voxel=volData->getVoxelAt((int)(i->getX()), (int)(i->getY()), (int)(i->getZ()));
        if (voxel.getDensity()>0) {
          voxel.setDensity(0);
          volData->setVoxelAt((int)(i->getX()), (int)(i->getY()), (int)(i->getZ()), voxel);
        }
       
        ++i;
      }
     
      [self regenerateBuffers];
    }


I get back a bunch of points in the intersect points, and it turns out that none of them ever trigger the voxel.getDensity()>0 condition.

Am I on the completely wrong path? I have done 3D picking before, but never felt completely confident in my abilities on it however.

Author:  David Williams [ Thu Nov 29, 2012 8:29 pm ]
Post subject:  Re: Voxel Picking

The first question is whether your 'direction' vector has some reasonable length to it, as the length of this vector determines how far the ray is cast (a common mistake is to pass a unit vector here).

Also, you operator() is always returning true, which means the ray will pass though all voxels even if they are solid. This is OK if it's your desired behaviour, but in many cases I would expect you to stop the ray once you have hit something.

Because you are passing though solid voxels (if they exist of course) you will always travel the full length of the ray. That is, the return result will always be RayCast::Completed. If you interupt the raycast by returning false (because you have encountered a solid voxel) then the return result will be Raycast::Interupted.

Lastly, be aware that the raycast is designed for cubic style terrain - i.e. where each voxel can be considered solid or empty. You can still use it on smooth terrain but it might be off by a voxel or so.

Did you see the raycast unit test? That would be a good starting point.

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