Compare commits

..

5 Commits

Author SHA1 Message Date
59d9311cc8 Rewrite intersect_ray_recurse
Like the function in the slides now, but I had to change a part because it's not working 100% otherwise... not very optimized now
2021-01-16 19:16:36 +01:00
40dc7850a9 Add support for multiple triangles per Point 2021-01-16 15:57:41 +01:00
ba98ae3386 Minor kdtree fixes/workarounds
Not sure why, but it misses some collisions with that t >= 0.0 clause...
2021-01-15 13:56:53 +01:00
90b6769278 Add visual output for the collision 2021-01-15 11:44:28 +01:00
3504d878f8 Improve visuals for kdtree rendering
Also remove the animations - these don't make sense with a static kdtree
2021-01-12 18:42:55 +01:00
9 changed files with 418 additions and 64 deletions

View File

@ -28,10 +28,10 @@ struct Lines {
} }
void render() const { void render() const {
// glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
// glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBindVertexArray(lineVAO); glBindVertexArray(lineVAO);
glLineWidth(3.3f); glLineWidth(1.0f);
glDrawArrays(GL_LINES, 0, vertex_count); glDrawArrays(GL_LINES, 0, vertex_count);
glLineWidth(1.0f); glLineWidth(1.0f);
} }

View File

@ -5,7 +5,6 @@
#ifndef ECSGAME_MESH_H #ifndef ECSGAME_MESH_H
#define ECSGAME_MESH_H #define ECSGAME_MESH_H
#include <GLFW/glfw3.h>
#include <glad/glad.h> #include <glad/glad.h>
#include <vector> #include <vector>

View File

@ -8,13 +8,16 @@
#include "../Components/Transform.h" #include "../Components/Transform.h"
#include "../ECS.h" #include "../ECS.h"
#include <map>
using namespace ECS; using namespace ECS;
class CollisionSystem : public EntitySystem { class CollisionSystem : public EntitySystem {
public: public:
CollisionSystem(Entity *collision_entity) : collision_entity(collision_entity) {}
// Initialize the kdtree // Initialize the kdtree
void build() { void build() {
std::vector<Triangle *> triangles;
std::vector<Point *> points; std::vector<Point *> points;
// ObjMesh // ObjMesh
@ -23,7 +26,11 @@ class CollisionSystem : public EntitySystem {
std::vector<unsigned int> indices = mesh->indices; std::vector<unsigned int> indices = mesh->indices;
std::vector<float> vertices = mesh->vertices; std::vector<float> vertices = mesh->vertices;
std::map<Vector, Point *> triangle_map;
// TODO: Iterate over vertices, add triangles by also iterating over indices
for (int i = 0; i < mesh->vertex_count; i += 3) { for (int i = 0; i < mesh->vertex_count; i += 3) {
// Build vertices from this triangle
float v0p0 = vertices[indices[i + 0] * 14 + 0]; float v0p0 = vertices[indices[i + 0] * 14 + 0];
float v0p1 = vertices[indices[i + 0] * 14 + 1]; float v0p1 = vertices[indices[i + 0] * 14 + 1];
float v0p2 = vertices[indices[i + 0] * 14 + 2]; float v0p2 = vertices[indices[i + 0] * 14 + 2];
@ -51,12 +58,30 @@ class CollisionSystem : public EntitySystem {
Vector v3(v3glm.x, v3glm.y, v3glm.z); Vector v3(v3glm.x, v3glm.y, v3glm.z);
Triangle *triangle = new Triangle(v1, v2, v3); Triangle *triangle = new Triangle(v1, v2, v3);
triangles.emplace_back(triangle);
points.emplace_back(new Point(v1, triangle)); if (triangle_map.count(v1) == 0) {
points.emplace_back(new Point(v2, triangle)); triangle_map[v1] = new Point(v1, std::list<Triangle *>{triangle});
points.emplace_back(new Point(v3, triangle)); } else {
triangle_map[v1]->triangles.emplace_back(triangle);
} }
if (triangle_map.count(v2) == 0) {
triangle_map[v2] = new Point(v2, std::list<Triangle *>{triangle});
} else {
triangle_map[v2]->triangles.emplace_back(triangle);
}
if (triangle_map.count(v3) == 0) {
triangle_map[v3] = new Point(v3, std::list<Triangle *>{triangle});
} else {
triangle_map[v3]->triangles.emplace_back(triangle);
}
}
// Convert to list
std::transform(
triangle_map.begin(), triangle_map.end(), back_inserter(points),
[](const std::map<Vector, Point *>::value_type &val) { return val.second; });
}); });
// LODObjMesh // LODObjMesh
@ -68,8 +93,6 @@ class CollisionSystem : public EntitySystem {
std::cout << "Start building kdtree with " << points.size() << " points" << std::endl; std::cout << "Start building kdtree with " << points.size() << " points" << std::endl;
kdtree = new KDTree(points); kdtree = new KDTree(points);
std::cout << "Done" << std::endl; std::cout << "Done" << std::endl;
std::cout << kdtree->to_string() << std::endl;
} }
void tick(World *pWorld, float deltaTime) override { void tick(World *pWorld, float deltaTime) override {
@ -81,16 +104,23 @@ class CollisionSystem : public EntitySystem {
glm::vec3 direction_glm = mouse_look->get_look_direction(); glm::vec3 direction_glm = mouse_look->get_look_direction();
Vector direction = Vector(direction_glm.x, direction_glm.y, direction_glm.z); Vector direction = Vector(direction_glm.x, direction_glm.y, direction_glm.z);
Ray ray(origin, direction * 5.0); Ray ray(origin, direction);
Triangle *result = kdtree->intersect_ray(ray); Vector collision_position(0, 0, 0);
const Triangle *result = kdtree->intersect_ray(ray, collision_position);
if (result) { if (result) {
std::cout << result->p1[0] << ", " << result->p1[1] << ", " << result->p1[2] // Output to console
<< std::endl; std::cout << "Triangle: " << result->p1[0] << ", " << result->p1[1] << ", "
} << result->p1[2] << " | " << result->p2[0] << ", " << result->p2[1]
<< ", " << result->p2[2] << " | " << result->p3[0] << ", "
<< result->p3[1] << ", " << result->p3[2] << std::endl;
// TODO: Also output visually // Ouput visually
glm::vec3 pos =
glm::vec3(collision_position[0], collision_position[1], collision_position[2]);
collision_entity->get<Transform>()->set_origin(pos);
}
}); });
} }
@ -99,4 +129,6 @@ class CollisionSystem : public EntitySystem {
World *myWorld; World *myWorld;
KDTree *kdtree; KDTree *kdtree;
Entity *collision_entity;
}; };

BIN
Resources/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

10
Resources/sphere.mtl Normal file
View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 500
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

271
Resources/sphere.obj Normal file
View File

