Browse Source

improved ray trace

Kajetan Johannes Hammerle 2 years ago
parent
commit
259b6d6483
2 changed files with 19 additions and 9 deletions
  1. 18 8
      client/World.cpp
  2. 1 1
      subprojects/gaming-core

+ 18 - 8
client/World.cpp

@@ -188,23 +188,33 @@ Vector3 World::limitMove(const Box& box, Vector3 move) {
 
 RayTrace World::rayTrace(const Vector3& start, const Vector3& direction,
                          float maxDistance) {
-    constexpr float stepLength = 0.125f;
     RayTrace result{RayTrace::Type::AIR, IntVector3()};
 
     Vector3 pos = start;
     Vector3 step = direction;
-    step.normalize();
-    step *= stepLength;
 
-    int end = maxDistance / stepLength;
+    // prevent zero division
+    for(int i = 0; i < 3; i++) {
+        if(step[i] == 0.0f) {
+            step[i] = 0.0001f;
+        }
+    }
+    step.normalize();
 
-    for(int i = 0; i < end; i++) {
-        if(!World::isAir(pos[0], pos[1], pos[2])) {
-            result.block = pos.toInt();
+    while(maxDistance > 0.0f) {
+        IntVector3 lower(floorf(pos[0]), floorf(pos[1]), floorf(pos[2]));
+        if(!World::isAir(lower[0], lower[1], lower[2])) {
+            result.block = lower;
             result.type = RayTrace::Type::BLOCK;
             return result;
         }
-        pos += step;
+        Vector3 goal(step[0] < 0.0f ? lower[0] : lower[0] + 1,
+                     step[1] < 0.0f ? lower[1] : lower[1] + 1,
+                     step[2] < 0.0f ? lower[2] : lower[2] + 1);
+        Vector3 f = (goal - pos) / step;
+        float min = Math::max(Math::min(f[0], f[1], f[2]), 0.001f);
+        pos += step * min;
+        maxDistance -= min;
     }
     return result;
 }

+ 1 - 1
subprojects/gaming-core

@@ -1 +1 @@
-Subproject commit ab398c30bc566f56db81fdbbf2b7a40f07d1a308
+Subproject commit 1f086aa7d211204604b80f7d8028498d02444318