Browse Source

prevent stack overflow on kdtree build, ignore triangles without an area
for collision

Kajetan Johannes Hammerle 3 years ago
parent
commit
119bc496ee
2 changed files with 27 additions and 3 deletions
  1. 10 1
      client/Game.cpp
  2. 17 2
      common/utils/KDTree.cpp

+ 10 - 1
client/Game.cpp

@@ -9,6 +9,7 @@
 #include "common/utils/Random.h"
 #include "math/Quaternion.h"
 #include "rendering/wrapper/GLWrapper.h"
+#include "rendering/wrapper/GLFWWrapper.h"
 
 static float readFloat(std::ifstream& in) {
     float f;
@@ -60,6 +61,7 @@ worldRenderer(world), pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(
     std::vector<KDTree::Triangle> data;
 
     (void) readFloat;
+    (void) file;
 
     std::ifstream in;
     in.open(file);
@@ -95,7 +97,10 @@ worldRenderer(world), pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(
     }*/
     treeData.build();
 
+    u64 time = GLFWWrapper::getTimeNanos();
     kdTree.build(data);
+    time = GLFWWrapper::getTimeNanos() - time;
+    std::cout << "KD-Tree-Build-Time: " << time << "ns for " << data.size() << " triangles\n";
     kdTree.fillLines(lines);
 }
 
@@ -217,7 +222,11 @@ void Game::tick() {
         clickLine.clear();
         clickLine.add(pos, pos + direction * 100.0f, 0xFF00FF);
 
-        if(kdTree.findIntersection(pos, direction)) {
+        u64 time = GLFWWrapper::getTimeNanos();
+        bool check = kdTree.findIntersection(pos, direction);
+        time = GLFWWrapper::getTimeNanos() - time;
+        std::cout << "Intersection-Time: " << time << "ns\n";
+        if(check) {
             KDTree::Triangle t = kdTree.getIntersectedTriangle();
 
             clickLine.add(t[0], t[1], 0xFFFF00);

+ 17 - 2
common/utils/KDTree.cpp

@@ -73,6 +73,9 @@ float KDTree::median(std::vector<KDTree::Triangle>& data, int dim) const {
 }
 
 void KDTree::build(Node* n, std::vector<KDTree::Triangle>& data) {
+    for(KDTree::Triangle& t : data) {
+        n->data.push_back(t);
+    }
     if(data.size() == 0) {
         return;
     } else if(data.size() == 1) {
@@ -125,6 +128,15 @@ void KDTree::build(Node* n, std::vector<KDTree::Triangle>& data) {
             n->data.push_back(t);
         }
     }
+    if(lessEqualData.size() == 0 || greaterData.size() == 0) {
+        for(KDTree::Triangle& t : lessEqualData) {
+            n->data.push_back(t);
+        }
+        for(KDTree::Triangle& t : greaterData) {
+            n->data.push_back(t);
+        }
+        return;
+    }
     // recursive calls
     if(lessEqualData.size() > 0) {
         n->childs[0] = new Node();
@@ -225,7 +237,7 @@ bool KDTree::findIntersection(const Vector3& pos, const Vector3& direction) {
         t = std::max(t, std::abs((min[i] - pos[i]) / direction[i]));
         t = std::max(t, std::abs((max[i] - pos[i]) / direction[i]));
     }
-    
+
     return findIntersection(&root, pos, direction, t);
 }
 
@@ -258,7 +270,7 @@ bool KDTree::findIntersection(Node* n, const Vector3& pos, const Vector3& direct
             r = findIntersection(n->childs[first], pos, direction, tMax);
         }
     }
-
+    
     for(KDTree::Triangle& tri : n->data) {
         float t = testIntersection(pos, direction, tri);
         if(t < 0.0f) {
@@ -286,6 +298,9 @@ float KDTree::testIntersection(const Vector3& pos, const Vector3& direction, con
     Vector3 h1 = t[1] - t[0];
     Vector3 h2 = t[2] - t[0];
     Vector3 abc = h1.cross(h2);
+    if(abc.squareLength() < eps) {
+        return -1.0f;
+    }
     abc.normalize();
     float d = -abc.dot(t[0]);