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); |
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/ |