diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index 2318d55c..ce80aaec 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -343,7 +343,7 @@ Perlin::Perlin(int octaves,float freq,float amp,int seed) mStart = true; } -void createPerlinVolume(Volume& volData) +void createPerlinVolumeSlow(Volume& volData) { Perlin perlin(2,8,1,234); @@ -374,6 +374,54 @@ void createPerlinVolume(Volume& volData) } } +void createPerlinVolumeFast(Volume& volData) +{ + Perlin perlin(2,8,1,234); + + for(int blockZ = 0; blockZ < volData.m_uDepthInBlocks; blockZ++) + { + std::cout << blockZ << std::endl; + for(int blockY = 0; blockY < volData.m_uHeightInBlocks; blockY++) + { + for(int blockX = 0; blockX < volData.m_uWidthInBlocks; blockX++) + { + for(int offsetz = 0; offsetz < volData.m_uBlockSideLength; offsetz++) + { + for(int offsety = 0; offsety < volData.m_uBlockSideLength; offsety++) + { + for(int offsetx = 0; offsetx < volData.m_uBlockSideLength; offsetx++) + { + int x = blockX * volData.m_uBlockSideLength + offsetx; + int y = blockY * volData.m_uBlockSideLength + offsety; + int z = blockZ * volData.m_uBlockSideLength + offsetz; + + if((x == 0) || (x == volData.getWidth()-1)) continue; + if((y == 0) || (y == volData.getHeight()-1)) continue; + if((z == 0) || (z == volData.getDepth()-1)) continue; + + float perlinVal = perlin.Get3D(x /static_cast(volData.getWidth()-1), (y) / static_cast(volData.getHeight()-1), z / static_cast(volData.getDepth()-1)); + + MaterialDensityPair44 voxel; + if(perlinVal < 0.0f) + { + voxel.setMaterial(245); + voxel.setDensity(MaterialDensityPair44::getMaxDensity()); + } + else + { + voxel.setMaterial(0); + voxel.setDensity(MaterialDensityPair44::getMinDensity()); + } + + volData.setVoxelAt(x, y, z, voxel); + } + } + } + } + } + } +} + void createSphereInVolume(Volume& volData, Vector3DFloat v3dVolCenter, float fRadius) { //This vector hold the position of the center of the volume @@ -421,9 +469,9 @@ int main(int argc, char *argv[]) openGLWidget.show(); //Create an empty volume and then place a sphere in it - Volume volData(128, 128, 128); + Volume volData(1024, 1024, 1024); //createSphereInVolume(volData, 30); - createPerlinVolume(volData); + createPerlinVolumeFast(volData); /*srand(12345); for(int ct = 0; ct < 1000; ct++) @@ -439,12 +487,12 @@ int main(int argc, char *argv[]) }*/ //Extract the surface - SurfaceMesh mesh; + /*SurfaceMesh mesh; CubicSurfaceExtractorWithNormals surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); surfaceExtractor.execute(); //Pass the surface to the OpenGL window - openGLWidget.setSurfaceMeshToRender(mesh); + openGLWidget.setSurfaceMeshToRender(mesh);*/ //Run the message pump. return app.exec(); diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.h b/library/PolyVoxCore/include/PolyVoxImpl/Block.h index 18d536d7..4a0bdce8 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.h @@ -61,6 +61,7 @@ namespace PolyVox uint8_t m_uSideLengthPower; VoxelType* m_tUncompressedData; bool m_bIsCompressed; + bool m_bIsUncompressedDataModified; uint64_t m_uTimestamp; std::vector runlengths; diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl index 5ccb1d14..fc86ed63 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl @@ -38,6 +38,7 @@ namespace PolyVox ,m_uSideLengthPower(0) ,m_tUncompressedData(0) ,m_bIsCompressed(true) + ,m_bIsUncompressedDataModified(true) ,m_uTimestamp(0) { if(uSideLength != 0) @@ -77,6 +78,7 @@ namespace PolyVox m_uSideLength = rhs.m_uSideLength; m_uSideLengthPower = rhs.m_uSideLengthPower; m_bIsCompressed = rhs.m_bIsCompressed; + m_bIsUncompressedDataModified = rhs.m_bIsUncompressedDataModified; m_uTimestamp = rhs.m_uTimestamp; runlengths = rhs.runlengths; values = rhs.values; @@ -134,6 +136,8 @@ namespace PolyVox uYPos * m_uSideLength + uZPos * m_uSideLength * m_uSideLength ] = tValue; + + m_bIsUncompressedDataModified = true; } template @@ -152,6 +156,8 @@ namespace PolyVox const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue); + + m_bIsUncompressedDataModified = true; } template @@ -180,6 +186,8 @@ namespace PolyVox //If this fails an exception will be thrown. Memory is not //allocated and there is nothing else in this class to clean up m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; + + m_bIsUncompressedDataModified = true; } } @@ -200,38 +208,43 @@ namespace PolyVox template void Block::compress(void) { - uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; - runlengths.clear(); - values.clear(); + //If the uncompressed data hasn't actually been + //modified then we don't need to redo the compression. + if(m_bIsUncompressedDataModified) + { + uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; + runlengths.clear(); + values.clear(); - VoxelType current = m_tUncompressedData[0]; - uint8_t runLength = 1; + VoxelType current = m_tUncompressedData[0]; + uint8_t runLength = 1; - for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct) - { - VoxelType value = m_tUncompressedData[ct]; - if((value == current) && (runLength < (std::numeric_limits::max)())) - { - runLength++; - } - else - { - runlengths.push_back(runLength); - values.push_back(current); - current = value; - runLength = 1; + for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct) + { + VoxelType value = m_tUncompressedData[ct]; + if((value == current) && (runLength < (std::numeric_limits::max)())) + { + runLength++; + } + else + { + runlengths.push_back(runLength); + values.push_back(current); + current = value; + runLength = 1; + } } + + runlengths.push_back(runLength); + values.push_back(current); + + //Shrink the vectors to their contents (seems slow?): + //http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector + //C++0x may have a shrink_to_fit() function? + //std::vector(runlengths).swap(runlengths); + //std::vector(values).swap(values); } - runlengths.push_back(runLength); - values.push_back(current); - - //Shrink the vectors to their contents (seems slow?): - //http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector - //C++0x may have a shrink_to_fit() function? - //std::vector(runlengths).swap(runlengths); - //std::vector(values).swap(values); - delete[] m_tUncompressedData; m_tUncompressedData = 0; m_bIsCompressed = true; @@ -270,5 +283,6 @@ namespace PolyVox } m_bIsCompressed = false; + m_bIsUncompressedDataModified = false; } } diff --git a/library/PolyVoxCore/include/Volume.h b/library/PolyVoxCore/include/Volume.h index 3c94d443..18fc33a6 100644 --- a/library/PolyVoxCore/include/Volume.h +++ b/library/PolyVoxCore/include/Volume.h @@ -155,7 +155,7 @@ namespace PolyVox ///Resises the volume to the specified dimensions void resize(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32); - private: + public: Block* getUncompressedBlock(Block* block) const; Block m_pBorderBlock;