This commit is contained in:
David Williams 2011-02-09 20:52:36 +00:00
parent 4da1f6149a
commit b1eab6c6a3
5 changed files with 89 additions and 13 deletions

View File

@ -422,6 +422,39 @@ void createPerlinVolumeFast(Volume<MaterialDensityPair44>& volData)
} }
} }
void createPerlinTerrain(Volume<MaterialDensityPair44>& volData)
{
Perlin perlin(2,2,1,234);
for(int x = 1; x < volData.getWidth()-1; x++)
{
std::cout << x << std::endl;
for(int y = 1; y < volData.getHeight()-1; y++)
{
float perlinVal = perlin.Get(x / static_cast<float>(volData.getHeight()-1), y / static_cast<float>(volData.getDepth()-1));
perlinVal += 1.0f;
perlinVal *= 0.5f;
perlinVal *= volData.getWidth();
for(int z = 1; z < volData.getDepth()-1; z++)
{
MaterialDensityPair44 voxel;
if(z < perlinVal)
{
voxel.setMaterial(245);
voxel.setDensity(MaterialDensityPair44::getMaxDensity());
}
else
{
voxel.setMaterial(0);
voxel.setDensity(MaterialDensityPair44::getMinDensity());
}
volData.setVoxelAt(x, y, z, voxel);
}
}
}
}
void createSphereInVolume(Volume<MaterialDensityPair44>& volData, Vector3DFloat v3dVolCenter, float fRadius) void createSphereInVolume(Volume<MaterialDensityPair44>& volData, Vector3DFloat v3dVolCenter, float fRadius)
{ {
//This vector hold the position of the center of the volume //This vector hold the position of the center of the volume
@ -469,9 +502,10 @@ int main(int argc, char *argv[])
openGLWidget.show(); openGLWidget.show();
//Create an empty volume and then place a sphere in it //Create an empty volume and then place a sphere in it
Volume<MaterialDensityPair44> volData(256, 256, 256); Volume<MaterialDensityPair44> volData(1024, 1280, 256);
//createSphereInVolume(volData, 30); //createSphereInVolume(volData, 30);
createPerlinVolumeFast(volData); createPerlinTerrain(volData);
volData.setBlockCacheSize(8);
/*srand(12345); /*srand(12345);
for(int ct = 0; ct < 1000; ct++) for(int ct = 0; ct < 1000; ct++)
@ -487,12 +521,12 @@ int main(int argc, char *argv[])
}*/ }*/
//Extract the surface //Extract the surface
SurfaceMesh<PositionMaterialNormal> mesh; /*SurfaceMesh<PositionMaterialNormal> mesh;
CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute(); surfaceExtractor.execute();
//Pass the surface to the OpenGL window //Pass the surface to the OpenGL window
openGLWidget.setSurfaceMeshToRender(mesh); openGLWidget.setSurfaceMeshToRender(mesh);*/
//Run the message pump. //Run the message pump.
return app.exec(); return app.exec();

View File

@ -64,7 +64,7 @@ namespace PolyVox
bool m_bIsUncompressedDataModified; bool m_bIsUncompressedDataModified;
uint64_t m_uTimestamp; uint64_t m_uTimestamp;
std::vector<uint8_t> runlengths; std::vector<uint16_t> runlengths;
std::vector<VoxelType> values; std::vector<VoxelType> values;
}; };
} }

View File

@ -208,6 +208,8 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void Block<VoxelType>::compress(void) void Block<VoxelType>::compress(void)
{ {
assert(m_bIsCompressed == false);
//If the uncompressed data hasn't actually been //If the uncompressed data hasn't actually been
//modified then we don't need to redo the compression. //modified then we don't need to redo the compression.
if(m_bIsUncompressedDataModified) if(m_bIsUncompressedDataModified)
@ -217,12 +219,12 @@ namespace PolyVox
values.clear(); values.clear();
VoxelType current = m_tUncompressedData[0]; VoxelType current = m_tUncompressedData[0];
uint8_t runLength = 1; uint16_t runLength = 1;
for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct) for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct)
{ {
VoxelType value = m_tUncompressedData[ct]; VoxelType value = m_tUncompressedData[ct];
if((value == current) && (runLength < (std::numeric_limits<uint8_t>::max)())) if((value == current) && (runLength < (std::numeric_limits<uint16_t>::max)()))
{ {
runLength++; runLength++;
} }
@ -245,6 +247,7 @@ namespace PolyVox
//std::vector<VoxelType>(values).swap(values); //std::vector<VoxelType>(values).swap(values);
} }
assert(m_tUncompressedData != 0);
delete[] m_tUncompressedData; delete[] m_tUncompressedData;
m_tUncompressedData = 0; m_tUncompressedData = 0;
m_bIsCompressed = true; m_bIsCompressed = true;
@ -253,6 +256,8 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void Block<VoxelType>::uncompress(void) void Block<VoxelType>::uncompress(void)
{ {
assert(m_bIsCompressed == true);
assert(m_tUncompressedData == 0);
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
VoxelType* pUncompressedData = m_tUncompressedData; VoxelType* pUncompressedData = m_tUncompressedData;
@ -261,7 +266,7 @@ namespace PolyVox
//on unsigned chars so is only possible if our voxel type is the right size. //on unsigned chars so is only possible if our voxel type is the right size.
//Nore that memset takes an int type, but sonverts it to unsiogned char: //Nore that memset takes an int type, but sonverts it to unsiogned char:
//http://www.cplusplus.com/reference/clibrary/cstring/memset/ //http://www.cplusplus.com/reference/clibrary/cstring/memset/
if(sizeof(VoxelType) == sizeof(unsigned char)) /*if(sizeof(VoxelType) == sizeof(unsigned char))
{ {
for(uint32_t ct = 0; ct < runlengths.size(); ++ct) for(uint32_t ct = 0; ct < runlengths.size(); ++ct)
{ {
@ -271,7 +276,7 @@ namespace PolyVox
} }
//Otherwise we fall back on a loop. //Otherwise we fall back on a loop.
else else
{ {*/
for(uint32_t ct = 0; ct < runlengths.size(); ++ct) for(uint32_t ct = 0; ct < runlengths.size(); ++ct)
{ {
for(uint32_t i = 0; i < runlengths[ct]; ++i) for(uint32_t i = 0; i < runlengths[ct]; ++i)
@ -280,7 +285,7 @@ namespace PolyVox
++pUncompressedData; ++pUncompressedData;
} }
} }
} //}
m_bIsCompressed = false; m_bIsCompressed = false;
m_bIsUncompressedDataModified = false; m_bIsUncompressedDataModified = false;

