-namespace {
-
-// propagate light from a's edge to b
-void edge_light(
- Chunk &a, const Chunk::Pos &a_pos,
- Chunk &b, const Chunk::Pos &b_pos
-) noexcept {
- if (a.GetLight(a_pos) > 1) {
- const BlockType &b_type = b.Type(Chunk::ToIndex(b_pos));
- if (!b_type.block_light) {
- light_queue.emplace(&a, a_pos);
- }
- if (b_type.visible) {
- b.Invalidate();
- }
- }
-}
-
-}
-
-void Chunk::SetNeighbor(Chunk &other) noexcept {
- if (other.position == position + Pos(-1, 0, 0)) {
- if (neighbor[Block::FACE_LEFT] != &other) {
- neighbor[Block::FACE_LEFT] = &other;
- other.neighbor[Block::FACE_RIGHT] = this;
- for (int z = 0; z < depth; ++z) {
- for (int y = 0; y < height; ++y) {
- Pos my_pos(0, y, z);
- Pos other_pos(width - 1, y, z);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);
- }
- }
- work_light();
- }
- } else if (other.position == position + Pos(1, 0, 0)) {
- if (neighbor[Block::FACE_RIGHT] != &other) {
- neighbor[Block::FACE_RIGHT] = &other;
- other.neighbor[Block::FACE_LEFT] = this;
- for (int z = 0; z < depth; ++z) {
- for (int y = 0; y < height; ++y) {
- Pos my_pos(width - 1, y, z);
- Pos other_pos(0, y, z);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);
- }
- }
- work_light();
- }
- } else if (other.position == position + Pos(0, -1, 0)) {
- if (neighbor[Block::FACE_DOWN] != &other) {
- neighbor[Block::FACE_DOWN] = &other;
- other.neighbor[Block::FACE_UP] = this;
- for (int z = 0; z < depth; ++z) {
- for (int x = 0; x < width; ++x) {
- Pos my_pos(x, 0, z);
- Pos other_pos(x, height - 1, z);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);
- }
- }
- work_light();
- }
- } else if (other.position == position + Pos(0, 1, 0)) {
- if (neighbor[Block::FACE_UP] != &other) {
- neighbor[Block::FACE_UP] = &other;
- other.neighbor[Block::FACE_DOWN] = this;
- for (int z = 0; z < depth; ++z) {
- for (int x = 0; x < width; ++x) {
- Pos my_pos(x, height - 1, z);
- Pos other_pos(x, 0, z);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);
- }
- }
- work_light();
- }
- } else if (other.position == position + Pos(0, 0, -1)) {
- if (neighbor[Block::FACE_BACK] != &other) {
- neighbor[Block::FACE_BACK] = &other;
- other.neighbor[Block::FACE_FRONT] = this;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- Pos my_pos(x, y, 0);
- Pos other_pos(x, y, depth - 1);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);
- }
- }
- work_light();
- }
- } else if (other.position == position + Pos(0, 0, 1)) {
- if (neighbor[Block::FACE_FRONT] != &other) {
- neighbor[Block::FACE_FRONT] = &other;
- other.neighbor[Block::FACE_BACK] = this;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- Pos my_pos(x, y, depth - 1);
- Pos other_pos(x, y, 0);
- edge_light(*this, my_pos, other, other_pos);
- edge_light(other, other_pos, *this, my_pos);