]> git.localhorst.tv Git - blank.git/commitdiff
check for entities under crosshair
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 17 Aug 2015 15:29:38 +0000 (17:29 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 17 Aug 2015 15:29:38 +0000 (17:29 +0200)
also display aim block information in debug overlay, sorry

src/ui/Interface.hpp
src/ui/ui.cpp
src/world/Block.hpp
src/world/World.cpp
src/world/World.hpp
src/world/block.cpp

index d045cc900b2e5215fea3c3dcc00eb443e7ee02fa..907f9c234a320e5434c0da1f21bd2244c397c958 100644 (file)
@@ -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;
 
index ef005f6dea778ec8f243a8087e7167c0368f59f1..c063099e9c230cf2c8e550c6758c64bbe5b5c560 100644 (file)
@@ -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()) {
index 274e3d3c3120369eb8915c752db357c8b8b80b23..5f52d173882903af05a8346561842d0f77006f52 100644 (file)
@@ -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 &);
index 1e372e753d8c82257fb7bcd34fe6295c11e70e78..2c0d164d5b4acb8f09bc4eba77b8a83faf881967 100644 (file)
@@ -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<float>::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<WorldCollision> &col) {
        AABB box = e.Bounds();
        glm::mat4 M = e.Transform(player->ChunkCoords());
index 2fd312c7ce39efb990ed2be07b16f0ce6b7313a8..6d27d12b8ab97f03fc6ef05688ae771a4348ccdd 100644 (file)
@@ -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<WorldCollision> &);
        void Resolve(Entity &e, std::vector<WorldCollision> &);
 
index aa91e7953a67238e1501d989ff5f397ec756bcca..54ceba081b035036164e6537919c8feca29e085e 100644 (file)
@@ -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() << ')';
 }