Fast version of perlin noise.
This commit is contained in:
parent
23a56ed000
commit
42db69e013
@ -343,7 +343,7 @@ Perlin::Perlin(int octaves,float freq,float amp,int seed)
|
|||||||
mStart = true;
|
mStart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createPerlinVolume(Volume<MaterialDensityPair44>& volData)
|
void createPerlinVolumeSlow(Volume<MaterialDensityPair44>& volData)
|
||||||
{
|
{
|
||||||
Perlin perlin(2,8,1,234);
|
Perlin perlin(2,8,1,234);
|
||||||
|
|
||||||
@ -374,6 +374,54 @@ void createPerlinVolume(Volume<MaterialDensityPair44>& volData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createPerlinVolumeFast(Volume<MaterialDensityPair44>& 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<float>(volData.getWidth()-1), (y) / static_cast<float>(volData.getHeight()-1), z / static_cast<float>(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<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
|
||||||
@ -421,9 +469,9 @@ 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(128, 128, 128);
|
Volume<MaterialDensityPair44> volData(1024, 1024, 1024);
|
||||||
//createSphereInVolume(volData, 30);
|
//createSphereInVolume(volData, 30);
|
||||||
createPerlinVolume(volData);
|
createPerlinVolumeFast(volData);
|
||||||
|
|
||||||
/*srand(12345);
|
/*srand(12345);
|
||||||
for(int ct = 0; ct < 1000; ct++)
|
for(int ct = 0; ct < 1000; ct++)
|
||||||
@ -439,12 +487,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();
|
||||||
|
@ -61,6 +61,7 @@ namespace PolyVox
|
|||||||
uint8_t m_uSideLengthPower;
|
uint8_t m_uSideLengthPower;
|
||||||
VoxelType* m_tUncompressedData;
|
VoxelType* m_tUncompressedData;
|
||||||
bool m_bIsCompressed;
|
bool m_bIsCompressed;
|
||||||
|
bool m_bIsUncompressedDataModified;
|
||||||
uint64_t m_uTimestamp;
|
uint64_t m_uTimestamp;
|
||||||
|
|
||||||
std::vector<uint8_t> runlengths;
|
std::vector<uint8_t> runlengths;
|
||||||
|
@ -38,6 +38,7 @@ namespace PolyVox
|
|||||||
,m_uSideLengthPower(0)
|
,m_uSideLengthPower(0)
|
||||||
,m_tUncompressedData(0)
|
,m_tUncompressedData(0)
|
||||||
,m_bIsCompressed(true)
|
,m_bIsCompressed(true)
|
||||||
|
,m_bIsUncompressedDataModified(true)
|
||||||
,m_uTimestamp(0)
|
,m_uTimestamp(0)
|
||||||
{
|
{
|
||||||
if(uSideLength != 0)
|
if(uSideLength != 0)
|
||||||
@ -77,6 +78,7 @@ namespace PolyVox
|
|||||||
m_uSideLength = rhs.m_uSideLength;
|
m_uSideLength = rhs.m_uSideLength;
|
||||||
m_uSideLengthPower = rhs.m_uSideLengthPower;
|
m_uSideLengthPower = rhs.m_uSideLengthPower;
|
||||||
m_bIsCompressed = rhs.m_bIsCompressed;
|
m_bIsCompressed = rhs.m_bIsCompressed;
|
||||||
|
m_bIsUncompressedDataModified = rhs.m_bIsUncompressedDataModified;
|
||||||
m_uTimestamp = rhs.m_uTimestamp;
|
m_uTimestamp = rhs.m_uTimestamp;
|
||||||
runlengths = rhs.runlengths;
|
runlengths = rhs.runlengths;
|
||||||
values = rhs.values;
|
values = rhs.values;
|
||||||
@ -134,6 +136,8 @@ namespace PolyVox
|
|||||||
uYPos * m_uSideLength +
|
uYPos * m_uSideLength +
|
||||||
uZPos * m_uSideLength * m_uSideLength
|
uZPos * m_uSideLength * m_uSideLength
|
||||||
] = tValue;
|
] = tValue;
|
||||||
|
|
||||||
|
m_bIsUncompressedDataModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -152,6 +156,8 @@ namespace PolyVox
|
|||||||
|
|
||||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue);
|
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue);
|
||||||
|
|
||||||
|
m_bIsUncompressedDataModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -180,6 +186,8 @@ namespace PolyVox
|
|||||||
//If this fails an exception will be thrown. Memory is not
|
//If this fails an exception will be thrown. Memory is not
|
||||||
//allocated and there is nothing else in this class to clean up
|
//allocated and there is nothing else in this class to clean up
|
||||||
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||||
|
|
||||||
|
m_bIsUncompressedDataModified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,38 +208,43 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::compress(void)
|
void Block<VoxelType>::compress(void)
|
||||||
{
|
{
|
||||||
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
//If the uncompressed data hasn't actually been
|
||||||
runlengths.clear();
|
//modified then we don't need to redo the compression.
|
||||||
values.clear();
|
if(m_bIsUncompressedDataModified)
|
||||||
|
{
|
||||||
|
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
|
runlengths.clear();
|
||||||
|
values.clear();
|
||||||
|
|
||||||
VoxelType current = m_tUncompressedData[0];
|
VoxelType current = m_tUncompressedData[0];
|
||||||
uint8_t runLength = 1;
|
uint8_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<uint8_t>::max)()))
|
||||||
{
|
{
|
||||||
runLength++;
|
runLength++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runlengths.push_back(runLength);
|
runlengths.push_back(runLength);
|
||||||
values.push_back(current);
|
values.push_back(current);
|
||||||
current = value;
|
current = value;
|
||||||
runLength = 1;
|
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<uint8_t>(runlengths).swap(runlengths);
|
||||||
|
//std::vector<VoxelType>(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<uint8_t>(runlengths).swap(runlengths);
|
|
||||||
//std::vector<VoxelType>(values).swap(values);
|
|
||||||
|
|
||||||
delete[] m_tUncompressedData;
|
delete[] m_tUncompressedData;
|
||||||
m_tUncompressedData = 0;
|
m_tUncompressedData = 0;
|
||||||
m_bIsCompressed = true;
|
m_bIsCompressed = true;
|
||||||
@ -270,5 +283,6 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_bIsCompressed = false;
|
m_bIsCompressed = false;
|
||||||
|
m_bIsUncompressedDataModified = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ namespace PolyVox
|
|||||||
///Resises the volume to the specified dimensions
|
///Resises 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);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
Block<VoxelType>* getUncompressedBlock(Block<VoxelType>* block) const;
|
Block<VoxelType>* getUncompressedBlock(Block<VoxelType>* block) const;
|
||||||
|
|
||||||
Block<VoxelType> m_pBorderBlock;
|
Block<VoxelType> m_pBorderBlock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user