1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
#include "ChunkNeighbors.hpp"
namespace MC::World::Generation {
ChunkNeighbors find_chunk_neighbors(ChunkIndex chunk, ChunkRegistry& chunks) {
UInt neighbor_index = 0;
std::array<Chunk*, 8> 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())};
}
}
|