View File

@ -120,7 +120,7 @@ namespace PolyVox
public: public:
///Constructor ///Constructor
Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 64); Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32);
///Destructor ///Destructor
~Volume(); ~Volume();
@ -155,12 +155,16 @@ namespace PolyVox
///Resizes the volume to the specified dimensions ///Resizes the volume to the specified dimensions
void resize(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32); void resize(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32);
void setBlockCacheSize(uint16_t uBlockCacheSize);
void clearBlockCache(void);
public: public:
Block<VoxelType>* getUncompressedBlock(Block<VoxelType>* block) const; Block<VoxelType>* getUncompressedBlock(Block<VoxelType>* block) const;
Block<VoxelType> m_pBorderBlock; Block<VoxelType> m_pBorderBlock;
std::vector< Block<VoxelType> > m_pBlocks; std::vector< Block<VoxelType> > m_pBlocks;
mutable std::vector<Block<VoxelType>*> m_pUncompressedBlocks; mutable std::vector<Block<VoxelType>*> m_pUncompressedBlocks;
uint16_t m_uBlockCacheSize;
uint32_t m_uNoOfBlocksInVolume; uint32_t m_uNoOfBlocksInVolume;
@ -179,6 +183,9 @@ namespace PolyVox
uint16_t m_uShortestSideLength; uint16_t m_uShortestSideLength;
float m_fDiagonalLength; float m_fDiagonalLength;
mutable uint64_t m_uTimestamper; mutable uint64_t m_uTimestamper;
mutable uint32_t m_uCompressions;
mutable uint32_t m_uUncompressions;
}; };
//Some handy typedefs //Some handy typedefs

View File

@ -49,7 +49,13 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
Volume<VoxelType>::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength) Volume<VoxelType>::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength)
:m_uTimestamper(0) :m_uTimestamper(0)
,m_uBlockCacheSize(1024)
,m_uCompressions(0)
,m_uUncompressions(0)
,m_uBlockSideLength(uBlockSideLength)
{ {
setBlockCacheSize(m_uBlockCacheSize);
//Create a volume of the right size. //Create a volume of the right size.
resize(uWidth, uHeight, uDepth, uBlockSideLength); resize(uWidth, uHeight, uDepth, uBlockSideLength);
} }
@ -262,6 +268,18 @@ namespace PolyVox
return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
} }
template <typename VoxelType>
void Volume<VoxelType>::clearBlockCache(void)
{
for(uint32_t ct = 0; ct < m_pUncompressedBlocks.size(); ct++)
{
m_pUncompressedBlocks[ct]->compress();
m_uCompressions++;
}
m_pUncompressedBlocks.clear();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// Note: Calling this function will destroy all existing data in the volume. /// Note: Calling this function will destroy all existing data in the volume.
/// \param uWidth The desired width in voxels. This must be a power of two. /// \param uWidth The desired width in voxels. This must be a power of two.
@ -344,6 +362,14 @@ namespace PolyVox
m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth)); m_fDiagonalLength = sqrtf(static_cast<float>(m_uWidth * m_uWidth + m_uHeight * m_uHeight + m_uDepth * m_uDepth));
} }
template <typename VoxelType>
void Volume<VoxelType>::setBlockCacheSize(uint16_t uBlockCacheSize)
{
clearBlockCache();
m_uBlockCacheSize = uBlockCacheSize;
}
template <typename VoxelType> template <typename VoxelType>
Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const
{ {
@ -354,8 +380,10 @@ namespace PolyVox
return block; return block;
} }
const uint32_t MaxUncompressedBlocks = 10; uint32_t uUncompressedBlockIndex = 100000000;
if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks)
assert(m_pUncompressedBlocks.size() <= m_uBlockCacheSize);
if(m_pUncompressedBlocks.size() == m_uBlockCacheSize)
{ {
int32_t leastRecentlyUsedBlockIndex = -1; int32_t leastRecentlyUsedBlockIndex = -1;
uint32_t uLeastRecentTimestamp = 1000000000000000; uint32_t uLeastRecentTimestamp = 1000000000000000;
@ -369,6 +397,7 @@ namespace PolyVox
} }
m_pUncompressedBlocks[leastRecentlyUsedBlockIndex]->compress(); m_pUncompressedBlocks[leastRecentlyUsedBlockIndex]->compress();
m_uCompressions++;
m_pUncompressedBlocks[leastRecentlyUsedBlockIndex] = block; m_pUncompressedBlocks[leastRecentlyUsedBlockIndex] = block;
} }
else else
@ -377,6 +406,7 @@ namespace PolyVox
} }
block->uncompress(); block->uncompress();
m_uUncompressions++;
return block; return block;
} }