It is currently Sat Aug 22, 2020 5:43 am


All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Just wanted to share some editing class
PostPosted: Wed Mar 09, 2011 10:07 pm 

Joined: Fri Feb 18, 2011 8:41 pm
Posts: 173
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


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Just wanted to share some editing class
PostPosted: Wed Mar 09, 2011 11:08 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
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 :)


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

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