]> git.localhorst.tv Git - blank.git/commitdiff
test entities for world collision
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 24 Jun 2015 14:26:44 +0000 (16:26 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 24 Jun 2015 14:26:44 +0000 (16:26 +0200)
useless and slow as hell, but hey, it's a start ^^

src/app/Application.cpp
src/ui/ui.cpp
src/world/Chunk.hpp
src/world/Entity.cpp
src/world/Entity.hpp
src/world/World.cpp
src/world/World.hpp
src/world/chunk.cpp

index 67438dbdcbca6a17d00b3749d5fffa3c457bac24..a5613f9c66357e48874b9158a927b3f7b8fc26ed 100644 (file)
@@ -32,7 +32,10 @@ Application::Application(const Config &config)
 
 Entity &Application::MakeTestEntity(World &world) {
        Entity &e = world.AddEntity();
+       e.Name("test");
        e.Position({ 0.0f, 0.0f, 0.0f });
+       e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
+       e.WorldCollidable(true);
        e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f });
        e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
        return e;
index 410072da681ed292042949fb88247bd409160068..c71b7c105a0f0c357a359e5cd8ac34779856d166 100644 (file)
@@ -356,7 +356,7 @@ void Interface::Update(int dt) {
 
 void Interface::CheckAim() {
        float dist;
-       if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) {
+       if (world.Intersection(aim, glm::mat4(1.0f), aim_chunk, aim_block, dist, aim_normal)) {
                outline.Clear();
                aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline);
                outline_transform = glm::scale(glm::vec3(1.0002f));
index 8d6816c29b8f526527bbb8fb07688f74132c340c..8a2ded64e53970ee5929ce9aa336d90f41981d45 100644 (file)
@@ -143,6 +143,11 @@ public:
                float &dist,
                glm::vec3 &normal) const noexcept;
 
+       bool Intersection(
+               const AABB &box,
+               const glm::mat4 &Mbox,
+               const glm::mat4 &Mchunk) const noexcept;
+
        void Position(const Pos &pos) noexcept { position = pos; }
        const Pos &Position() const noexcept { return position; }
        glm::mat4 Transform(const Pos &offset) const noexcept {
index 6b23cacf8cccfc1d11aa9f86479be1df3523d174..844f74bf5f7be7da0cb7d9545beb157bd9d1f1fe 100644 (file)
@@ -1,6 +1,5 @@
 #include "Entity.hpp"
 
-#include "../model/geometry.hpp"
 #include "../model/Shape.hpp"
 
 #include <cmath>
@@ -17,11 +16,14 @@ namespace blank {
 Entity::Entity() noexcept
 : shape(nullptr)
 , model()
+, name("anonymous")
+, bounds()
 , velocity(0, 0, 0)
 , position(0, 0, 0)
 , chunk(0, 0, 0)
 , angular_velocity(1.0f, 0.0f, 0.0f, 0.0f)
-, rotation(1.0f) {
+, rotation(1.0f)
+, world_collision(false) {
 
 }
 
index 83c1f6fb0889b88697365e34a129b15aa7dc076f..7c96f4f3408d2c346c3c638f10ff83bb19f53213 100644 (file)
@@ -3,15 +3,16 @@
 
 #include "Block.hpp"
 #include "Chunk.hpp"
+#include "../model/geometry.hpp"
 #include "../model/Model.hpp"
 
+#include <string>
 #include <glm/glm.hpp>
 #include <glm/gtc/quaternion.hpp>
 
 
 namespace blank {
 
-class Ray;
 class Shape;
 
 class Entity {
@@ -24,6 +25,15 @@ public:
        void SetShape(const Shape *, const glm::vec3 &color);
        void SetShapeless() noexcept;
 
+       const std::string &Name() const noexcept { return name; }
+       void Name(const std::string &n) { name = n; }
+
+       const AABB &Bounds() const noexcept { return bounds; }
+       void Bounds(const AABB &b) noexcept { bounds = b; }
+
+       bool WorldCollidable() const noexcept { return world_collision; }
+       void WorldCollidable(bool b) noexcept { world_collision = b; }
+
        const glm::vec3 &Velocity() const noexcept { return velocity; }
        void Velocity(const glm::vec3 &) noexcept;
 
@@ -51,6 +61,10 @@ private:
        const Shape *shape;
        Model model;
 
+       std::string name;
+
+       AABB bounds;
+
        glm::vec3 velocity;
        Block::Pos position;
        Chunk::Pos chunk;
@@ -58,6 +72,8 @@ private:
        glm::quat angular_velocity;
        glm::mat4 rotation;
 
+       bool world_collision;
+
 };
 
 }
index 529968ea7470ce67ae7d9ed2e3a77a173f37e47d..82701ce8686f48f20b3f24039a1239547375671f 100644 (file)
@@ -3,6 +3,7 @@
 #include "../graphics/BlockLighting.hpp"
 #include "../graphics/DirectionalLighting.hpp"
 
+#include <iostream>
 #include <limits>
 #include <glm/gtx/transform.hpp>
 
@@ -113,6 +114,9 @@ World::World(const Config &config)
        generate.Solids({ 1, 4, 7, 10 });
 
        player = &AddEntity();
+       player->Name("player");
+       player->Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
+       player->WorldCollidable(true);
        player->Position(config.spawn);
 
        chunks.GenerateSurrounding(player->ChunkCoords());
@@ -131,12 +135,13 @@ std::vector<Candidate> candidates;
 }
 
 bool World::Intersection(
-               const Ray &ray,
-               const glm::mat4 &M,
-               Chunk **chunk,
-               int *blkid,
-               float *dist,
-               glm::vec3 *normal) {
+       const Ray &ray,
+       const glm::mat4 &M,
+       Chunk *&chunk,
+       int &blkid,
+       float &dist,
+       glm::vec3 &normal
+) {
        candidates.clear();
 
        for (Chunk &cur_chunk : chunks.Loaded()) {
@@ -148,39 +153,37 @@ bool World::Intersection(
 
        if (candidates.empty()) return false;
 
-       Chunk *closest_chunk = nullptr;
-       float closest_dist = std::numeric_limits<float>::infinity();
-       int closest_blkid = -1;
-       glm::vec3 closest_normal;
+       chunk = nullptr;
+       dist = std::numeric_limits<float>::infinity();
+       blkid = -1;
 
        for (Candidate &cand : candidates) {
-               if (cand.dist > closest_dist) continue;
+               if (cand.dist > dist) continue;
                int cur_blkid;
                float cur_dist;
                glm::vec3 cur_normal;
                if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(player->ChunkCoords()), cur_blkid, cur_dist, cur_normal)) {
-                       if (cur_dist < closest_dist) {
-                               closest_chunk = cand.chunk;
-                               closest_blkid = cur_blkid;
-                               closest_dist = cur_dist;
-                               closest_normal = cur_normal;
+                       if (cur_dist < dist) {
+                               chunk = cand.chunk;
+                               blkid = cur_blkid;
+                               dist = cur_dist;
+                               normal = cur_normal;
                        }
                }
        }
 
-       if (chunk) {
-               *chunk = closest_chunk;
-       }
-       if (blkid) {
-               *blkid = closest_blkid;
-       }
-       if (dist) {
-               *dist = closest_dist;
-       }
-       if (normal) {
-               *normal = closest_normal;
+       return chunk;
+}
+
+bool World::Intersection(const Entity &e) {
+       AABB box = e.Bounds();
+       glm::mat4 M = e.Transform(player->ChunkCoords());
+       for (Chunk &cur_chunk : chunks.Loaded()) {
+               if (cur_chunk.Intersection(box, M, cur_chunk.Transform(player->ChunkCoords()))) {
+                       return true;
+               }
        }
-       return closest_chunk;
+       return false;
 }
 
 
@@ -198,6 +201,12 @@ void World::Update(int dt) {
        for (Entity &entity : entities) {
                entity.Update(dt);
        }
+       for (Entity &entity : entities) {
+               if (entity.WorldCollidable() && Intersection(entity)) {
+                       // entity collides with the world
+                       std::cout << entity.Name() << " entity intersects world" << std::endl;
+               }
+       }
        chunks.Rebase(player->ChunkCoords());
        chunks.Update(dt);
 }
index ae704946dc4403079ebae724c54c828b0cc82fd8..7f38942ea2e4d9b4389dc97e2a430a1458951ff3 100644 (file)
@@ -21,7 +21,7 @@ class World {
 public:
        struct Config {
                // initial player position
-               glm::vec3 spawn = { 4.0f, 4.0f, 4.0f };
+               glm::vec3 spawn = { 0.0f, 0.0f, 0.0f };
                // direction facing towards(!) the light
                glm::vec3 light_direction = { -1.0f, -3.0f, -2.0f };
                // fade out reaches 1/e (0.3679) at 1/fog_density,
@@ -39,10 +39,12 @@ public:
        bool Intersection(
                const Ray &,
                const glm::mat4 &M,
-               Chunk **chunk = nullptr,
-               int *blkid = nullptr,
-               float *dist = nullptr,
-               glm::vec3 *normal = nullptr);
+               Chunk *&chunk,
+               int &blkid,
+               float &dist,
+               glm::vec3 &normal);
+
+       bool Intersection(const Entity &e);
 
        BlockTypeRegistry &BlockTypes() { return blockType; }
 
index c114526ba46cdace3204acb226189cb0af671d27..2216617ec52aac4dc59b317329d2103da84d872a 100644 (file)
@@ -481,6 +481,30 @@ bool Chunk::Intersection(
        }
 }
 
+bool Chunk::Intersection(
+       const AABB &box,
+       const glm::mat4 &Mbox,
+       const glm::mat4 &Mchunk
+) const noexcept {
+       if (!blank::Intersection(box, Mbox, Bounds(), Mchunk)) {
+               return false;
+       }
+       for (int idx = 0, z = 0; z < depth; ++z) {
+               for (int y = 0; y < height; ++y) {
+                       for (int x = 0; x < width; ++x, ++idx) {
+                               const BlockType &type = Type(idx);
+                               if (!type.visible) {
+                                       continue;
+                               }
+                               if (type.shape->Intersects(Mchunk * ToTransform(Pos(x, y, z), idx), box, Mbox)) {
+                                       return true;
+                               }
+                       }
+               }
+       }
+       return false;
+}
+
 
 namespace {