chunkgen: take advantage of intervalmap structure

brings down heap memory usage to about 67% of that using arrays (valgrind, tested on standard terrain with renderdistance at 8)
intervalmaps-array-y
EmaMaker 2022-11-20 19:47:04 +01:00 committed by emamaker
parent 8eb15f4725
commit b724640384
3 changed files with 27 additions and 6 deletions

View File

@ -40,6 +40,7 @@ namespace Chunk
void setState(uint8_t nstate, bool value);
void setBlock(Block b, int x, int y, int z);
void setBlocks(int start, int end, Block b);
Block getBlock(int x, int y, int z);
IntervalMap<Block>& getBlocks() { return (this->blocks); }
Block* getBlocksArray(int* len) { return (this->blocks.toArray(len)); }

View File

@ -38,6 +38,10 @@ namespace Chunk
blocks.insert(coord <= 0 ? 0 : coord, coord+1 >= CHUNK_VOLUME ? CHUNK_VOLUME : coord+1, b);
}
void Chunk::setBlocks(int start, int end, Block b){
this->blocks.insert(start < 0 ? 0 : start, end >= CHUNK_VOLUME ? CHUNK_VOLUME : end, b);
}
void Chunk::setState(uint8_t nstate, bool value)
{
if (value)

View File

@ -40,9 +40,15 @@ void generateNoise(Chunk::Chunk *chunk)
dirtNoiseLUT[i] = -1;
}
for (int i = 0; i < CHUNK_SIZE; i++)
Block block_prev{Block::AIR};
int block_prev_start{0};
// The order of iteration MUST RESPECT the order in which the array is transformed from 3d to 1d
for (int k = 0; k < CHUNK_SIZE; k++)
{
for (int j = 0; j < CHUNK_SIZE; j++)
{
for (int i = 0; i < CHUNK_SIZE; i++)
{
int x = i + CHUNK_SIZE * chunk->getPosition().x;
int y = j + CHUNK_SIZE * chunk->getPosition().y;
@ -58,8 +64,6 @@ void generateNoise(Chunk::Chunk *chunk)
int dirtNoise = dirtNoiseLUT[d2];
int stoneLevel = grassNoise - dirtNoise;
// std::cout << grassNoise << " " << dirtNoise << " " << stoneLevel << std::endl;
if (y < stoneLevel)
block = Block::STONE;
else if (y >= stoneLevel && y < grassNoise)
@ -69,8 +73,20 @@ void generateNoise(Chunk::Chunk *chunk)
else
block = Block::AIR;
chunk->setBlock(block, i, j, k);
int index = Chunk::coord3DTo1D(i, j, k);
int min = index > block_prev_start ? block_prev_start : index, max = index > block_prev_start ? index : block_prev_start;
if (block != block_prev)
{
chunk->setBlocks(block_prev_start, index, block_prev);
block_prev_start = index;
}
block_prev = block;
}
}
}
chunk->setBlocks(block_prev_start, CHUNK_VOLUME, block_prev);
}
void generatePyramid(Chunk::Chunk *chunk)