mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 17:44:52 +01:00
Separate top layer search from block data retrieval
This commit is contained in:
parent
569d0f1198
commit
072d664199
4 changed files with 64 additions and 38 deletions
|
@ -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) {
|
static void addChunkBiome(uint8_t biomemap[DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) {
|
||||||
World::Chunk chunk(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 x = 0; x < World::Chunk::SIZE; x++) {
|
||||||
for (size_t z = 0; z < World::Chunk::SIZE; z++) {
|
for (size_t z = 0; z < World::Chunk::SIZE; z++) {
|
||||||
size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x;
|
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];
|
||||||
|
biomemap[i] = chunk.getBiome(x, height.y, z);
|
||||||
biomemap[i] = chunk.getBiome(x, block.height, 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) {
|
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 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 x = 0; x < World::Chunk::SIZE; x++) {
|
||||||
for (size_t z = 0; z < World::Chunk::SIZE; z++) {
|
for (size_t z = 0; z < World::Chunk::SIZE; z++) {
|
||||||
size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x;
|
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();
|
image[i] = block.getColor();
|
||||||
lightmap[2*i+1] = (1 - block.blockLight/15.f)*192;
|
lightmap[2*i+1] = (1 - block.blockLight/15.f)*192;
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace World {
|
||||||
|
|
||||||
struct Block {
|
struct Block {
|
||||||
const Resource::BlockType *type;
|
const Resource::BlockType *type;
|
||||||
unsigned height;
|
unsigned depth;
|
||||||
uint8_t blockLight;
|
uint8_t blockLight;
|
||||||
uint8_t biome;
|
uint8_t biome;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ struct Block {
|
||||||
if (!type || !(type->flags & BLOCK_OPAQUE))
|
if (!type || !(type->flags & BLOCK_OPAQUE))
|
||||||
return Resource::Color {};
|
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 {
|
operator bool() const {
|
||||||
|
|
|
@ -81,41 +81,62 @@ uint8_t Chunk::getBiome(size_t x, size_t y, size_t z) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Chunk::getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const {
|
Block Chunk::getBlock(size_t x, Chunk::Height height, size_t z) const {
|
||||||
if (block->height > 0)
|
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;
|
return false;
|
||||||
|
|
||||||
const Resource::BlockType *type = section->getBlockStateAt(x, y, z);
|
const Resource::BlockType *type = section->getBlockStateAt(x, y, z);
|
||||||
if (!type || !(type->flags & BLOCK_OPAQUE))
|
if (!type || !(type->flags & BLOCK_OPAQUE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!block->type) {
|
if (height->y == 0)
|
||||||
block->type = type;
|
height->y = SIZE*section->getY() + y;
|
||||||
block->blockLight = prev_light;
|
|
||||||
block->biome = getBiome(x, y, z);
|
if (!withDepth)
|
||||||
}
|
return true;
|
||||||
|
|
||||||
if (type->flags & BLOCK_WATER)
|
if (type->flags & BLOCK_WATER)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
block->height = SIZE*section->getY() + y;
|
height->depth = SIZE*section->getY() + y;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk::Blocks Chunk::getTopLayer() const {
|
Chunk::Heightmap Chunk::getTopLayer(bool withDepth) const {
|
||||||
size_t done = 0;
|
size_t done = 0;
|
||||||
Blocks ret = {};
|
Heightmap ret = {};
|
||||||
uint8_t prev_light[SIZE][SIZE] = {};
|
|
||||||
|
|
||||||
for (ssize_t Y = sections.size() - 1; Y >= 0; Y--) {
|
for (ssize_t Y = sections.size() - 1; Y >= 0; Y--) {
|
||||||
if (done == SIZE*SIZE)
|
if (done == SIZE*SIZE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!sections[Y]) {
|
if (!sections[Y])
|
||||||
std::memset(prev_light, 0, sizeof(prev_light));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
const Section *section = sections[Y].get();
|
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 z = 0; z < SIZE; z++) {
|
||||||
for (size_t x = 0; x < SIZE; x++) {
|
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++;
|
done++;
|
||||||
|
|
||||||
prev_light[x][z] = section->getBlockLightAt(x, y, z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,13 @@ public:
|
||||||
static const size_t BSIZE = SIZE / BGROUP;
|
static const size_t BSIZE = SIZE / BGROUP;
|
||||||
static const size_t BMAXY = MAXY / BGROUP;
|
static const size_t BMAXY = MAXY / BGROUP;
|
||||||
|
|
||||||
struct Blocks {
|
struct Height {
|
||||||
Block blocks[SIZE][SIZE];
|
unsigned y;
|
||||||
|
unsigned depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Heightmap {
|
||||||
|
Height v[SIZE][SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -62,16 +67,7 @@ private:
|
||||||
std::shared_ptr<const NBT::IntArrayTag> biomeIntsPre115;
|
std::shared_ptr<const NBT::IntArrayTag> biomeIntsPre115;
|
||||||
std::shared_ptr<const NBT::IntArrayTag> biomeInts;
|
std::shared_ptr<const NBT::IntArrayTag> biomeInts;
|
||||||
|
|
||||||
bool getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const;
|
bool getHeight(Height *height, const Section *section, size_t x, size_t y, size_t z, bool withDepth) 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;
|
|
||||||
|
|
||||||
const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const {
|
const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const {
|
||||||
size_t Y = y / SIZE;
|
size_t Y = y / SIZE;
|
||||||
|
@ -82,7 +78,18 @@ public:
|
||||||
return sections[Y]->getBlockStateAt(x, y % SIZE, z);
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue