]> git.localhorst.tv Git - blank.git/blobdiff - src/world/chunk.cpp
special treatment for players
[blank.git] / src / world / chunk.cpp
index c4ce097922ec1065d5c150d7f7e51b81d7cbbcb7..11c9d36bdaedee1682725db27c31d3341b89b305 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "Generator.hpp"
 #include "WorldCollision.hpp"
-#include "WorldSave.hpp"
+#include "../io/WorldSave.hpp"
 
 #include <algorithm>
 #include <limits>
@@ -25,7 +25,6 @@ Chunk::Chunk(const BlockTypeRegistry &types) noexcept
 , neighbor{0}
 , blocks{}
 , light{0}
-, model()
 , position(0, 0, 0)
 , dirty_model(false)
 , dirty_save(false) {
@@ -34,7 +33,6 @@ Chunk::Chunk(const BlockTypeRegistry &types) noexcept
 
 Chunk::Chunk(Chunk &&other) noexcept
 : types(other.types)
-, model(std::move(other.model))
 , position(other.position)
 , dirty_model(other.dirty_model)
 , dirty_save(other.dirty_save) {
@@ -48,7 +46,6 @@ Chunk &Chunk::operator =(Chunk &&other) noexcept {
        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_model = other.dirty_save;
        dirty_save = other.dirty_save;
@@ -429,24 +426,15 @@ bool Chunk::IsSurface(const Pos &pos) const noexcept {
 }
 
 
-void Chunk::Draw() noexcept {
-       if (ShouldUpdateModel()) {
-               Update();
-       }
-       model.Draw();
-}
-
-
 bool Chunk::Intersection(
        const Ray &ray,
        const glm::mat4 &M,
-       int &blkid,
-       float &dist,
-       glm::vec3 &normal
-) const noexcept {
+       WorldCollision &coll
+) noexcept {
        int idx = 0;
-       blkid = -1;
-       dist = std::numeric_limits<float>::infinity();
+       coll.chunk = this;
+       coll.block = -1;
+       coll.depth = std::numeric_limits<float>::infinity();
        for (int z = 0; z < depth; ++z) {
                for (int y = 0; y < height; ++y) {
                        for (int x = 0; x < width; ++x, ++idx) {
@@ -457,20 +445,20 @@ bool Chunk::Intersection(
                                float cur_dist;
                                glm::vec3 cur_norm;
                                if (type.shape->Intersects(ray, M * ToTransform(Pos(x, y, z), idx), cur_dist, cur_norm)) {
-                                       if (cur_dist < dist) {
-                                               blkid = idx;
-                                               dist = cur_dist;
-                                               normal = cur_norm;
+                                       if (cur_dist < coll.depth) {
+                                               coll.block = idx;
+                                               coll.depth = cur_dist;
+                                               coll.normal = cur_norm;
                                        }
                                }
                        }
                }
        }
 
-       if (blkid < 0) {
+       if (coll.block < 0) {
                return false;
        } else {
-               normal = glm::vec3(BlockAt(blkid).Transform() * glm::vec4(normal, 0.0f));
+               coll.normal = glm::vec3(BlockAt(coll.block).Transform() * glm::vec4(coll.normal, 0.0f));
                return true;
        }
 }
@@ -480,7 +468,7 @@ bool Chunk::Intersection(
        const glm::mat4 &Mbox,
        const glm::mat4 &Mchunk,
        std::vector<WorldCollision> &col
-) const noexcept {
+) noexcept {
        bool any = false;
        float penetration;
        glm::vec3 normal;
@@ -512,13 +500,7 @@ BlockModel::Buffer buf;
 
 }
 
-void Chunk::CheckUpdate() noexcept {
-       if (ShouldUpdateModel()) {
-               Update();
-       }
-}
-
-void Chunk::Update() noexcept {
+void Chunk::Update(BlockModel &model) noexcept {
        int vtx_count = 0, idx_count = 0;
        for (const auto &block : blocks) {
                const Shape *shape = Type(block).shape;
@@ -772,6 +754,10 @@ std::list<Chunk>::iterator ChunkLoader::Remove(std::list<Chunk>::iterator chunk)
        ++next;
        // unlink neighbors so they won't reference a dead chunk
        chunk->ClearNeighbors();
+       // if it should be saved, do it now
+       if (chunk->ShouldUpdateSave()) {
+               save.Write(*chunk);
+       }
        // and move it from loaded to free list
        to_free.splice(to_free.end(), loaded, chunk);
        return next;
@@ -854,11 +840,23 @@ void ChunkLoader::QueueSurrounding(const Chunk::Pos &pos) {
 }
 
 void ChunkLoader::Update(int dt) {
-       // check if a chunk generation is scheduled for this frame
-       // and if there's a chunk waiting to be generated
+       // check if a chunk load is scheduled for this frame
+       // and if there's chunks waiting to be loaded
        gen_timer.Update(dt);
        if (gen_timer.Hit()) {
-               LoadOne();
+               // we may
+               // load until one of load or generation limits was hit
+               constexpr int max_load = 10;
+               constexpr int max_gen = 1;
+               int loaded = 0;
+               int generated = 0;
+               while (!to_load.empty() && loaded < max_load && generated < max_gen) {
+                       if (LoadOne()) {
+                               ++generated;
+                       } else {
+                               ++loaded;
+                       }
+               }
        }
 
        constexpr int max_save = 10;
@@ -881,8 +879,8 @@ void ChunkLoader::LoadN(std::size_t n) {
        }
 }
 
-void ChunkLoader::LoadOne() {
-       if (to_load.empty()) return;
+bool ChunkLoader::LoadOne() {
+       if (to_load.empty()) return false;
 
        // take position of next chunk in queue
        Chunk::Pos pos(to_load.front());
@@ -893,7 +891,7 @@ void ChunkLoader::LoadOne() {
                if (iter->Position() == pos) {
                        loaded.splice(loaded.end(), to_free, iter);
                        Insert(loaded.back());
-                       return;
+                       return false;
                }
        }
 
@@ -906,14 +904,17 @@ void ChunkLoader::LoadOne() {
                loaded.splice(loaded.end(), to_free, to_free.begin());
        }
 
+       bool generated = false;
        Chunk &chunk = loaded.back();
        chunk.Position(pos);
        if (save.Exists(pos)) {
                save.Read(chunk);
        } else {
                gen(chunk);
+               generated = true;
        }
        Insert(chunk);
+       return generated;
 }
 
 }