]> git.localhorst.tv Git - blank.git/blobdiff - src/chunk.cpp
remove move branching from interface
[blank.git] / src / chunk.cpp
index 5162952347b492c8578bf28da291555a37059533..a64e184140f503d4d343b26c04207571db0c459e 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "generator.hpp"
 
+#include <algorithm>
 #include <limits>
 #include <queue>
 #include <glm/gtx/transform.hpp>
@@ -11,9 +12,9 @@ namespace blank {
 
 Chunk::Chunk(const BlockTypeRegistry &types)
 : types(&types)
-, neighbor{ 0, 0, 0, 0, 0, 0 }
-, blocks()
-, light()
+, neighbor{0}
+, blocks{}
+, light{0}
 , model()
 , position(0, 0, 0)
 , dirty(false) {
@@ -22,23 +23,19 @@ Chunk::Chunk(const BlockTypeRegistry &types)
 
 Chunk::Chunk(Chunk &&other)
 : types(other.types)
-, blocks(std::move(other.blocks))
-, light(std::move(other.light))
 , model(std::move(other.model))
 , position(other.position)
 , dirty(other.dirty) {
-       for (size_t i = 0; i < Block::FACE_COUNT; ++i) {
-               neighbor[i] = other.neighbor[i];
-       }
+       std::copy(other.neighbor, other.neighbor + sizeof(neighbor), neighbor);
+       std::copy(other.blocks, other.blocks + sizeof(blocks), blocks);
+       std::copy(other.light, other.light + sizeof(light), light);
 }
 
 Chunk &Chunk::operator =(Chunk &&other) {
        types = other.types;
-       for (size_t i = 0; i < Block::FACE_COUNT; ++i) {
-               neighbor[i] = other.neighbor[i];
-       }
-       blocks = std::move(other.blocks);
-       light = std::move(other.light);
+       std::copy(other.neighbor, other.neighbor + sizeof(neighbor), neighbor);
+       std::copy(other.blocks, other.blocks + sizeof(blocks), blocks);
+       std::copy(other.light, other.light + sizeof(light), light);
        model = std::move(other.model);
        position = other.position;
        dirty = other.dirty;
@@ -61,11 +58,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());
        }
 
 };
@@ -84,7 +81,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)); }
 
@@ -376,19 +373,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<Chunk *>(this), pos, Block::NormalFace(norm));
+       if (direct) {
+               float direct_light = direct.GetLight();
                if (direct_light > light) {
                        light = direct_light;
                }
@@ -422,12 +410,6 @@ bool Chunk::IsSurface(const Pos &pos) const {
 }
 
 
-void Chunk::Allocate() {
-       blocks.resize(Size(), Block(0));
-       light.resize(Size(), 0);
-}
-
-
 void Chunk::Draw() {
        if (dirty) {
                Update();
@@ -620,12 +602,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;
                }
        }
@@ -634,6 +617,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p)
                        chunk = &chunk->GetNeighbor(Block::FACE_LEFT);
                        pos.x += Chunk::Width();
                } else {
+                       chunk = nullptr;
                        return;
                }
        }
@@ -642,6 +626,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p)
                        chunk = &chunk->GetNeighbor(Block::FACE_UP);
                        pos.y -= Chunk::Height();
                } else {
+                       chunk = nullptr;
                        return;
                }
        }
@@ -650,6 +635,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p)
                        chunk = &chunk->GetNeighbor(Block::FACE_DOWN);
                        pos.y += Chunk::Height();
                } else {
+                       chunk = nullptr;
                        return;
                }
        }
@@ -658,6 +644,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p)
                        chunk = &chunk->GetNeighbor(Block::FACE_FRONT);
                        pos.z -= Chunk::Depth();
                } else {
+                       chunk = nullptr;
                        return;
                }
        }
@@ -666,23 +653,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);
        }
 }
 
@@ -787,7 +769,6 @@ Chunk &ChunkLoader::Generate(const Chunk::Pos &pos) {
        loaded.emplace_back(reg);
        Chunk &chunk = loaded.back();
        chunk.Position(pos);
-       chunk.Allocate();
        gen(chunk);
        Insert(chunk);
        return chunk;
@@ -881,39 +862,31 @@ void ChunkLoader::GenerateSurrounding(const Chunk::Pos &pos) {
 }
 
 void ChunkLoader::Update() {
-       bool reused = false;
-       if (!to_generate.empty()) {
-               Chunk::Pos pos(to_generate.front());
-
-               for (auto iter(to_free.begin()), end(to_free.end()); iter != end; ++iter) {
-                       if (iter->Position() == pos) {
-                               iter->Relink();
-                               loaded.splice(loaded.end(), to_free, iter);
-                               reused = true;
-                               break;
-                       }
-               }
+       if (to_generate.empty()) {
+               return;
+       }
 
-               if (!reused) {
-                       if (to_free.empty()) {
-                               loaded.emplace_back(reg);
-                       } else {
-                               to_free.front().ClearNeighbors();
-                               loaded.splice(loaded.end(), to_free, to_free.begin());
-                               reused = true;
-                       }
-                       Chunk &chunk = loaded.back();
-                       chunk.Position(pos);
-                       chunk.Allocate();
-                       gen(chunk);
-                       Insert(chunk);
+       Chunk::Pos pos(to_generate.front());
+       to_generate.pop_front();
+
+       for (auto iter(to_free.begin()), end(to_free.end()); iter != end; ++iter) {
+               if (iter->Position() == pos) {
+                       iter->Relink();
+                       loaded.splice(loaded.end(), to_free, iter);
+                       return;
                }
-               to_generate.pop_front();
        }
 
-       if (!reused && !to_free.empty()) {
-               to_free.pop_front();
+       if (to_free.empty()) {
+               loaded.emplace_back(reg);
+       } else {
+               to_free.front().ClearNeighbors();
+               loaded.splice(loaded.end(), to_free, to_free.begin());
        }
+       Chunk &chunk = loaded.back();
+       chunk.Position(pos);
+       gen(chunk);
+       Insert(chunk);
 }
 
 }