]> git.localhorst.tv Git - blank.git/commitdiff
indexed iteration in ray/world collision tests
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 9 Dec 2015 16:22:03 +0000 (17:22 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 9 Dec 2015 16:22:03 +0000 (17:22 +0100)
src/world/ChunkIndex.hpp
src/world/world.cpp

index 1823de72b154359c4635a7a0e4f0d1d55ae6f9db..eb961a9d3ca236cef4b7dc5a2857ca75fcf95ec8 100644 (file)
@@ -47,6 +47,10 @@ public:
 
        int Extent() const noexcept { return extent; }
 
+       // raw iteration access, may contain nullptrs
+       std::vector<Chunk *>::const_iterator begin() const noexcept { return chunks.begin(); }
+       std::vector<Chunk *>::const_iterator end() const noexcept { return chunks.end(); }
+
        ExactLocation::Coarse CoordsBegin() const noexcept { return base - ExactLocation::Coarse(extent); }
        ExactLocation::Coarse CoordsEnd() const noexcept { return base + ExactLocation::Coarse(extent + 1); }
 
index 920313653ac1104ee91073a2d55df97462e2a4ed..243fb8a81b439655193b21615a84eddc7b70c389 100644 (file)
@@ -779,12 +779,22 @@ bool World::Intersection(
        const ExactLocation::Coarse &reference,
        WorldCollision &coll
 ) {
+       // only consider chunks of the idex closest to reference
+       // this makes the ray not be infinite anymore (which means it's
+       // actually a line segment), but oh well
+       ChunkIndex *index = chunks.ClosestIndex(reference);
+       if (!index) {
+               return false;
+       }
+
        candidates.clear();
 
-       for (Chunk &cur_chunk : chunks) {
+       // TODO: convert to coords based iteration and trim based
+       //       on ray direction
+       for (Chunk *cur_chunk : *index) {
                float cur_dist;
-               if (cur_chunk.Intersection(ray, reference, cur_dist)) {
-                       candidates.push_back({ &cur_chunk, cur_dist });
+               if (cur_chunk && cur_chunk->Intersection(ray, reference, cur_dist)) {
+                       candidates.push_back({ cur_chunk, cur_dist });
                }
        }
 
@@ -859,16 +869,19 @@ bool World::Intersection(
        const glm::ivec3 &reference,
        std::vector<WorldCollision> &col
 ) {
+       // this only works if box's diameter is < than 16
+       ExactLocation::Coarse begin(reference - 1);
+       ExactLocation::Coarse end(reference + 2);
+
        bool any = false;
-       for (Chunk &cur_chunk : chunks) {
-               if (manhattan_radius(cur_chunk.Position() - reference) > 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
-                       // TODO: change to indexed (like with entity)
-                       continue;
-               }
-               if (cur_chunk.Intersection(box, M, cur_chunk.Transform(reference), col)) {
-                       any = true;
+       for (ExactLocation::Coarse pos(begin); pos.z < end.z; ++pos.z) {
+               for (pos.y = begin.y; pos.y < end.y; ++pos.y) {
+                       for (pos.x = begin.x; pos.x < end.x; ++pos.x) {
+                               Chunk *chunk = chunks.Get(pos);
+                               if (chunk && chunk->Intersection(box, M, chunk->Transform(reference), col)) {
+                                       any = true;
+                               }
+                       }
                }
        }
        return any;