From bea14b67ae4e5705965f3cc6422410a25f38ef9e Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 8 Mar 2015 22:29:00 +0100 Subject: [PATCH] limit number of chunks generated per frame --- src/app.cpp | 2 +- src/camera.cpp | 2 +- src/world.cpp | 57 +++++++++++++++++++++++++++++++++++++------------- src/world.hpp | 9 ++++---- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 21eb85c..539858f 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -34,7 +34,7 @@ Application::Application() glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); - world.Generate(); + world.Generate({ -4, -4, -4 }, { 5, 5, 5}); hud.Viewport(960, 600); hud.Display(*world.BlockTypes()[place_id]); diff --git a/src/camera.cpp b/src/camera.cpp index 8f61867..eeb4dce 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -10,7 +10,7 @@ Camera::Camera() : fov(45.0f) , aspect(1.0f) , near_clip(0.1f) -, far_clip(100.0f) +, far_clip(256.0f) , projection(glm::perspective(fov, aspect, near_clip, far_clip)) { } diff --git a/src/world.cpp b/src/world.cpp index 7a498c3..cca483d 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -166,7 +166,8 @@ World::World() , slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}) , blockNoise(0) , colorNoise(1) -, chunks() { +, loaded() +, to_generate() { 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 @@ -184,20 +185,35 @@ World::World() } -void World::Generate() { - for (int z = -2; z < 3; ++z) { - for (int y = -2; y < 3; ++y) { - for (int x = -2; x < 3; ++x) { - Generate(glm::vec3(x, y, z)); +namespace { + +bool ChunkLess(const Chunk &a, const Chunk &b) { + return dot(a.Position(), a.Position()) < dot(b.Position(), b.Position()); +} + +} + +void World::Generate(const glm::tvec3 &from, const glm::tvec3 &to) { + for (int z = from.z; z < to.z; ++z) { + for (int y = from.y; y < to.y; ++y) { + for (int x = from.x; x < to.x; ++x) { + glm::vec3 pos{float(x), float(y), float(z)}; + if (x == 0 && y == 0 && z == 0) { + loaded.emplace_back(); + loaded.back().Position(pos); + Generate(loaded.back()); + } else { + to_generate.emplace_back(); + to_generate.back().Position(pos); + } } } } + to_generate.sort(ChunkLess); } -Chunk &World::Generate(const glm::vec3 &pos) { - chunks.emplace_back(); - Chunk &chunk = chunks.back(); - chunk.Position(pos); +void World::Generate(Chunk &chunk) { + glm::vec3 pos(chunk.Position()); if (pos.x == 0 && pos.y == 0 && pos.z == 0) { for (size_t i = 1; i < blockType.Size(); ++i) { chunk.BlockAt(i) = Block(blockType[i]); @@ -220,7 +236,6 @@ Chunk &World::Generate(const glm::vec3 &pos) { } } chunk.Invalidate(); - return chunk; } bool World::Intersection( @@ -235,7 +250,7 @@ bool World::Intersection( float closest_dist = std::numeric_limits::infinity(); glm::vec3 closest_normal; - for (Chunk &cur_chunk : chunks) { + for (Chunk &cur_chunk : loaded) { int cur_blkid; float cur_dist; glm::vec3 cur_normal; @@ -267,17 +282,31 @@ bool World::Intersection( Chunk &World::Next(const Chunk &to, const glm::vec3 &dir) { const glm::vec3 tgt_pos = to.Position() + dir; - for (Chunk &chunk : chunks) { + for (Chunk &chunk : LoadedChunks()) { if (chunk.Position() == tgt_pos) { return chunk; } } - return Generate(tgt_pos); + for (Chunk &chunk : to_generate) { + if (chunk.Position() == tgt_pos) { + Generate(chunk); + return chunk; + } + } + loaded.emplace_back(); + loaded.back().Position(tgt_pos); + Generate(loaded.back()); + return loaded.back(); } void World::Update(int dt) { player.Update(dt); + + if (!to_generate.empty()) { + Generate(to_generate.front()); + loaded.splice(loaded.end(), to_generate, to_generate.begin()); + } } diff --git a/src/world.hpp b/src/world.hpp index 8ca03a2..6f63915 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -168,7 +168,7 @@ class World { public: World(); - void Generate(); + void Generate(const glm::tvec3 &from, const glm::tvec3 &to); bool Intersection( const Ray &, @@ -179,7 +179,7 @@ public: glm::vec3 *normal = nullptr); BlockTypeRegistry &BlockTypes() { return blockType; } - std::list &LoadedChunks() { return chunks; } + std::list &LoadedChunks() { return loaded; } FPSController &Controller() { return player; } @@ -190,7 +190,7 @@ public: void Render(DirectionalLighting &); private: - Chunk &Generate(const glm::vec3 &); + void Generate(Chunk &); private: BlockTypeRegistry blockType; @@ -203,7 +203,8 @@ private: FPSController player; - std::list chunks; + std::list loaded; + std::list to_generate; }; -- 2.39.2