From: Daniel Karbach Date: Mon, 17 Aug 2015 15:29:38 +0000 (+0200) Subject: check for entities under crosshair X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=b0c2d423138dfb4849c679b3fb93e4336dcf5845;p=blank.git check for entities under crosshair also display aim block information in debug overlay, sorry --- diff --git a/src/ui/Interface.hpp b/src/ui/Interface.hpp index d045cc9..907f9c2 100644 --- a/src/ui/Interface.hpp +++ b/src/ui/Interface.hpp @@ -19,6 +19,7 @@ namespace blank { class Chunk; +class Entity; class Environment; class Viewport; class World; @@ -71,6 +72,7 @@ public: void UpdateCounter(); void UpdatePosition(); void UpdateOrientation(); + void UpdateBlockInfo(); void PostMessage(const char *); void PostMessage(const std::string &msg) { @@ -83,6 +85,7 @@ public: private: void CheckAim(); + void UpdateOutline(); private: Environment &env; @@ -92,6 +95,7 @@ private: Ray aim; Chunk *aim_chunk; + Entity *aim_entity; int aim_block; glm::vec3 aim_normal; @@ -101,6 +105,8 @@ private: FixedText counter_text; FixedText position_text; FixedText orientation_text; + FixedText block_text; + Block last_displayed; MessageBox messages; IntervalTimer msg_timer; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index ef005f6..c063099 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -111,6 +111,8 @@ Interface::Interface( , counter_text() , position_text() , orientation_text() +, block_text() +, last_displayed() , messages(env.assets.small_ui_font) , msg_timer(5000) , config(config) @@ -132,6 +134,10 @@ Interface::Interface( orientation_text.Position(glm::vec3(-25.0f, 25.0f + 2 * env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST); orientation_text.Foreground(glm::vec4(1.0f)); orientation_text.Background(glm::vec4(0.5f)); + block_text.Position(glm::vec3(-25.0f, 25.0f + 4 * env.assets.small_ui_font.LineSkip(), 0.0f), Gravity::NORTH_EAST); + block_text.Foreground(glm::vec4(1.0f)); + block_text.Background(glm::vec4(0.5f)); + block_text.Set(env.assets.small_ui_font, "Block: none"); messages.Position(glm::vec3(25.0f, -25.0f, 0.0f), Gravity::SOUTH_WEST); messages.Foreground(glm::vec4(1.0f)); messages.Background(glm::vec4(0.5f)); @@ -378,6 +384,7 @@ void Interface::ToggleDebug() { UpdateCounter(); UpdatePosition(); UpdateOrientation(); + UpdateBlockInfo(); } } @@ -403,6 +410,28 @@ void Interface::UpdateOrientation() { orientation_text.Set(env.assets.small_ui_font, s.str()); } +void Interface::UpdateBlockInfo() { + if (aim_chunk) { + const Block &block = aim_chunk->BlockAt(aim_block); + if (last_displayed != block) { + std::stringstream s; + s << "Block: " + << aim_chunk->Type(block).label + << ", face: " << block.GetFace() + << ", turn: " << block.GetTurn(); + block_text.Set(env.assets.small_ui_font, s.str()); + last_displayed = block; + } + } else { + if (last_displayed != Block()) { + std::stringstream s; + s << "Block: none"; + block_text.Set(env.assets.small_ui_font, s.str()); + last_displayed = Block(); + } + } +} + void Interface::Handle(const SDL_MouseMotionEvent &event) { if (config.mouse_disabled) return; @@ -547,17 +576,45 @@ OutlineModel::Buffer outl_buf; } void Interface::CheckAim() { - float dist; - if (world.Intersection(aim, glm::mat4(1.0f), aim_chunk, aim_block, dist, aim_normal)) { - outl_buf.Clear(); - aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outl_buf); - outline.Update(outl_buf); - outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); - outline_transform *= aim_chunk->ToTransform(Chunk::ToPos(aim_block), aim_block); - outline_transform *= glm::scale(glm::vec3(1.005f)); + float chunk_dist; + glm::vec3 chunk_normal; + if (world.Intersection(aim, glm::mat4(1.0f), aim_chunk, aim_block, chunk_dist, chunk_normal)) { } else { aim_chunk = nullptr; } + float entity_dist; + glm::vec3 entity_normal; + if (!world.Intersection(aim, glm::mat4(1.0f), aim_entity, entity_dist, entity_normal)) { + aim_entity = nullptr; + } + if (aim_chunk && aim_entity) { + // got both, pick the closest one + if (chunk_dist < entity_dist) { + aim_normal = chunk_normal; + UpdateOutline(); + aim_entity = nullptr; + } else { + aim_normal = entity_normal; + aim_chunk = nullptr; + } + } else if (aim_chunk) { + aim_normal = chunk_normal; + UpdateOutline(); + } else if (aim_entity) { + aim_normal = entity_normal; + } + if (debug) { + UpdateBlockInfo(); + } +} + +void Interface::UpdateOutline() { + outl_buf.Clear(); + aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outl_buf); + outline.Update(outl_buf); + outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); + outline_transform *= aim_chunk->ToTransform(Chunk::ToPos(aim_block), aim_block); + outline_transform *= glm::scale(glm::vec3(1.005f)); } @@ -574,6 +631,7 @@ void Interface::Render(Viewport &viewport) noexcept { counter_text.Render(viewport); position_text.Render(viewport); orientation_text.Render(viewport); + block_text.Render(viewport); } if (msg_timer.Running()) { diff --git a/src/world/Block.hpp b/src/world/Block.hpp index 274e3d3..5f52d17 100644 --- a/src/world/Block.hpp +++ b/src/world/Block.hpp @@ -131,7 +131,13 @@ private: }; -bool operator ==(const Block &, const Block &); +inline bool operator ==(const Block &a, const Block &b) { + return a.type == b.type && a.orient == b.orient; +} + +inline bool operator !=(const Block &a, const Block &b) { + return !(a == b); +} std::ostream &operator <<(std::ostream &, const Block &); std::ostream &operator <<(std::ostream &, const Block::Face &); diff --git a/src/world/World.cpp b/src/world/World.cpp index 1e372e7..2c0d164 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -95,6 +95,35 @@ bool World::Intersection( return chunk; } +bool World::Intersection( + const Ray &ray, + const glm::mat4 &M, + Entity *&entity, + float &dist, + glm::vec3 &normal +) { + entity = nullptr; + dist = std::numeric_limits::infinity(); + for (Entity &cur_entity : entities) { + // TODO: better check for skipping self (because the check might not be for the player) + if (&cur_entity == player) { + continue; + } + float cur_dist; + glm::vec3 cur_normal; + if (blank::Intersection(ray, cur_entity.Bounds(), M * cur_entity.Transform(player->ChunkCoords()), &cur_dist, &cur_normal)) { + // TODO: fine grained check goes here? maybe? + if (cur_dist < dist) { + entity = &cur_entity; + dist = cur_dist; + normal = cur_normal; + } + } + } + + return entity; +} + bool World::Intersection(const Entity &e, std::vector &col) { AABB box = e.Bounds(); glm::mat4 M = e.Transform(player->ChunkCoords()); diff --git a/src/world/World.hpp b/src/world/World.hpp index 2fd312c..6d27d12 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -38,6 +38,7 @@ public: World(const Assets &, const Config &, const WorldSave &); + // check if this ray hits a block bool Intersection( const Ray &, const glm::mat4 &M, @@ -46,6 +47,14 @@ public: float &dist, glm::vec3 &normal); + // check if this ray hits an entity + bool Intersection( + const Ray &, + const glm::mat4 &M, + Entity *&entity, + float &dist, + glm::vec3 &normal); + bool Intersection(const Entity &e, std::vector &); void Resolve(Entity &e, std::vector &); diff --git a/src/world/block.cpp b/src/world/block.cpp index aa91e79..54ceba0 100644 --- a/src/world/block.cpp +++ b/src/world/block.cpp @@ -14,10 +14,6 @@ namespace blank { const NullShape BlockType::DEFAULT_SHAPE; -bool operator ==(const Block &a, const Block &b) { - return a.type == b.type && a.orient == b.orient; -} - std::ostream &operator <<(std::ostream &out, const Block &block) { return out << "Block(" << block.type << ", " << block.GetFace() << ", " << block.GetTurn() << ')'; }