]> git.localhorst.tv Git - blank.git/commitdiff
simplify ray/chunk intersection test
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 9 Nov 2015 13:15:36 +0000 (14:15 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 9 Nov 2015 13:15:36 +0000 (14:15 +0100)
doc/todo
src/ai/ai.cpp
src/ui/ui.cpp
src/world/Chunk.hpp
src/world/World.hpp
src/world/chunk.cpp
src/world/world.cpp

index 39cb8a743b85e205ca30d3b9846aafc3ff44ed33..921221aa14f9681672023c4ed7480a35eaa3604d 100644 (file)
--- a/doc/todo
+++ b/doc/todo
@@ -29,6 +29,9 @@ persistence
 
        store some kind of byte order mark?
 
+       world and player names should be normalized so they can safely
+       be used in path names
+
 networking
 
        definitely needs throttling for the internets
@@ -36,6 +39,11 @@ networking
        players stats (who's connected, their ping, and game-relevant
        things) should be sent to clients
 
+       some method for authenticating a player might be nice
+
+       maybe stale and inexistent chunks should be visualized (e.g. by
+       drawing a semi-transparent box around them)
+
 threading
 
        (clientside) networking and disk IO are prime candidates for threading
index a2f5938eb707c3c58fc9199c3759a935b51a3393..0d4c9e9158256011e3477e595a93472cd52d4e8a 100644 (file)
@@ -169,7 +169,7 @@ Player *AIController::ClosestVisiblePlayer(const Entity &e) noexcept {
 
                // LOS test, assumes all entities are see-through
                WorldCollision col;
-               if (world.Intersection(aim, glm::mat4(1.0f), reference, col) && col.depth < dist) {
+               if (world.Intersection(aim, reference, col) && col.depth < dist) {
                        continue;
                }
 
@@ -189,7 +189,7 @@ bool AIController::LineOfSight(const Entity &from, const Entity &to) const noexc
                return false;
        }
        WorldCollision col;
-       if (world.Intersection(aim, glm::mat4(1.0f), reference, col) && col.depth < dist) {
+       if (world.Intersection(aim, reference, col) && col.depth < dist) {
                return false;
        }
        return true;
index c45b34b13213cf85dc6317e46e63fecae0abfa2d..02f2781c5e8f9cdb2326c1933092fd9105569ff1 100644 (file)
@@ -97,10 +97,10 @@ void PlayerController::Invalidate() noexcept {
 void PlayerController::UpdatePlayer() noexcept {
        if (dirty) {
                Ray aim = player.Aim();
-               if (!world.Intersection(aim, glm::mat4(1.0f), player.GetEntity().ChunkCoords(), aim_world)) {
+               if (!world.Intersection(aim, player.GetEntity().ChunkCoords(), aim_world)) {
                        aim_world = WorldCollision();
                }
-               if (!world.Intersection(aim, glm::mat4(1.0f), player.GetEntity(), aim_entity)) {
+               if (!world.Intersection(aim, player.GetEntity(), aim_entity)) {
                        aim_entity = EntityCollision();
                }
                if (aim_world && aim_entity) {
index 4938c1b1a7a92f3f34c861e30287ca23491c6686..d0dcf9404219ba063f91fb9b2e5dced933df40e9 100644 (file)
@@ -69,7 +69,11 @@ public:
                        (idx / (side * side))
                );
        }
-       glm::mat4 ToTransform(const RoughLocation::Fine &pos, int idx) const noexcept;
+       /// get a chunk-local transform for block at given position and index
+       /// (position and index are redundant)
+       glm::mat4 ToTransform(const RoughLocation::Fine &position, int index) const noexcept;
+       /// same as above, but also apply offset to given reference
+       glm::mat4 ToTransform(const ExactLocation::Coarse &ref, const RoughLocation::Fine &pos, int idx) const noexcept;
 
        ExactLocation::Fine ToSceneCoords(const ExactLocation::Coarse &base, const ExactLocation::Fine &pos) const noexcept {
                return ExactLocation::Fine((position - base) * ExactLocation::Extent()) + pos;
@@ -130,15 +134,17 @@ public:
 
        bool Intersection(
                const Ray &ray,
-               const glm::mat4 &M,
+               const ExactLocation::Coarse &reference,
                float &dist
        ) const noexcept {
-               return blank::Intersection(ray, Bounds(), M, &dist);
+               return blank::Intersection(ray, Bounds(), Transform(reference), &dist);
        }
 
+       /// check if given ray intersects any block of this chunk
+       /// given reference indicated the chunk offset of the ray in world space
        bool Intersection(
                const Ray &,
-               const glm::mat4 &M,
+               const ExactLocation::Coarse &reference,
                WorldCollision &) noexcept;
 
        bool Intersection(
@@ -155,6 +161,7 @@ public:
 
        void Position(const ExactLocation::Coarse &pos) noexcept { position = pos; }
        const ExactLocation::Coarse &Position() const noexcept { return position; }
+
        glm::mat4 Transform(const ExactLocation::Coarse &offset) const noexcept {
                return glm::translate((position - offset) * ExactLocation::Extent());
        }
index 8754d3992e800f518dd9b5db021a8c997a80ec9b..767f527a9034b97f352c66eda80f42d3f6569c0b 100644 (file)
@@ -45,19 +45,17 @@ public:
        /// check if this ray hits a block
        /// depth in the collision is the distance between the ray's
        /// origin and the intersection point
-       /// M is the global transform for given reference chunk
+       /// reference is the chunk offset of the ray in world space
        bool Intersection(
                const Ray &,
-               const glm::mat4 &M,
                const ExactLocation::Coarse &reference,
                WorldCollision &);
 
        /// check if this ray hits an entity
        /// intersections with the reference are not tested
-       /// M is the global transform for the chunk of given reference entity
+       /// the ray is assumed to be in world space offset by entity's chunk coords
        bool Intersection(
                const Ray &,
-               const glm::mat4 &M,
                const Entity &reference,
                EntityCollision &);
 
index cc305cd56a4b293f8aa1df121e797033f6e261b0..9e95458ef45ac7b9b818cd40d32193bc52fc9f51 100644 (file)
@@ -359,7 +359,7 @@ bool Chunk::IsSurface(const RoughLocation::Fine &pos) const noexcept {
 
 bool Chunk::Intersection(
        const Ray &ray,
-       const glm::mat4 &M,
+       const ExactLocation::Coarse &reference,
        WorldCollision &coll
 ) noexcept {
        int idx = 0;
@@ -375,7 +375,7 @@ bool Chunk::Intersection(
                                }
                                float cur_dist;
                                glm::vec3 cur_norm;
-                               if (type.shape->Intersects(ray, M * ToTransform(RoughLocation::Fine(x, y, z), idx), cur_dist, cur_norm)) {
+                               if (type.shape->Intersects(ray, ToTransform(reference, RoughLocation::Fine(x, y, z), idx), cur_dist, cur_norm)) {
                                        if (cur_dist < coll.depth) {
                                                coll.block = idx;
                                                coll.depth = cur_dist;
@@ -560,6 +560,10 @@ glm::mat4 Chunk::ToTransform(const RoughLocation::Fine &pos, int idx) const noex
        return glm::translate(ToCoords(pos)) * BlockAt(idx).Transform();
 }
 
+glm::mat4 Chunk::ToTransform(const ExactLocation::Coarse &ref, const RoughLocation::Fine &pos, int idx) const noexcept {
+       return glm::translate(ExactLocation::Fine((position - ref) * ExactLocation::Extent()) + ToCoords(pos)) * BlockAt(idx).Transform();
+}
+
 
 BlockLookup::BlockLookup(Chunk *c, const RoughLocation::Fine &p) noexcept
 : chunk(c), pos(p) {
index c43747a8c89f60089e560d54dbb49b01ce97a930..5e3420d525494f646ea85ad3789c1d83c6b011ad 100644 (file)
@@ -459,7 +459,6 @@ std::vector<Candidate> candidates;
 
 bool World::Intersection(
        const Ray &ray,
-       const glm::mat4 &M,
        const ExactLocation::Coarse &reference,
        WorldCollision &coll
 ) {
@@ -467,7 +466,7 @@ bool World::Intersection(
 
        for (Chunk &cur_chunk : chunks) {
                float cur_dist;
-               if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(reference), cur_dist)) {
+               if (cur_chunk.Intersection(ray, reference, cur_dist)) {
                        candidates.push_back({ &cur_chunk, cur_dist });
                }
        }
@@ -483,7 +482,7 @@ bool World::Intersection(
        for (Candidate &cand : candidates) {
                if (cand.dist > coll.depth) continue;
                WorldCollision cur_coll;
-               if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(reference), cur_coll)) {
+               if (cand.chunk->Intersection(ray, reference, cur_coll)) {
                        if (cur_coll.depth < coll.depth) {
                                coll = cur_coll;
                        }
@@ -495,7 +494,6 @@ bool World::Intersection(
 
 bool World::Intersection(
        const Ray &ray,
-       const glm::mat4 &M,
        const Entity &reference,
        EntityCollision &coll
 ) {
@@ -507,7 +505,7 @@ bool World::Intersection(
                }
                float cur_dist;
                glm::vec3 cur_normal;
-               if (blank::Intersection(ray, cur_entity.Bounds(), M * cur_entity.Transform(reference.ChunkCoords()), &cur_dist, &cur_normal)) {
+               if (blank::Intersection(ray, cur_entity.Bounds(), cur_entity.Transform(reference.ChunkCoords()), &cur_dist, &cur_normal)) {
                        // TODO: fine grained check goes here? maybe?
                        if (cur_dist < coll.depth) {
                                coll.entity = &cur_entity;