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 setState(uint8_t nstate, bool value);
void setBlock(Block b, int x, int y, int z); 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); Block getBlock(int x, int y, int z);
IntervalMap<Block>& getBlocks() { return (this->blocks); } IntervalMap<Block>& getBlocks() { return (this->blocks); }
Block* getBlocksArray(int* len) { return (this->blocks.toArray(len)); } Block* getBlocksArray(int* len) { return (this->blocks.toArray(len)); }

View File

@ -37,6 +37,10 @@ namespace Chunk
int coord = coord3DTo1D(x, y, z); int coord = coord3DTo1D(x, y, z);
blocks.insert(coord <= 0 ? 0 : coord, coord+1 >= CHUNK_VOLUME ? CHUNK_VOLUME : coord+1, b); 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) void Chunk::setState(uint8_t nstate, bool value)
{ {

View File

@ -40,9 +40,15 @@ void generateNoise(Chunk::Chunk *chunk)
dirtNoiseLUT[i] = -1; dirtNoiseLUT[i] = -1;
} }
for (int i = 0; i < CHUNK_SIZE; i++) Block block_prev{Block::AIR};
for (int k = 0; k < CHUNK_SIZE; k++) int block_prev_start{0};
for (int j = 0; j < CHUNK_SIZE; j++)
// 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 x = i + CHUNK_SIZE * chunk->getPosition().x;
int y = j + CHUNK_SIZE * chunk->getPosition().y; int y = j + CHUNK_SIZE * chunk->getPosition().y;
@ -58,8 +64,6 @@ void generateNoise(Chunk::Chunk *chunk)
int dirtNoise = dirtNoiseLUT[d2]; int dirtNoise = dirtNoiseLUT[d2];
int stoneLevel = grassNoise - dirtNoise; int stoneLevel = grassNoise - dirtNoise;
// std::cout << grassNoise << " " << dirtNoise << " " << stoneLevel << std::endl;
if (y < stoneLevel) if (y < stoneLevel)
block = Block::STONE; block = Block::STONE;
else if (y >= stoneLevel && y < grassNoise) else if (y >= stoneLevel && y < grassNoise)
@ -69,8 +73,20 @@ void generateNoise(Chunk::Chunk *chunk)
else else
block = Block::AIR; 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) void generatePyramid(Chunk::Chunk *chunk)