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

Just wanted to share some editing class
http://www.volumesoffun.com/phpBB3/viewtopic.php?f=2&t=168
Page 1 of 1

Author:  Shanee [ Wed Mar 09, 2011 10:07 pm ]
Post subject:  Just wanted to share some editing class

hopefully it will be useful for anyone :)

header:
Code:
class VoxelEditor
   {
   public:
      template <typename VoxelType>
      static void smoothSphereRegion(PolyVox::Volume<VoxelType>& volData, const PolyVox::Region& regionToSmooth, Vector3& sphereCenter, float radius);
   
      static void BoxBrush(PolyVox::Volume<PolyVox::MaterialDensityPair44>& volume, Vector3 &min, Vector3 &max, uint8_t density, float smooth = 0);
      static void SphereBrush(PolyVox::Volume<PolyVox::MaterialDensityPair44>& volume, Vector3 &position, float radius, uint8_t density, float smooth = 0);
   };

float GetDistanceSquared(CONST D3DXVECTOR3* vec1, CONST D3DXVECTOR3* vec2);


cpp:
Code:
void VoxelEditor::BoxBrush(PolyVox::Volume<PolyVox::MaterialDensityPair44>& volume, Vector3 &min, Vector3 &max, uint8_t density, float smooth)
   {
      Vector3 boxCenter = (max + min) / 2;
      Vector3 boxExtents = boxCenter - min;
      float xDiff, yDiff, zDiff;
      float maxDiff;
      Vector3 innerExtents = boxExtents - Vector3(smooth,smooth,smooth);

      for (int z = min.z; z <= max.z; z++)
      {
         for (int y = min.y; y <= max.y; y++)
         {
            for (int x = min.x; x <= max.x; x++)
            {
               // Store our current position as a vector...
               Vector3 v3dCurrentPos(x,y,z);
               
               // Our new density value

               xDiff = 1 - clamp((abs(v3dCurrentPos.x - boxCenter.x) - innerExtents.x) / smooth, 0, 1);
               yDiff = 1 - clamp((abs(v3dCurrentPos.y - boxCenter.y) - innerExtents.y) / smooth, 0, 1);
               zDiff = 1 - clamp((abs(v3dCurrentPos.z - boxCenter.z) - innerExtents.z) / smooth, 0, 1);

               maxDiff = max(xDiff, max(yDiff, zDiff)) ;

               uint8_t uDensity = density * maxDiff;

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

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

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

      PolyVox::smoothRegion(volume, PolyVox::Region(PolyVox::Vector3DInt16(min.x, min.y, min.z), PolyVox::Vector3DInt16(max.x, max.y, max.z));
   }

   void VoxelEditor::SphereBrush(PolyVox::Volume<PolyVox::MaterialDensityPair44>& volume, Vector3 &position, float radius, uint8_t density, float smooth)
   {
      float smoothSQ = smooth * smooth;
      float radiusSQ = radius * radius;
      float distanceSQ;
      float diff;
      
      for (int z = (position.z - radius); z <= (position.z + radius); z++)
      {
         for (int y = (position.y - radius); y <= (position.y + radius); y++)
         {
            for (int x = (position.x - radius); x <= (position.x + radius); x++)
            {
               // Store our current position as a vector...
               Vector3 v3dCurrentPos(x,y,z);
               // And compute how far the current position is from the center of the volume

               distanceSQ = GetDistanceSquared(&position, &v3dCurrentPos);
               
               if (distanceSQ <= radiusSQ)
               {
                  // Our new density value
                  uint8_t uDensity = density;
                  
                  diff = radiusSQ - distanceSQ;
                  if (smoothSQ >= diff)
                     uDensity = sqrt(abs(distanceSQ-radiusSQ) / smooth) * density;

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

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

                  // Write the voxel value into the volume
                  volume.setVoxelAt(x, y, z, voxel);
               }
            }
         }
      }
   
      VoxelEditor::smoothSphereRegion(volume, PolyVox::Region(PolyVox::Vector3DInt16(position.x - radius, position.y - radius, position.z - radius), PolyVox::Vector3DInt16(position.x + radius, position.y + radius, position.z + radius)), position, radius);
   }

   template <typename VoxelType>
   void VoxelEditor::smoothSphereRegion(PolyVox::Volume<VoxelType>& volData, const PolyVox::Region& regionToSmooth, Vector3& sphereCenter, float radius)
   {
      PolyVox::Region croppedRegion = regionToSmooth;
      croppedRegion.cropTo(volData.getEnclosingRegion());

      PolyVox::Array<3, uint16_t> temp(PolyVox::ArraySizes(croppedRegion.width())(croppedRegion.height())(croppedRegion.depth()));

      for (int z = croppedRegion.getLowerCorner().getZ(); z < croppedRegion.getUpperCorner().getZ(); z++)
      {
         for (int y = croppedRegion.getLowerCorner().getY(); y < croppedRegion.getUpperCorner().getY(); y++)
         {
            for (int x = croppedRegion.getLowerCorner().getX(); x < croppedRegion.getUpperCorner().getX(); x++)
            {
               uint16_t& uDensity = temp[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()];

               uDensity=0;
               uDensity += volData.getVoxelAt(x-1,y-1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-1,y-1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-1,y-1,z+1).getDensity();
               uDensity += volData.getVoxelAt(x-1,y-0,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-1,y-0,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-1,y-0,z+1).getDensity();
               uDensity += volData.getVoxelAt(x-1,y+1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-1,y+1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-1,y+1,z+1).getDensity();

               uDensity += volData.getVoxelAt(x-0,y-1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-0,y-1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-0,y-1,z+1).getDensity();
               uDensity += volData.getVoxelAt(x-0,y-0,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-0,y-0,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-0,y-0,z+1).getDensity();
               uDensity += volData.getVoxelAt(x-0,y+1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x-0,y+1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x-0,y+1,z+1).getDensity();

               uDensity += volData.getVoxelAt(x+1,y-1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x+1,y-1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x+1,y-1,z+1).getDensity();
               uDensity += volData.getVoxelAt(x+1,y-0,z-1).getDensity();
               uDensity += volData.getVoxelAt(x+1,y-0,z-0).getDensity();
               uDensity += volData.getVoxelAt(x+1,y-0,z+1).getDensity();
               uDensity += volData.getVoxelAt(x+1,y+1,z-1).getDensity();
               uDensity += volData.getVoxelAt(x+1,y+1,z-0).getDensity();
               uDensity += volData.getVoxelAt(x+1,y+1,z+1).getDensity();
               uDensity /= 27;
            }
         }
      }

      float radiusSQ = radius * radius;
      for (int z = croppedRegion.getLowerCorner().getZ(); z < croppedRegion.getUpperCorner().getZ(); z++)
      {
         for (int y = croppedRegion.getLowerCorner().getY(); y < croppedRegion.getUpperCorner().getY(); y++)
         {
            for (int x = croppedRegion.getLowerCorner().getX(); x < croppedRegion.getUpperCorner().getX(); x++)
            {
               Vector3 v3dCurrentPos(x,y,z);
               if (GetDistanceSquared(&v3dCurrentPos, &sphereCenter) > radiusSQ)
                  continue;

               uint16_t& uDensity = temp[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()];

               PolyVox::MaterialDensityPair44 val = volData.getVoxelAt(x,y,z);
               val.setDensity(uDensity);
               volData.setVoxelAt(x,y,z,val);
            }
         }
      }
   }

float GetDistanceSquared(CONST D3DXVECTOR3* vec1, CONST D3DXVECTOR3* vec2)
   {
      Vector3 diffVec = *vec2 - *vec1;

      float distance = diffVec.x * diffVec.x + diffVec.y * diffVec.y + diffVec.z * diffVec.z;

      

      return distance;
   }


I must admit I didn't test the box brush yet :) but here is an example done with these settings:
Code:
PolyVox::Volume<PolyVox::MaterialDensityPair44> volume(1024, 512, 1024);

   VoxelEditor::SphereBrush(volume, Vector3(512, 256, 512), 21, 15, 4);

Image

Author:  David Williams [ Wed Mar 09, 2011 11:08 pm ]
Post subject:  Re: Just wanted to share some editing class

Very nice, I'm sure some people will be interested in what you're doing here. If you do end up with more code that you want to share the Wiki would be a great place for it :)

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