diff options
| author | Mel <einebeere@gmail.com> | 2024-04-09 03:34:50 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2024-04-09 03:34:50 +0200 |
| commit | 22f3bad59de14b62c6680d10aff2cea5ac5b11dc (patch) | |
| tree | 038add33df7ead1759bdd2ca9e2087fd55b1512f /src/World/Chunk.hpp | |
| parent | 2ab9e650f814d47e78fc95500605b4561922893d (diff) | |
| download | meowcraft-22f3bad59de14b62c6680d10aff2cea5ac5b11dc.tar.zst meowcraft-22f3bad59de14b62c6680d10aff2cea5ac5b11dc.zip | |
Traverse all chunk blocks in a unified (and cache-friendly) way
Diffstat (limited to 'src/World/Chunk.hpp')
| -rw-r--r-- | src/World/Chunk.hpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index bab20f2..e958b9a 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -7,6 +7,7 @@ #include "BlockType.hpp" #include "ChunkIndex.hpp" #include "Position.hpp" +#include "../Common/Iteration.hpp" #include "../GFX/Mesh.hpp" namespace MC::World { @@ -16,6 +17,8 @@ public: static constexpr U32 Width = ChunkDimensions::Width; static constexpr U32 Height = ChunkDimensions::Height; + static constexpr U32 BlockCount = Width * Height * Width; + Chunk(I64 x, I64 y) : m_blocks{Width * Height * Width, {BlockType::Air}}, m_index(x, y), @@ -48,16 +51,32 @@ public: void set_details(const Details& details) { m_details = details; } Details& details(){ return m_details; } + // Cache-friendly iteration through all blocks in the chunk. template <typename F> void for_each(F f) { + for (U32 i = 0; i < BlockCount; ++i) { + Iteration control = f(pos(i), m_blocks[i]); + if (control == Iteration::Break) break; + } + } + + // Iteration through all blocks in the chunk by column. + // Starts from the top of the chunk and goes down. + enum class ColumnIteration { Continue, Break, SkipColumn }; + template <typename F> + void for_each_by_column(F f) { + // TODO: Maybe add a way to lookup the highest block in a column + // to skip all the air? for (U32 x = 0; x < Width; ++x) { - for (U32 y = 0; y < Height; ++y) { - for (U32 z = 0; z < Width; ++z) { - Position::BlockLocal pos{x, y, z}; - f(pos, at(x, y, z)); + for (U32 z = 0; z < Width; ++z) { + for (UInt y = Height - 1; y != 0; y--) { + ColumnIteration control = f({x, y, z}, m_blocks.at(pos(x, y, z))); + if (control == ColumnIteration::Break) goto end; + if (control == ColumnIteration::SkipColumn) break; } } } + end: return; } ChunkIndex index() const; @@ -70,7 +89,10 @@ public: static AABB block_bounds(Position::BlockLocal pos); static AABB block_bounds(Position::BlockWorld pos); private: + // Convert a local position to a chunk block index. static U64 pos(U32 x, U32 y, U32 z); + // Convert a chunk block index to a local position. + static Position::BlockLocal pos(U64 i); ChunkIndex m_index; Vector<3> m_position; |
