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)
{
//This vector hold the position of the center of the volume
@ -469,9 +502,10 @@ int main(int argc, char *argv[])
openGLWidget.show();
//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);
createPerlinVolumeFast(volData);
createPerlinTerrain(volData);
volData.setBlockCacheSize(8);
/*srand(12345);
for(int ct = 0; ct < 1000; ct++)
@ -487,12 +521,12 @@ int main(int argc, char *argv[])
}*/
//Extract the surface
SurfaceMesh<PositionMaterialNormal> mesh;
/*SurfaceMesh<PositionMaterialNormal> mesh;
CubicSurfaceExtractorWithNormals<MaterialDensityPair44> 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();

View File

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

View File

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

View File

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

View File

@ -49,7 +49,13 @@ namespace PolyVox
template <typename VoxelType>
Volume<VoxelType>::Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength)
: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.
resize(uWidth, uHeight, uDepth, uBlockSideLength);
}
@ -262,6 +268,18 @@ namespace PolyVox
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.
/// \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));
}
template <typename VoxelType>
void Volume<VoxelType>::setBlockCacheSize(uint16_t uBlockCacheSize)
{
clearBlockCache();
m_uBlockCacheSize = uBlockCacheSize;
}
template <typename VoxelType>
Block<VoxelType>* Volume<VoxelType>::getUncompressedBlock(Block<VoxelType>* block) const
{
@ -354,8 +380,10 @@ namespace PolyVox
return block;
}
const uint32_t MaxUncompressedBlocks = 10;
if(m_pUncompressedBlocks.size() == MaxUncompressedBlocks)
uint32_t uUncompressedBlockIndex = 100000000;
assert(m_pUncompressedBlocks.size() <= m_uBlockCacheSize);
if(m_pUncompressedBlocks.size() == m_uBlockCacheSize)
{
int32_t leastRecentlyUsedBlockIndex = -1;
uint32_t uLeastRecentTimestamp = 1000000000000000;
@ -369,6 +397,7 @@ namespace PolyVox
}
m_pUncompressedBlocks[leastRecentlyUsedBlockIndex]->compress();
m_uCompressions++;
m_pUncompressedBlocks[leastRecentlyUsedBlockIndex] = block;
}
else
@ -377,6 +406,7 @@ namespace PolyVox
}
block->uncompress();
m_uUncompressions++;
return block;
}