#include "ChunkNeighbors.hpp" namespace MC::World::Generation { ChunkNeighbors find_chunk_neighbors(ChunkIndex chunk, ChunkRegistry& chunks) { UInt neighbor_index = 0; std::array neighbors{}; for (I32 x = -1; x <= 1; x++) { for (I32 y = -1; y <= 1; y++) { if (x == 0 && y == 0) continue; auto& neighbor_data = chunks.get({chunk.x + x, chunk.y + y}); if (neighbor_data.chunk.has_value()) neighbors[neighbor_index++] = &neighbor_data.chunk.value(); } } // Layout of neighboring chunks in `neighbors` array: // (-1; -1) > (-1; 0) > (-1; 1) > (0; -1) // ( 0; 1) > ( 1; -1) > ( 1; 0) > (1; 1) return { neighbors[3], neighbors[6], neighbors[4], neighbors[1], neighbors[5], neighbors[7], neighbors[2], neighbors[0], }; } GetBlockWrappingResult get_block_wrapping(const Chunk& chunk, const ChunkNeighbors& neighbors, Vector<3, I32> pos) { const Chunk* chunk_to_ask; auto overflow = [](I32& c, I32 max) -> I8 { if (c < 0) { c += max; return -1; } if (c >= max) { c -= max; return 1; } return 0; }; auto xo = overflow(pos.x(), Chunk::Width); auto yo = overflow(pos.y(), Chunk::Height); auto zo = overflow(pos.z(), Chunk::Width); // Blocks above and below a chunk are always Air. if (yo != 0) return {}; if (xo == 1 && zo == 1) { chunk_to_ask = neighbors.south_east; } else if (xo == 1 && zo == -1) { chunk_to_ask = neighbors.north_east; } else if (xo == -1 && zo == 1) { chunk_to_ask = neighbors.south_west; } else if (xo == -1 && zo == -1) { chunk_to_ask = neighbors.north_west; } else if (xo == 1) { chunk_to_ask = neighbors.east; } else if (xo == -1) { chunk_to_ask = neighbors.west; } else if (zo == 1) { chunk_to_ask = neighbors.south; } else if (zo == -1) { chunk_to_ask = neighbors.north; } else { chunk_to_ask = &chunk; } if (!chunk_to_ask) return {false}; return {true, chunk_to_ask->at(pos.x(), pos.y(), pos.z())}; } }