@ -0,0 +1,271 @@
# Blender v2.83.5 OBJ File: ''
# www.blender.org
mtllib sphere.mtl
o Icosphere
v -0.000000 -0.200000 -0.000000
v 0.144721 -0.089444 0.105145
v -0.055278 -0.089444 0.170130
v -0.178885 -0.089443 -0.000000
v -0.055278 -0.089444 -0.170130
v 0.144721 -0.089444 -0.105145
v 0.055278 0.089444 0.170130
v -0.144721 0.089444 0.105145
v -0.144721 0.089444 -0.105145
v 0.055278 0.089444 -0.170130
v 0.178885 0.089443 -0.000000
v -0.000000 0.200000 -0.000000
v -0.032491 -0.170131 0.099999
v 0.085065 -0.170131 0.061802
v 0.052574 -0.105148 0.161802
v 0.170130 -0.105147 -0.000000
v 0.085065 -0.170131 -0.061802
v -0.105146 -0.170130 -0.000000
v -0.137638 -0.105147 0.099999
v -0.032491 -0.170131 -0.099999
v -0.137638 -0.105147 -0.099999
v 0.052574 -0.105148 -0.161802
v 0.190212 0.000000 0.061803
v 0.190212 0.000000 -0.061803
v -0.000000 0.000000 0.200000
v 0.117557 0.000000 0.161803
v -0.190212 0.000000 0.061803
v -0.117557 0.000000 0.161803
v -0.117557 0.000000 -0.161803
v -0.190212 0.000000 -0.061803
v 0.117557 0.000000 -0.161803
v -0.000000 0.000000 -0.200000
v 0.137638 0.105147 0.099999
v -0.052574 0.105148 0.161802
v -0.170130 0.105147 -0.000000
v -0.052574 0.105148 -0.161802
v 0.137638 0.105147 -0.099999
v 0.032491 0.170131 0.099999
v 0.105146 0.170130 -0.000000
v -0.085065 0.170131 0.061802
v -0.085065 0.170131 -0.061802
v 0.032491 0.170131 -0.099999
vt 0.818181 0.000000
vt 0.772726 0.078731
vt 0.863635 0.078731
vt 0.727272 0.157461
vt 0.681818 0.078731
vt 0.636363 0.157461
vt 0.090909 0.000000
vt 0.045454 0.078731
vt 0.136363 0.078731
vt 0.272727 0.000000
vt 0.227273 0.078731
vt 0.318182 0.078731
vt 0.454545 0.000000
vt 0.409090 0.078731
vt 0.500000 0.078731
vt 0.681818 0.236191
vt 0.909090 0.157461
vt 0.818181 0.157461
vt 0.863635 0.236191
vt 0.181818 0.157461
vt 0.090909 0.157461
vt 0.136363 0.236191
vt 0.363636 0.157461
vt 0.272727 0.157461
vt 0.318182 0.236191
vt 0.545454 0.157461
vt 0.454545 0.157461
vt 0.500000 0.236191
vt 0.772726 0.236191
vt 0.954545 0.236191
vt 0.227273 0.236191
vt 0.409090 0.236191
vt 0.590909 0.236191
vt 0.818181 0.314921
vt 0.727272 0.314921
vt 0.772726 0.393651
vt 1.000000 0.314921
vt 0.909091 0.314921
vt 0.954545 0.393651
vt 0.272727 0.314921
vt 0.181818 0.314921
vt 0.227273 0.393651
vt 0.454545 0.314921
vt 0.363636 0.314921
vt 0.409090 0.393651
vt 0.636363 0.314921
vt 0.545454 0.314921
vt 0.590909 0.393651
vt 0.500000 0.393651
vt 0.545454 0.472382
vt 0.318182 0.393651
vt 0.363636 0.472382
vt 0.136363 0.393651
vt 0.181818 0.472382
vt 0.090909 0.314921
vt 0.863635 0.393651
vt 0.909090 0.472382
vt 0.681818 0.393651
vt 0.727272 0.472382
vt 0.045454 0.236191
vt 0.000000 0.157461
vt 0.590909 0.078731
vt 0.636363 0.000000
vn 0.1024 -0.9435 0.3151
vn 0.7002 -0.6617 0.2680
vn -0.2680 -0.9435 0.1947
vn -0.2680 -0.9435 -0.1947
vn 0.1024 -0.9435 -0.3151
vn 0.9050 -0.3304 0.2680
vn 0.0247 -0.3304 0.9435
vn -0.8897 -0.3304 0.3151
vn -0.5746 -0.3304 -0.7488
vn 0.5346 -0.3304 -0.7779
vn 0.8026 -0.1256 0.5831
vn -0.3066 -0.1256 0.9435
vn -0.9921 -0.1256 0.0000
vn -0.3066 -0.1256 -0.9435
vn 0.8026 -0.1256 -0.5831
vn 0.4089 0.6617 0.6284
vn -0.4713 0.6617 0.5831
vn -0.7002 0.6617 -0.2680
vn 0.0385 0.6617 -0.7488
vn 0.7240 0.6617 -0.1947
vn 0.2680 0.9435 -0.1947
vn 0.4911 0.7947 -0.3568
vn 0.4089 0.6617 -0.6284
vn -0.1024 0.9435 -0.3151
vn -0.1876 0.7947 -0.5773
vn -0.4713 0.6617 -0.5831
vn -0.3313 0.9435 0.0000
vn -0.6071 0.7947 0.0000
vn -0.7002 0.6617 0.2680
vn -0.1024 0.9435 0.3151
vn -0.1876 0.7947 0.5773
vn 0.0385 0.6617 0.7488
vn 0.2680 0.9435 0.1947
vn 0.4911 0.7947 0.3568
vn 0.7240 0.6617 0.1947
vn 0.8897 0.3304 -0.3151
vn 0.7947 0.1876 -0.5773
vn 0.5746 0.3304 -0.7488
vn -0.0247 0.3304 -0.9435
vn -0.3035 0.1876 -0.9342
vn -0.5346 0.3304 -0.7779
vn -0.9050 0.3304 -0.2680
vn -0.9822 0.1876 0.0000
vn -0.9050 0.3304 0.2680
vn -0.5346 0.3304 0.7779
vn -0.3035 0.1876 0.9342
vn -0.0247 0.3304 0.9435
vn 0.5746 0.3304 0.7488
vn 0.7947 0.1876 0.5773
vn 0.8897 0.3304 0.3151
vn 0.3066 0.1256 -0.9435
vn 0.3035 -0.1876 -0.9342
vn 0.0247 -0.3304 -0.9435
vn -0.8026 0.1256 -0.5831
vn -0.7947 -0.1876 -0.5773
vn -0.8897 -0.3304 -0.3151
vn -0.8026 0.1256 0.5831
vn -0.7947 -0.1876 0.5773
vn -0.5746 -0.3304 0.7488
vn 0.3066 0.1256 0.9435
vn 0.3035 -0.1876 0.9342
vn 0.5346 -0.3304 0.7779
vn 0.9921 0.1256 0.0000
vn 0.9822 -0.1876 0.0000
vn 0.9050 -0.3304 -0.2680
vn 0.4713 -0.6617 -0.5831
vn 0.1876 -0.7947 -0.5773
vn -0.0385 -0.6617 -0.7488
vn -0.4089 -0.6617 -0.6284
vn -0.4911 -0.7947 -0.3568
vn -0.7240 -0.6617 -0.1947
vn -0.7240 -0.6617 0.1947
vn -0.4911 -0.7947 0.3568
vn -0.4089 -0.6617 0.6284
vn 0.7002 -0.6617 -0.2680
vn 0.6071 -0.7947 0.0000
vn 0.3313 -0.9435 0.0000
vn -0.0385 -0.6617 0.7488
vn 0.1876 -0.7947 0.5773
vn 0.4713 -0.6617 0.5831
usemtl None
s off
f 1/1/1 14/2/1 13/3/1
f 2/4/2 14/5/2 16/6/2
f 1/7/3 13/8/3 18/9/3
f 1/10/4 18/11/4 20/12/4
f 1/13/5 20/14/5 17/15/5
f 2/4/6 16/6/6 23/16/6
f 3/17/7 15/18/7 25/19/7
f 4/20/8 19/21/8 27/22/8
f 5/23/9 21/24/9 29/25/9
f 6/26/10 22/27/10 31/28/10
f 2/4/11 23/16/11 26/29/11
f 3/17/12 25/19/12 28/30/12
f 4/20/13 27/22/13 30/31/13
f 5/23/14 29/25/14 32/32/14
f 6/26/15 31/28/15 24/33/15
f 7/34/16 33/35/16 38/36/16
f 8/37/17 34/38/17 40/39/17
f 9/40/18 35/41/18 41/42/18
f 10/43/19 36/44/19 42/45/19
f 11/46/20 37/47/20 39/48/20
f 39/48/21 42/49/21 12/50/21
f 39/48/22 37/47/22 42/49/22
f 37/47/23 10/43/23 42/49/23
f 42/45/24 41/51/24 12/52/24
f 42/45/25 36/44/25 41/51/25
f 36/44/26 9/40/26 41/51/26
f 41/42/27 40/53/27 12/54/27
f 41/42/28 35/41/28 40/53/28
f 35/41/29 8/55/29 40/53/29
f 40/39/30 38/56/30 12/57/30
f 40/39/31 34/38/31 38/56/31
f 34/38/32 7/34/32 38/56/32
f 38/36/33 39/58/33 12/59/33
f 38/36/34 33/35/34 39/58/34
f 33/35/35 11/46/35 39/58/35
f 24/33/36 37/47/36 11/46/36
f 24/33/37 31/28/37 37/47/37
f 31/28/38 10/43/38 37/47/38
f 32/32/39 36/44/39 10/43/39
f 32/32/40 29/25/40 36/44/40
f 29/25/41 9/40/41 36/44/41
f 30/31/42 35/41/42 9/40/42
f 30/31/43 27/22/43 35/41/43
f 27/22/44 8/55/44 35/41/44
f 28/30/45 34/38/45 8/37/45
f 28/30/46 25/19/46 34/38/46
f 25/19/47 7/34/47 34/38/47
f 26/29/48 33/35/48 7/34/48
f 26/29/49 23/16/49 33/35/49
f 23/16/50 11/46/50 33/35/50
f 31/28/51 32/32/51 10/43/51
f 31/28/52 22/27/52 32/32/52
f 22/27/53 5/23/53 32/32/53
f 29/25/54 30/31/54 9/40/54
f 29/25/55 21/24/55 30/31/55
f 21/24/56 4/20/56 30/31/56
f 27/22/57 28/60/57 8/55/57
f 27/22/58 19/21/58 28/60/58
f 19/21/59 3/61/59 28/60/59
f 25/19/60 26/29/60 7/34/60
f 25/19/61 15/18/61 26/29/61
f 15/18/62 2/4/62 26/29/62
f 23/16/63 24/33/63 11/46/63
f 23/16/64 16/6/64 24/33/64
f 16/6/65 6/26/65 24/33/65
f 17/15/66 22/27/66 6/26/66
f 17/15/67 20/14/67 22/27/67
f 20/14/68 5/23/68 22/27/68
f 20/12/69 21/24/69 5/23/69
f 20/12/70 18/11/70 21/24/70
f 18/11/71 4/20/71 21/24/71
f 18/9/72 19/21/72 4/20/72
f 18/9/73 13/8/73 19/21/73
f 13/8/74 3/61/74 19/21/74
f 16/6/75 17/62/75 6/26/75
f 16/6/76 14/5/76 17/62/76
f 14/5/77 1/63/77 17/62/77
f 13/3/78 15/18/78 3/17/78
f 13/3/79 14/2/79 15/18/79
f 14/2/80 2/4/80 15/18/80

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <list>
#include <vector> #include <vector>
// Forward declarations // Forward declarations
@ -21,6 +22,14 @@ struct Vector {
return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]); return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]);
} }
bool operator<(const Vector &other) const {
if ((c[2] < other.c[2])) { return true; }
if ((c[2] == other.c[2]) && (c[1] < other.c[1])) { return true; }
if ((c[2] == other.c[2]) && (c[1] == other.c[1]) && (c[0] < other.c[0])) { return true; }
return false;
}
Vector operator*(float scalar) const { Vector operator*(float scalar) const {
return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar); return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar);
} }
@ -36,18 +45,22 @@ struct Vector {
}; };
struct Point { struct Point {
Point(Vector pos, Triangle *triangle) : pos(pos), triangle(triangle) {} Point(Vector pos) : pos(pos) {}
Point(Vector pos, std::list<Triangle *> triangles) : pos(pos), triangles(triangles) {}
Vector pos; Vector pos;
Triangle *triangle; std::list<Triangle *> triangles;
}; };
struct Triangle { struct Triangle {
Triangle(Vector p1, Vector p2, Vector p3) : p1(p1), p2(p2), p3(p3) {} Triangle(Vector p1, Vector p2, Vector p3) : p1(p1), p2(p2), p3(p3) {}
std::vector<Point *> create_point_objects() { std::vector<Point *> create_point_objects() {
return std::vector<Point *>{new Point(p1, this), new Point(p2, this), new Point(p3, this)}; return std::vector<Point *>{new Point(p1, std::list<Triangle *>{this}),
new Point(p2, std::list<Triangle *>{this}),
new Point(p3, std::list<Triangle *>{this})};
} }
Vector p1; Vector p1;
@ -74,7 +87,7 @@ struct Ray {
Vector direction; Vector direction;
bool intersects_triangle(Triangle *triangle) { bool intersects_triangle(const Triangle *triangle, Vector &result, float &t) {
// Ray-triangle-intersection with the MöllerTrumbore algorithm // Ray-triangle-intersection with the MöllerTrumbore algorithm
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
const float EPSILON = 0.0000001; const float EPSILON = 0.0000001;
@ -103,8 +116,9 @@ struct Ray {
// At this stage we can compute t to find out where the intersection point is on the // At this stage we can compute t to find out where the intersection point is on the
// line. // line.
float t = f * edge2.dot(q); t = f * edge2.dot(q);
if (t > EPSILON) { if (t > EPSILON) {
result = origin + direction * t;
return true; return true;
} else { } else {
// This means that there is a line intersection but not a ray intersection. // This means that there is a line intersection but not a ray intersection.

View File

@ -1,5 +1,6 @@
#include "geometry.h" #include "geometry.h"
#include <algorithm> #include <algorithm>
#include <chrono>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -7,11 +8,32 @@
class KDTree { class KDTree {
public: public:
KDTree(std::vector<Point *> points) { root = build(points, 0); } KDTree(std::vector<Point *> points) {
std::cout << "Starting to build tree with " << points.size() << " points took ";
auto start = std::chrono::high_resolution_clock::now();
root = build(points, 0);
auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " microseconds" << std::endl;
}
~KDTree() = default; // TODO: Delete all allocated Nodes ~KDTree() = default; // TODO: Delete all allocated Nodes
Triangle *intersect_ray(Ray ray) { return intersect_ray_recurse(ray, root, 1000.0, 0); } const Triangle *intersect_ray(const Ray ray, Vector &result) {
auto start = std::chrono::high_resolution_clock::now();
float nearest = 1000.0;
const Triangle *nearest_triangle = nullptr;
intersect_ray_recurse(nearest_triangle, result, ray, root, 1000.0, 0, nearest);
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Intersection took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " microseconds" << std::endl;
return nearest_triangle;
}
std::string to_string() { std::string to_string() {
std::string str = ""; std::string str = "";
@ -85,50 +107,49 @@ class KDTree {
build(right_of_median, depth + 1)); build(right_of_median, depth + 1));
} }
Triangle *intersect_ray_recurse(Ray ray, Node *node, float max_distance, int depth) { void intersect_ray_recurse(const Triangle *&nearest_triangle, Vector &result, Ray ray,
Node *node, float max_distance, int depth, float &nearest) {
// Exit condition: There was no collision // Exit condition: There was no collision
if (node == nullptr) { return nullptr; } if (node == nullptr) { return; }
// Check for a collision here
for (const Triangle *triangle : node->point->triangles) {
Vector current_result(0, 0, 0);
float current_distance;
if (ray.intersects_triangle(triangle, current_result, current_distance)) {
if (current_distance < nearest) {
nearest = current_distance;
nearest_triangle = triangle;
result = current_result;
}
}
}
// Is the left or right child node closer to this point? // Is the left or right child node closer to this point?
Node *near = Node *near =
ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left; ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left;
Node *far = near == node->right ? node->left : node->right; Node *far = near == node->right ? node->left : node->right;
// Check for collisions in this order (stopping if an intersection is found): if (ray.direction[node->axis] == 0.0) {
// 1. In the nearer section intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
// 2. With the point in this current node nearest);
// 3. In the further section } else {
/* float t =
(node->point->pos[node->axis] - ray.origin[node->axis]) /
ray.direction[node->axis];
// If the axes are not parallel, our max_distance decreases, since we've already covered if (t >= 0.0 && t < max_distance) {
// some area. `t` represents the distance from this node to the splitting plane. intersect_ray_recurse(nearest_triangle, result, ray, near, t, depth + 1,
float t = ray.direction[node->axis] != 0.0 nearest); intersect_ray_recurse(nearest_triangle, result, Ray(ray.origin +
? (node->point->pos[node->axis] - ray.origin[node->axis]) / ray.direction * t, ray.direction), far, max_distance - t, depth + 1, nearest); } else
ray.direction[node->axis] { intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
: max_distance; nearest);
Triangle *near_result = intersect_ray_recurse(ray, near, t, depth + 1); } */
intersect_ray_recurse(nearest_triangle, result, ray, near, max_distance, depth + 1,
// If the nearer segment had a collision, we're done! We're only interested in the closest nearest);
// collision. intersect_ray_recurse(nearest_triangle, result, ray, far, max_distance, depth + 1,
if (near_result != nullptr) { return near_result; } nearest);
// No collision in the nearer side, so check for a collision directly here
if (ray.intersects_triangle(node->point->triangle)) {
// We do have a collision here, so we're done and can return this point!
return node->point->triangle;
} }
// No collision here either. Does it make sense to also check the far node?
// Only if the axes are not parallel and if that area is not behind us
if (ray.direction[node->axis] != 0.0 && t >= 0.0) {
// It does make sense to check the far node.
// For this, calculate a new ray origin and continue towards that direction, but with
// the new origin (we can leave behind what we already checked)
return intersect_ray_recurse(Ray(ray.origin + ray.direction * t, ray.direction), far,
max_distance - t, depth + 1);
}
// If nothing worked, return a nullptr
return nullptr;
} }
void to_string_recurse(std::string &str, Node *node, int depth) { void to_string_recurse(std::string &str, Node *node, int depth) {

View File

@ -91,7 +91,14 @@ int main(int argc, char **argv) {
world->registerSystem(new SineAnimationSystem()); world->registerSystem(new SineAnimationSystem());
world->registerSystem(new InteractivePathSystem()); world->registerSystem(new InteractivePathSystem());
CollisionSystem *collision_system = new CollisionSystem(); // Create collision indicator
Entity *collision_point = world->create();
collision_point->assign<Transform>();
collision_point->assign<ObjMesh>(ObjMesh("Resources/sphere.obj", ObjMesh::Settings()));
collision_point->assign<Texture>("Resources/red.png", Texture::Settings(true), false);
collision_point->assign<Material>(0.1, 0.9);
CollisionSystem *collision_system = new CollisionSystem(collision_point);
world->registerSystem(collision_system); world->registerSystem(collision_system);
RenderSystem *renderSystem = new RenderSystem(); RenderSystem *renderSystem = new RenderSystem();
@ -222,10 +229,10 @@ int main(int argc, char **argv) {
world->tick(delta); world->tick(delta);
renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader); renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader);
ring->get<Transform>()->rotate(delta * 100.0, glm::vec3(0.0, 1.0, 0.0)); /* ring->get<Transform>()->rotate(delta * 100.0, glm::vec3(0.0, 1.0, 0.0));
sun->get<DirectionalLight>()->direction = glm::normalize(glm::vec3( sun->get<DirectionalLight>()->direction = glm::normalize(glm::vec3(
glm::rotate(glm::mat4(1), (float)elapsed_time * 0.5f, glm::vec3(0.0, 1.0, 0.0)) * glm::rotate(glm::mat4(1), (float)elapsed_time * 0.5f, glm::vec3(0.0, 1.0, 0.0))
glm::vec4(1.0, 1.0, 1.0, 0.0))); * glm::vec4(1.0, 1.0, 1.0, 0.0))); */
/* Swap front and back buffers */ /* Swap front and back buffers */
glfwSwapBuffers(window); glfwSwapBuffers(window);