bool HasNext(Block::Face face) {
const BlockLookup next(chunk, pos, face);
- return next.result && !next.chunk->Type(*next.result).block_light;
+ return next && !next.GetType().block_light;
}
SetNode GetNext(Block::Face face) {
const BlockLookup next(chunk, pos, face);
- return SetNode(next.chunk, next.pos);
+ return SetNode(&next.GetChunk(), next.GetBlockPos());
}
};
bool HasNext(Block::Face face) {
const BlockLookup next(chunk, pos, face);
- return next.result;
+ return next;
}
UnsetNode GetNext(Block::Face face) { return UnsetNode(SetNode::GetNext(face)); }
Chunk::Pos pos(ToPos(index));
Block::Face direct_face(Block::NormalFace(norm));
- const Chunk *direct_chunk = this;
- Chunk::Pos direct_pos(pos + Block::FaceNormal(direct_face));
- if (!InBounds(direct_pos)) {
- if (HasNeighbor(direct_face)) {
- direct_chunk = &GetNeighbor(direct_face);
- direct_pos -= (Block::FaceNormal(direct_face) * Extent());
- float direct_light = direct_chunk->GetLight(direct_pos);
- if (direct_light > light) {
- light = direct_light;
- }
- }
- } else {
- float direct_light = direct_chunk->GetLight(direct_pos);
+ // tis okay
+ BlockLookup direct(const_cast<Chunk *>(this), pos, Block::NormalFace(norm));
+ if (direct) {
+ float direct_light = direct.GetLight();
if (direct_light > light) {
light = direct_light;
}
BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p)
-: chunk(c), pos(p), result(nullptr) {
+: chunk(c), pos(p) {
while (pos.x >= Chunk::Width()) {
if (chunk->HasNeighbor(Block::FACE_RIGHT)) {
chunk = &chunk->GetNeighbor(Block::FACE_RIGHT);
pos.x -= Chunk::Width();
} else {
+ chunk = nullptr;
return;
}
}
chunk = &chunk->GetNeighbor(Block::FACE_LEFT);
pos.x += Chunk::Width();
} else {
+ chunk = nullptr;
return;
}
}
chunk = &chunk->GetNeighbor(Block::FACE_UP);
pos.y -= Chunk::Height();
} else {
+ chunk = nullptr;
return;
}
}
chunk = &chunk->GetNeighbor(Block::FACE_DOWN);
pos.y += Chunk::Height();
} else {
+ chunk = nullptr;
return;
}
}
chunk = &chunk->GetNeighbor(Block::FACE_FRONT);
pos.z -= Chunk::Depth();
} else {
+ chunk = nullptr;
return;
}
}
chunk = &chunk->GetNeighbor(Block::FACE_BACK);
pos.z += Chunk::Depth();
} else {
+ chunk = nullptr;
return;
}
}
- result = &chunk->BlockAt(pos);
}
BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face)
-: chunk(c), pos(p), result(nullptr) {
+: chunk(c), pos(p) {
pos += Block::FaceNormal(face);
- if (Chunk::InBounds(pos)) {
- result = &chunk->BlockAt(pos);
- } else {
+ if (!Chunk::InBounds(pos)) {
pos -= Block::FaceNormal(face) * Chunk::Extent();
- if (chunk->HasNeighbor(face)) {
- chunk = &chunk->GetNeighbor(face);
- result = &chunk->BlockAt(pos);
- }
+ chunk = &chunk->GetNeighbor(face);
}
}
};
-struct BlockLookup {
+class BlockLookup {
- Chunk *chunk;
- Chunk::Pos pos;
- const Block *result;
-
- // resolve chunk/position/block from oob coordinates
- // result will be nullptr if unsuccessful
+public:
+ // resolve chunk/position from oob coordinates
BlockLookup(Chunk *c, const Chunk::Pos &p);
- // resolve chunk/position/block from ib coordinates and direction
- // result will be nullptr if unsuccessful
+ // resolve chunk/position from ib coordinates and direction
BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir);
+ // check if lookup was successful
+ operator bool() const { return chunk; }
+
+ // only valid if lookup was successful
+ Chunk &GetChunk() const { return *chunk; }
+ const Chunk::Pos &GetBlockPos() const { return pos; }
+ const Block &GetBlock() const { return GetChunk().BlockAt(GetBlockPos()); }
+ const BlockType &GetType() const { return GetChunk().Type(GetBlock()); }
+ int GetLight() const { return GetChunk().GetLight(GetBlockPos()); }
+
+private:
+ Chunk *chunk;
+ Chunk::Pos pos;
+
};