diff --git a/include/VolumeChangeTracker.h b/include/VolumeChangeTracker.h index 396a5888..331f1029 100644 --- a/include/VolumeChangeTracker.h +++ b/include/VolumeChangeTracker.h @@ -56,7 +56,6 @@ namespace PolyVox std::list getChangedRegionGeometry(void); void setAllUpToDateFlagsTo(bool newUpToDateValue); - void createSphereAt(Vector3DFloat centre, float radius, boost::uint8_t value, bool painting); //void generateLevelVolume(void); @@ -73,9 +72,10 @@ namespace PolyVox public: - void markVoxelChanged(boost::uint16_t x, boost::uint16_t y, boost::uint16_t z); void markRegionChanged(boost::uint16_t firstX, boost::uint16_t firstY, boost::uint16_t firstZ, boost::uint16_t lastX, boost::uint16_t lastY, boost::uint16_t lastZ); + void setVoxelAt(boost::uint16_t x, boost::uint16_t y, boost::uint16_t z, boost::uint8_t value); + static boost::uint16_t fileNo; diff --git a/source/VolumeChangeTracker.cpp b/source/VolumeChangeTracker.cpp index f5f164a8..9abc98bf 100644 --- a/source/VolumeChangeTracker.cpp +++ b/source/VolumeChangeTracker.cpp @@ -113,103 +113,12 @@ namespace PolyVox { for(uint16_t blockX = 0; blockX < POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS; ++blockX) { - //surfaceUpToDate[blockX][blockY][blockZ] = newUpToDateValue; volSurfaceUpToDate->setVoxelAt(blockX, blockY, blockZ, newUpToDateValue); } } } } - void VolumeChangeTracker::createSphereAt(Vector3DFloat centre, float radius, uint8_t value, bool painting) - { - int firstX = static_cast(std::floor(centre.x() - radius)); - int firstY = static_cast(std::floor(centre.y() - radius)); - int firstZ = static_cast(std::floor(centre.z() - radius)); - - int lastX = static_cast(std::ceil(centre.x() + radius)); - int lastY = static_cast(std::ceil(centre.y() + radius)); - int lastZ = static_cast(std::ceil(centre.z() + radius)); - - float radiusSquared = radius * radius; - - //Check bounds - firstX = std::max(firstX,0); - firstY = std::max(firstY,0); - firstZ = std::max(firstZ,0); - - lastX = std::min(lastX,int(volumeData->getSideLength()-1)); - lastY = std::min(lastY,int(volumeData->getSideLength()-1)); - lastZ = std::min(lastZ,int(volumeData->getSideLength()-1)); - - VolumeIterator volIter(*volumeData); - volIter.setValidRegion(firstX,firstY,firstZ,lastX,lastY,lastZ); - volIter.setPosition(firstX,firstY,firstZ); - while(volIter.isValidForRegion()) - { - //if((volIter.getPosX()*volIter.getPosX()+volIter.getPosY()*volIter.getPosY()+volIter.getPosZ()*volIter.getPosZ()) < radiusSquared) - if((centre - Vector3DFloat(volIter.getPosX(),volIter.getPosY(),volIter.getPosZ())).lengthSquared() <= radiusSquared) - { - if(painting) - { - if(volIter.getVoxel() != 0) - { - volIter.setVoxel(value); - //volIter.setVoxelAt(volIter.getPosX(),volIter.getPosY(),volIter.getPosZ(),value); - } - } - else - { - volIter.setVoxel(value); - //volIter.setVoxelAt(volIter.getPosX(),volIter.getPosY(),volIter.getPosZ(),value); - } - //markVoxelChanged(volIter.getPosX(),volIter.getPosY(),volIter.getPosZ()); //FIXME - create a version of this function to mark larger regions at a time. - } - volIter.moveForwardInRegion(); - } - markRegionChanged(firstX,firstY,firstZ,lastX,lastY,lastZ); - } - - void VolumeChangeTracker::markVoxelChanged(uint16_t x, uint16_t y, uint16_t z) - { - //If we are not on a boundary, just mark one region. - if((x % POLYVOX_REGION_SIDE_LENGTH != 0) && - (x % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1) && - (y % POLYVOX_REGION_SIDE_LENGTH != 0) && - (y % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1) && - (z % POLYVOX_REGION_SIDE_LENGTH != 0) && - (z % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1)) - { - //surfaceUpToDate[x >> POLYVOX_REGION_SIDE_LENGTH_POWER][y >> POLYVOX_REGION_SIDE_LENGTH_POWER][z >> POLYVOX_REGION_SIDE_LENGTH_POWER] = false; - volSurfaceUpToDate->setVoxelAt(x >> POLYVOX_REGION_SIDE_LENGTH_POWER, y >> POLYVOX_REGION_SIDE_LENGTH_POWER, z >> POLYVOX_REGION_SIDE_LENGTH_POWER, false); - } - else //Mark surrounding block as well - { - const uint16_t regionX = x >> POLYVOX_REGION_SIDE_LENGTH_POWER; - const uint16_t regionY = y >> POLYVOX_REGION_SIDE_LENGTH_POWER; - const uint16_t regionZ = z >> POLYVOX_REGION_SIDE_LENGTH_POWER; - - const uint16_t minRegionX = (std::max)(uint16_t(0),uint16_t(regionX-1)); - const uint16_t minRegionY = (std::max)(uint16_t(0),uint16_t(regionY-1)); - const uint16_t minRegionZ = (std::max)(uint16_t(0),uint16_t(regionZ-1)); - - const uint16_t maxRegionX = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionX+1)); - const uint16_t maxRegionY = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionY+1)); - const uint16_t maxRegionZ = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionZ+1)); - - for(uint16_t zCt = minRegionZ; zCt <= maxRegionZ; zCt++) - { - for(uint16_t yCt = minRegionY; yCt <= maxRegionY; yCt++) - { - for(uint16_t xCt = minRegionX; xCt <= maxRegionX; xCt++) - { - //surfaceUpToDate[xCt][yCt][zCt] = false; - volSurfaceUpToDate->setVoxelAt(xCt,yCt,zCt,false); - } - } - } - } - } - void VolumeChangeTracker::markRegionChanged(uint16_t firstX, uint16_t firstY, uint16_t firstZ, uint16_t lastX, uint16_t lastY, uint16_t lastZ) { const uint16_t firstRegionX = firstX >> POLYVOX_REGION_SIDE_LENGTH_POWER; @@ -261,4 +170,48 @@ namespace PolyVox { return volumeData; } + + void VolumeChangeTracker::setVoxelAt(boost::uint16_t x, boost::uint16_t y, boost::uint16_t z, boost::uint8_t value) + { + //FIXME - rather than creating a iterator each time we should have one stored + VolumeIterator iterVol(*volumeData); + iterVol.setPosition(x,y,z); + iterVol.setVoxel(value); + + //If we are not on a boundary, just mark one region. + if((x % POLYVOX_REGION_SIDE_LENGTH != 0) && + (x % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1) && + (y % POLYVOX_REGION_SIDE_LENGTH != 0) && + (y % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1) && + (z % POLYVOX_REGION_SIDE_LENGTH != 0) && + (z % POLYVOX_REGION_SIDE_LENGTH != POLYVOX_REGION_SIDE_LENGTH-1)) + { + volSurfaceUpToDate->setVoxelAt(x >> POLYVOX_REGION_SIDE_LENGTH_POWER, y >> POLYVOX_REGION_SIDE_LENGTH_POWER, z >> POLYVOX_REGION_SIDE_LENGTH_POWER, false); + } + else //Mark surrounding regions as well + { + const uint16_t regionX = x >> POLYVOX_REGION_SIDE_LENGTH_POWER; + const uint16_t regionY = y >> POLYVOX_REGION_SIDE_LENGTH_POWER; + const uint16_t regionZ = z >> POLYVOX_REGION_SIDE_LENGTH_POWER; + + const uint16_t minRegionX = (std::max)(uint16_t(0),uint16_t(regionX-1)); + const uint16_t minRegionY = (std::max)(uint16_t(0),uint16_t(regionY-1)); + const uint16_t minRegionZ = (std::max)(uint16_t(0),uint16_t(regionZ-1)); + + const uint16_t maxRegionX = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionX+1)); + const uint16_t maxRegionY = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionY+1)); + const uint16_t maxRegionZ = (std::min)(uint16_t(POLYVOX_VOLUME_SIDE_LENGTH_IN_REGIONS-1),uint16_t(regionZ+1)); + + for(uint16_t zCt = minRegionZ; zCt <= maxRegionZ; zCt++) + { + for(uint16_t yCt = minRegionY; yCt <= maxRegionY; yCt++) + { + for(uint16_t xCt = minRegionX; xCt <= maxRegionX; xCt++) + { + volSurfaceUpToDate->setVoxelAt(xCt,yCt,zCt,false); + } + } + } + } + } }