From f417749fb09718cde2faad77e8430cf175c68374 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 17 Aug 2015 11:23:27 +0200 Subject: [PATCH] fix some inline TODOs --- src/ai/Spawner.cpp | 17 ++++++++++------- src/io/WorldSave.cpp | 4 ---- src/io/token.cpp | 6 +++--- src/model/geometry.hpp | 13 +++++++++++++ src/model/shape.cpp | 31 ++++++++++++++++++++++++++----- src/world/World.cpp | 7 +++++-- 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/ai/Spawner.cpp b/src/ai/Spawner.cpp index e5bc68f..fd449c9 100644 --- a/src/ai/Spawner.cpp +++ b/src/ai/Spawner.cpp @@ -2,6 +2,7 @@ #include "Chaser.hpp" #include "RandomWalk.hpp" +#include "../world/BlockLookup.hpp" #include "../world/BlockType.hpp" #include "../world/BlockTypeRegistry.hpp" #include "../world/Entity.hpp" @@ -13,7 +14,7 @@ namespace blank { Spawner::Spawner(World &world) : world(world) , controllers() -, timer(8096) +, timer(64) , despawn_range(128 * 128) , spawn_distance(16 * 16) , max_entities(16) @@ -86,12 +87,14 @@ void Spawner::TrySpawn() { return; } - // block check - // TODO: avoid force load, abort spawn if chunk unavailble - Chunk &tgt_chunk = world.Next(world.PlayerChunk(), chunk); - // TODO: don't use visibility for spawn check - // also, check for more than one block space - if (tgt_chunk.Type(tgt_chunk.BlockAt(pos)).visible) { + // check if the spawn block and the one above it are loaded and inhabitable + BlockLookup spawn_block(&world.PlayerChunk(), chunk * Chunk::Extent() + pos); + if (!spawn_block || spawn_block.GetType().collide_block) { + return; + } + + BlockLookup head_block(spawn_block.Next(Block::FACE_UP)); + if (!head_block || head_block.GetType().collide_block) { return; } diff --git a/src/io/WorldSave.cpp b/src/io/WorldSave.cpp index d90bce1..a08d69c 100644 --- a/src/io/WorldSave.cpp +++ b/src/io/WorldSave.cpp @@ -30,8 +30,6 @@ bool WorldSave::Exists() const noexcept { void WorldSave::Read(World::Config &conf) const { - cout << "reading world save" << endl; - ifstream in(conf_path); if (!in) { throw runtime_error("failed to open world config"); @@ -71,8 +69,6 @@ void WorldSave::Read(World::Config &conf) const { } void WorldSave::Write(const World::Config &conf) const { - cout << "writing world save" << endl; - if (!make_dirs(root_path)) { throw runtime_error("failed to create world save directory"); } diff --git a/src/io/token.cpp b/src/io/token.cpp index db5c986..76a9c2f 100644 --- a/src/io/token.cpp +++ b/src/io/token.cpp @@ -32,7 +32,7 @@ void Tokenizer::ReadToken() { istream::sentry s(in); if (!s) { - // TODO: error? + throw runtime_error("read past the end of stream"); return; } @@ -47,7 +47,7 @@ void Tokenizer::ReadToken() { case ',': case '=': current.type = Token::Type(c); break; - case '+': case '-': + case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': in.putback(c); @@ -71,7 +71,7 @@ void Tokenizer::ReadToken() { namespace { bool is_num_char(istream::char_type c) { - return isdigit(c) + return isxdigit(c) || c == '.' || c == '-' || c == '+' diff --git a/src/model/geometry.hpp b/src/model/geometry.hpp index f1b3762..f9f87c4 100644 --- a/src/model/geometry.hpp +++ b/src/model/geometry.hpp @@ -25,6 +25,19 @@ constexpr float rad2deg(float r) { } +template +T manhattan_distance(const glm::tvec3 &a, const glm::tvec3 &b) { + glm::tvec3 diff(abs(a - b)); + return diff.x + diff.y + diff.z; +} + +template +T manhattan_radius(const glm::tvec3 &v) { + glm::tvec3 a(abs(v)); + return std::max(a.x, std::max(a.y, a.z)); +} + + struct AABB { glm::vec3 min; glm::vec3 max; diff --git a/src/model/shape.cpp b/src/model/shape.cpp index aeea644..c2d8261 100644 --- a/src/model/shape.cpp +++ b/src/model/shape.cpp @@ -403,8 +403,6 @@ StairShape::StairShape(const AABB &bb, const glm::vec2 &clip) 8, 9, 9, 11, 11, 10, 10 , 8, // top 0, 8, 4, 10, 2, 6, // verticals, btf 1, 9, 5, 11, 3, 7, - // 5, 8, 7, 10, - // 1, 9, 3, 11, }); } @@ -448,11 +446,34 @@ bool StairShape::Intersects( const glm::mat4 &M, const AABB &box, const glm::mat4 &box_M, - float &depth, + float &dist, glm::vec3 &normal ) const noexcept { - // TODO: this is wrong, but simple. so for now will have to do - return Intersection(bot, M, box, box_M, depth, normal) || Intersection(top, M, box, box_M, depth, normal); + bool top_hit, bot_hit; + float top_dist, bot_dist; + glm::vec3 top_normal, bot_normal; + + top_hit = Intersection(bot, M, box, box_M, top_dist, top_normal); + bot_hit = Intersection(top, M, box, box_M, bot_dist, bot_normal); + + if (top_hit) { + if (bot_hit && bot_dist < top_dist) { + dist = bot_dist; + normal = bot_normal; + return true; + } else { + dist = top_dist; + normal = top_normal; + return true; + } + return true; + } else if (bot_hit) { + dist = bot_dist; + normal = bot_normal; + return true; + } else { + return false; + } } } diff --git a/src/world/World.cpp b/src/world/World.cpp index 3d3eb6c..1e372e7 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -99,9 +99,12 @@ bool World::Intersection(const Entity &e, std::vector &col) { AABB box = e.Bounds(); glm::mat4 M = e.Transform(player->ChunkCoords()); bool any = false; - // TODO: this only needs to check the chunks surrounding the entity's chunk position - // need find out if that is quicker than the rough chunk bounds test for (Chunk &cur_chunk : chunks.Loaded()) { + if (manhattan_radius(cur_chunk.Position() - e.ChunkCoords()) > 1) { + // chunk is not one of the 3x3x3 surrounding the entity + // since there's no entity which can extent over 16 blocks, they can be skipped + continue; + } if (cur_chunk.Intersection(box, M, cur_chunk.Transform(player->ChunkCoords()), col)) { any = true; } -- 2.39.2