From 22f3bad59de14b62c6680d10aff2cea5ac5b11dc Mon Sep 17 00:00:00 2001 From: Mel Date: Tue, 9 Apr 2024 03:34:50 +0200 Subject: Traverse all chunk blocks in a unified (and cache-friendly) way --- src/World/Generation/Decoration.cpp | 68 ++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 38 deletions(-) (limited to 'src/World/Generation/Decoration.cpp') diff --git a/src/World/Generation/Decoration.cpp b/src/World/Generation/Decoration.cpp index 0623c05..ecfa49b 100644 --- a/src/World/Generation/Decoration.cpp +++ b/src/World/Generation/Decoration.cpp @@ -43,35 +43,31 @@ void Decorator::draw_circle(Chunk& chunk, Pos pos, Vector<3> axis, Real radius, void TreeDecorator::decorate_chunk(Chunk& chunk) { Pos last_tree = Pos::max(); - for (UInt x = 0; x < Chunk::Width; x++) { - for (UInt z = 0; z < Chunk::Width; z++) { - for (UInt y = Chunk::Height - 1; y != 0; y--) { - Pos pos{x, y, z}; - if (!is_valid_position(pos)) - continue; - - auto& block_below = chunk.at(x, y-1, z); - if (block_below.empty()) - continue; - - auto type = block_below.type; - if (type != BlockType::Snow && type != BlockType::Grass && type != BlockType::Dirt) - break; - - auto noise = m_tree_noise.at({(Real)x, (Real)z}); - if (noise < 0.8f) - continue; - - if (last_tree.distance(pos) < s_tree_radius * 3) - continue; - - draw_tree(chunk, pos); - block_below = {BlockType::Dirt}; - last_tree = pos; - break; - } - } - } + chunk.for_each_by_column([&](Pos pos, Chunk::BlockData& block) { + auto pos_above = pos + Pos::up(); + if (!is_valid_position(pos_above)) + return Chunk::ColumnIteration::Continue; + + if (block.empty()) + return Chunk::ColumnIteration::Continue; + + auto type = block.type; + if (type != BlockType::Snow && type != BlockType::Grass && type != BlockType::Dirt) + return Chunk::ColumnIteration::SkipColumn; + + auto noise = m_tree_noise.at({TO(Real, pos.x()), TO(Real, pos.z())}); + if (noise < 0.8f) + return Chunk::ColumnIteration::Continue; + + if (last_tree.distance(pos_above) < s_tree_radius * 3) + return Chunk::ColumnIteration::Continue; + + draw_tree(chunk, pos_above); + block = {BlockType::Dirt}; + last_tree = pos_above; + + return Chunk::ColumnIteration::SkipColumn; + }); } void TreeDecorator::draw_tree(Chunk& chunk, Pos pos) const { @@ -97,15 +93,11 @@ Bool TreeDecorator::is_valid_position(Pos pos) { } void DefaultLightDecorator::decorate_chunk(Chunk& chunk) { - for (UInt x = 0; x < Chunk::Width; x++) { - for (UInt z = 0; z < Chunk::Width; z++) { - for (UInt y = Chunk::Height - 1; y != 0; y--) { - auto& block = chunk.at(x, y, z); - if (!block.type.is_translucent()) break; - chunk.at(x, y, z).light = 200; - } - } - } + chunk.for_each_by_column([&](Pos pos, Chunk::BlockData& block) { + if (!block.type.is_translucent()) return Chunk::ColumnIteration::Break; + block.light = 200; + return Chunk::ColumnIteration::Continue; + }); } } -- cgit 1.4.1