From: Daniel Karbach Date: Mon, 9 Mar 2015 18:53:06 +0000 (+0100) Subject: limit chunks allocated/freed per frame X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=1a7bbd64b1fef1f4e2f9303f820d6f3ce76cebf1;p=blank.git limit chunks allocated/freed per frame --- diff --git a/src/app.cpp b/src/app.cpp index 0d7e7db..10a72b8 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -145,7 +145,7 @@ void Application::Update(int dt) { glm::vec3 next_pos = Chunk::ToCoords(blkid) + normal; if (!Chunk::InBounds(next_pos)) { mod_chunk = &world.Next(*chunk, normal); - next_pos -= normal * Chunk::Extent(); + next_pos -= normal * glm::vec3(Chunk::Extent()); } mod_chunk->BlockAt(next_pos).type = world.BlockTypes()[place_id]; mod_chunk->Invalidate(); diff --git a/src/chunk.cpp b/src/chunk.cpp index 514431c..483a4e5 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -7,8 +7,9 @@ namespace blank { Chunk::Chunk() -: blocks(Size()) +: blocks() , model() +, position(0, 0, 0) , dirty(false) { } @@ -28,6 +29,11 @@ Chunk &Chunk::operator =(Chunk &&other) { } +void Chunk::Allocate() { + blocks.resize(Size()); +} + + void Chunk::Draw() { if (dirty) { Update(); @@ -93,11 +99,11 @@ bool Chunk::Intersection( return true; } -void Chunk::Position(const glm::vec3 &pos) { +void Chunk::Position(const glm::tvec3 &pos) { position = pos; } -glm::mat4 Chunk::Transform(const glm::vec3 &offset) const { +glm::mat4 Chunk::Transform(const glm::tvec3 &offset) const { return glm::translate((position - offset) * Extent()); } diff --git a/src/chunk.hpp b/src/chunk.hpp index b625a17..d89fefc 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -23,10 +23,10 @@ public: static constexpr int Width() { return 16; } static constexpr int Height() { return 16; } static constexpr int Depth() { return 16; } - static glm::vec3 Extent() { return glm::vec3(Width(), Height(), Depth()); } + static glm::tvec3 Extent() { return { Width(), Height(), Depth() }; } static constexpr int Size() { return Width() * Height() * Depth(); } - static AABB Bounds() { return AABB{ { 0, 0, 0 }, { Width(), Height(), Depth() } }; } + static AABB Bounds() { return AABB{ { 0, 0, 0 }, Extent() }; } static constexpr bool InBounds(const glm::vec3 &pos) { return @@ -48,6 +48,7 @@ public: ); } + void Allocate(); void Invalidate() { dirty = true; } Block &BlockAt(int index) { return blocks[index]; } @@ -62,9 +63,9 @@ public: float *dist = nullptr, glm::vec3 *normal = nullptr) const; - void Position(const glm::vec3 &); - const glm::vec3 &Position() const { return position; } - glm::mat4 Transform(const glm::vec3 &offset) const; + void Position(const glm::tvec3 &); + const glm::tvec3 &Position() const { return position; } + glm::mat4 Transform(const glm::tvec3 &offset) const; void Draw(); @@ -75,7 +76,7 @@ private: private: std::vector blocks; Model model; - glm::vec3 position; + glm::tvec3 position; bool dirty; }; diff --git a/src/entity.cpp b/src/entity.cpp index cd2491f..c572429 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -57,7 +57,7 @@ void Entity::Rotation(const glm::mat4 &rot) { } glm::mat4 Entity::Transform(const glm::tvec3 &chunk_offset) const { - const glm::vec3 chunk_pos = glm::vec3(chunk - chunk_offset) * Chunk::Extent(); + const glm::vec3 chunk_pos = (chunk - chunk_offset) * Chunk::Extent(); return glm::translate(position + chunk_pos) * rotation; } diff --git a/src/world.cpp b/src/world.cpp index fb1023f..4d14dfd 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -16,7 +16,8 @@ World::World() , player() , player_chunk(0, 0, 0) , loaded() -, to_generate() { +, to_generate() +, to_free() { blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &blockShape }); // white block blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &stairShape }); // white stair blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &slabShape }); // white slab @@ -37,7 +38,13 @@ World::World() namespace { bool ChunkLess(const Chunk &a, const Chunk &b) { - return dot(a.Position(), a.Position()) < dot(b.Position(), b.Position()); + return + a.Position().x * a.Position().x + + a.Position().y * a.Position().y + + a.Position().z * a.Position().z < + b.Position().x * b.Position().x + + b.Position().y * b.Position().y + + b.Position().z * b.Position().z; } } @@ -64,6 +71,7 @@ void World::Generate(const glm::tvec3 &from, const glm::tvec3 &to) { } void World::Generate(Chunk &chunk) { + chunk.Allocate(); glm::vec3 pos(chunk.Position()); if (pos.x == 0 && pos.y == 0 && pos.z == 0) { for (size_t i = 1; i < blockType.Size(); ++i) { @@ -76,7 +84,7 @@ void World::Generate(Chunk &chunk) { for (int y = 0; y < Chunk::Height(); ++y) { for (int x = 0; x < Chunk::Width(); ++x) { glm::vec3 block_pos{float(x), float(y), float(z)}; - glm::vec3 gen_pos = (pos * Chunk::Extent() + block_pos) / 64.0f; + glm::vec3 gen_pos = (pos * glm::vec3(Chunk::Extent()) + block_pos) / 64.0f; float val = blockNoise(gen_pos); if (val > 0.8f) { int col_val = int((colorNoise(gen_pos) + 1.0f) * 2.0f) % 4; @@ -156,8 +164,8 @@ Chunk *World::ChunkAvailable(const glm::tvec3 &pos) { return ChunkQueued(pos); } -Chunk &World::Next(const Chunk &to, const glm::vec3 &dir) { - const glm::vec3 tgt_pos = to.Position() + dir; +Chunk &World::Next(const Chunk &to, const glm::tvec3 &dir) { + const glm::tvec3 tgt_pos = to.Position() + dir; Chunk *chunk = ChunkLoaded(tgt_pos); if (chunk) { @@ -193,7 +201,9 @@ void World::CheckChunkGeneration() { if (std::abs(player_chunk.x - iter->Position().x) > max_dist || std::abs(player_chunk.y - iter->Position().y) > max_dist || std::abs(player_chunk.z - iter->Position().z) > max_dist) { - iter = loaded.erase(iter); + auto saved = iter; + ++iter; + to_free.splice(to_free.end(), loaded, saved); } else { ++iter; } @@ -217,6 +227,10 @@ void World::CheckChunkGeneration() { Generate(to_generate.front()); loaded.splice(loaded.end(), to_generate, to_generate.begin()); } + + if (!to_free.empty()) { + to_free.pop_front(); + } } diff --git a/src/world.hpp b/src/world.hpp index 6b6aaf0..4c7a59f 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -37,7 +37,7 @@ public: Chunk *ChunkLoaded(const glm::tvec3 &); Chunk *ChunkQueued(const glm::tvec3 &); Chunk *ChunkAvailable(const glm::tvec3 &); - Chunk &Next(const Chunk &, const glm::vec3 &dir); + Chunk &Next(const Chunk &, const glm::tvec3 &dir); void Update(int dt); void CheckChunkGeneration(); @@ -61,6 +61,7 @@ private: std::list loaded; std::list to_generate; + std::list to_free; };