X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fchunk.cpp;h=2da66399407670eb9e1dbc3677c3764c1c6a1fd1;hb=8795094374130820e36ec4fd7e08e13b6b316fba;hp=994d68e41bf4e930d4d55df86379381685e4f4c3;hpb=e74f1ad236429f05db90c0ace825277e2a3fbc05;p=blank.git diff --git a/src/chunk.cpp b/src/chunk.cpp index 994d68e..2da6639 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -46,77 +46,6 @@ Chunk &Chunk::operator =(Chunk &&other) { } -void Chunk::SetNeighbor(Chunk &other) { - if (other.position == position + Pos(-1, 0, 0)) { - neighbor[Block::FACE_LEFT] = &other; - other.neighbor[Block::FACE_RIGHT] = this; - } else if (other.position == position + Pos(1, 0, 0)) { - neighbor[Block::FACE_RIGHT] = &other; - other.neighbor[Block::FACE_LEFT] = this; - } else if (other.position == position + Pos(0, -1, 0)) { - neighbor[Block::FACE_DOWN] = &other; - other.neighbor[Block::FACE_UP] = this; - } else if (other.position == position + Pos(0, 1, 0)) { - neighbor[Block::FACE_UP] = &other; - other.neighbor[Block::FACE_DOWN] = this; - } else if (other.position == position + Pos(0, 0, -1)) { - neighbor[Block::FACE_BACK] = &other; - other.neighbor[Block::FACE_FRONT] = this; - } else if (other.position == position + Pos(0, 0, 1)) { - neighbor[Block::FACE_FRONT] = &other; - other.neighbor[Block::FACE_BACK] = this; - } -} - -void Chunk::ClearNeighbors() { - for (int i = 0; i < Block::FACE_COUNT; ++i) { - neighbor[i] = nullptr; - } -} - -void Chunk::Unlink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = nullptr; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = nullptr; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = nullptr; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = nullptr; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = nullptr; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = nullptr; - } -} - -void Chunk::Relink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = this; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = this; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = this; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = this; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = this; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = this; - } -} - - namespace { struct SetNode { @@ -132,11 +61,11 @@ struct SetNode { 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()); } }; @@ -155,7 +84,7 @@ struct UnsetNode 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)); } @@ -227,10 +156,12 @@ void Chunk::SetBlock(int index, const Block &block) { work_light(); } else if (new_type.block_light && !old_type.block_light) { // obstacle added - dark_queue.emplace(this, ToPos(index)); - SetLight(index, 0); - work_dark(); - work_light(); + if (GetLight(index) > 0) { + dark_queue.emplace(this, ToPos(index)); + SetLight(index, 0); + work_dark(); + work_light(); + } } else if (!new_type.block_light && old_type.block_light) { // obstacle removed int level = 0; @@ -268,6 +199,166 @@ const Block *Chunk::FindNext(const Pos &pos, Block::Face face) const { } } +void Chunk::SetNeighbor(Chunk &other) { + 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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_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); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } +} + +void Chunk::ClearNeighbors() { + for (int i = 0; i < Block::FACE_COUNT; ++i) { + neighbor[i] = nullptr; + } +} + +void Chunk::Unlink() { + if (neighbor[Block::FACE_UP]) { + neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = nullptr; + } + if (neighbor[Block::FACE_DOWN]) { + neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = nullptr; + } + if (neighbor[Block::FACE_LEFT]) { + neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = nullptr; + } + if (neighbor[Block::FACE_RIGHT]) { + neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = nullptr; + } + if (neighbor[Block::FACE_FRONT]) { + neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = nullptr; + } + if (neighbor[Block::FACE_BACK]) { + neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = nullptr; + } +} + +void Chunk::Relink() { + if (neighbor[Block::FACE_UP]) { + neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = this; + } + if (neighbor[Block::FACE_DOWN]) { + neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = this; + } + if (neighbor[Block::FACE_LEFT]) { + neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = this; + } + if (neighbor[Block::FACE_RIGHT]) { + neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = this; + } + if (neighbor[Block::FACE_FRONT]) { + neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = this; + } + if (neighbor[Block::FACE_BACK]) { + neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = this; + } +} + void Chunk::SetLight(int index, int level) { if (light[index] != level) { @@ -285,19 +376,10 @@ float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Bl 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(this), pos, Block::NormalFace(norm)); + if (direct) { + float direct_light = direct.GetLight(); if (direct_light > light) { light = direct_light; } @@ -529,12 +611,13 @@ glm::mat4 Chunk::ToTransform(int idx) const { 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; } } @@ -543,6 +626,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_LEFT); pos.x += Chunk::Width(); } else { + chunk = nullptr; return; } } @@ -551,6 +635,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_UP); pos.y -= Chunk::Height(); } else { + chunk = nullptr; return; } } @@ -559,6 +644,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_DOWN); pos.y += Chunk::Height(); } else { + chunk = nullptr; return; } } @@ -567,6 +653,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_FRONT); pos.z -= Chunk::Depth(); } else { + chunk = nullptr; return; } } @@ -575,23 +662,18 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) 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); } } @@ -696,8 +778,9 @@ Chunk &ChunkLoader::Generate(const Chunk::Pos &pos) { loaded.emplace_back(reg); Chunk &chunk = loaded.back(); chunk.Position(pos); - Insert(chunk); + chunk.Allocate(); gen(chunk); + Insert(chunk); return chunk; } @@ -812,8 +895,9 @@ void ChunkLoader::Update() { } Chunk &chunk = loaded.back(); chunk.Position(pos); - Insert(chunk); + chunk.Allocate(); gen(chunk); + Insert(chunk); } to_generate.pop_front(); }