From 072d66419976c9ffa1c5c9eaa7259e62c4f7f7e6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 19 Jun 2020 23:14:25 +0200 Subject: [PATCH] Separate top layer search from block data retrieval --- src/MinedMap.cpp | 12 +++++----- src/World/Block.hpp | 4 ++-- src/World/Chunk.cpp | 53 ++++++++++++++++++++++++++++++--------------- src/World/Chunk.hpp | 33 +++++++++++++++++----------- 4 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index c5ad61f..f85e8e0 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -54,26 +54,26 @@ static const size_t DIM = World::Region::SIZE*World::Chunk::SIZE; static void addChunkBiome(uint8_t biomemap[DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) { World::Chunk chunk(data); - World::Chunk::Blocks layer = chunk.getTopLayer(); + World::Chunk::Heightmap layer = chunk.getTopLayer(false); for (size_t x = 0; x < World::Chunk::SIZE; x++) { for (size_t z = 0; z < World::Chunk::SIZE; z++) { size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; - const World::Block &block = layer.blocks[x][z]; - - biomemap[i] = chunk.getBiome(x, block.height, z); + const World::Chunk::Height &height = layer.v[x][z]; + biomemap[i] = chunk.getBiome(x, height.y, z); } } } static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) { World::Chunk chunk(data); - World::Chunk::Blocks layer = chunk.getTopLayer(); + World::Chunk::Heightmap layer = chunk.getTopLayer(true); for (size_t x = 0; x < World::Chunk::SIZE; x++) { for (size_t z = 0; z < World::Chunk::SIZE; z++) { size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; - const World::Block &block = layer.blocks[x][z]; + const World::Chunk::Height &height = layer.v[x][z]; + const World::Block block = chunk.getBlock(x, height, z); image[i] = block.getColor(); lightmap[2*i+1] = (1 - block.blockLight/15.f)*192; diff --git a/src/World/Block.hpp b/src/World/Block.hpp index b8f8218..8f219c2 100644 --- a/src/World/Block.hpp +++ b/src/World/Block.hpp @@ -36,7 +36,7 @@ namespace World { struct Block { const Resource::BlockType *type; - unsigned height; + unsigned depth; uint8_t blockLight; uint8_t biome; @@ -45,7 +45,7 @@ struct Block { if (!type || !(type->flags & BLOCK_OPAQUE)) return Resource::Color {}; - return (Resource::BIOMES[biome] ?: Resource::BIOME_DEFAULT)->getBlockColor(type, height); + return (Resource::BIOMES[biome] ?: Resource::BIOME_DEFAULT)->getBlockColor(type, depth); } operator bool() const { diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index d638ba8..7adb04c 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -81,41 +81,62 @@ uint8_t Chunk::getBiome(size_t x, size_t y, size_t z) const { return 0; } -bool Chunk::getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const { - if (block->height > 0) +Block Chunk::getBlock(size_t x, Chunk::Height height, size_t z) const { + Block block = {}; + + block.depth = height.depth; + block.biome = getBiome(x, height.y, z); + + size_t Y = height.y / SIZE; + size_t y = height.y % SIZE; + + if (Y < sections.size() && sections[Y]) + block.type = sections[Y]->getBlockStateAt(x, y, z); + + size_t Yt = (height.y + 1) / SIZE; + size_t yt = (height.y + 1) % SIZE; + + if (Yt < sections.size() && sections[Yt]) + block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); + + return block; +} + +bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, size_t y, size_t z, bool withDepth) const { + if (height->depth > 0) + return false; + + if (!withDepth && height->y > 0) return false; const Resource::BlockType *type = section->getBlockStateAt(x, y, z); if (!type || !(type->flags & BLOCK_OPAQUE)) return false; - if (!block->type) { - block->type = type; - block->blockLight = prev_light; - block->biome = getBiome(x, y, z); - } + if (height->y == 0) + height->y = SIZE*section->getY() + y; + + if (!withDepth) + return true; if (type->flags & BLOCK_WATER) return false; - block->height = SIZE*section->getY() + y; + height->depth = SIZE*section->getY() + y; return true; } -Chunk::Blocks Chunk::getTopLayer() const { +Chunk::Heightmap Chunk::getTopLayer(bool withDepth) const { size_t done = 0; - Blocks ret = {}; - uint8_t prev_light[SIZE][SIZE] = {}; + Heightmap ret = {}; for (ssize_t Y = sections.size() - 1; Y >= 0; Y--) { if (done == SIZE*SIZE) break; - if (!sections[Y]) { - std::memset(prev_light, 0, sizeof(prev_light)); + if (!sections[Y]) continue; - } const Section *section = sections[Y].get(); @@ -125,10 +146,8 @@ Chunk::Blocks Chunk::getTopLayer() const { for (size_t z = 0; z < SIZE; z++) { for (size_t x = 0; x < SIZE; x++) { - if (getBlock(&ret.blocks[x][z], section, x, y, z, prev_light[x][z])) + if (getHeight(&ret.v[x][z], section, x, y, z, withDepth)) done++; - - prev_light[x][z] = section->getBlockLightAt(x, y, z); } } } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 19c0d44..ccbba54 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -50,8 +50,13 @@ public: static const size_t BSIZE = SIZE / BGROUP; static const size_t BMAXY = MAXY / BGROUP; - struct Blocks { - Block blocks[SIZE][SIZE]; + struct Height { + unsigned y; + unsigned depth; + }; + + struct Heightmap { + Height v[SIZE][SIZE]; }; private: @@ -62,16 +67,7 @@ private: std::shared_ptr biomeIntsPre115; std::shared_ptr biomeInts; - bool getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const; - -public: - Chunk(const ChunkData *data); - - const NBT::CompoundTag & getLevel() const { - return *level; - } - - uint8_t getBiome(size_t x, size_t y, size_t z) const; + bool getHeight(Height *height, const Section *section, size_t x, size_t y, size_t z, bool withDepth) const; const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const { size_t Y = y / SIZE; @@ -82,7 +78,18 @@ public: return sections[Y]->getBlockStateAt(x, y % SIZE, z); } - Blocks getTopLayer() const; + +public: + Chunk(const ChunkData *data); + + const NBT::CompoundTag & getLevel() const { + return *level; + } + + uint8_t getBiome(size_t x, size_t y, size_t z) const; + Block getBlock(size_t x, Height y, size_t z) const; + + Heightmap getTopLayer(bool withDepth) const; }; }