diff --git a/ECS/Systems/CollisionSystem.h b/ECS/Systems/CollisionSystem.h index ee64e35..2bc9c5a 100644 --- a/ECS/Systems/CollisionSystem.h +++ b/ECS/Systems/CollisionSystem.h @@ -28,7 +28,8 @@ class CollisionSystem : public EntitySystem { std::map triangle_map; - // TODO: Iterate over vertices, add triangles by also iterating over indices + // We iterate over the index array and add the resulting triangles to a hash map of + // vertices. That way, each vertex holds a list of all triangles it is involved in. for (int i = 0; i < mesh->vertex_count; i += 3) { // Build vertices from this triangle float v0p0 = vertices[indices[i + 0] * 14 + 0]; @@ -90,9 +91,7 @@ class CollisionSystem : public EntitySystem { // TODO }); - std::cout << "Start building kdtree with " << points.size() << " points" << std::endl; kdtree = new KDTree(points); - std::cout << "Done" << std::endl; } void tick(World *pWorld, float deltaTime) override { diff --git a/Util/geometry.h b/Util/geometry.h index f52683f..847122b 100644 --- a/Util/geometry.h +++ b/Util/geometry.h @@ -22,6 +22,7 @@ struct Vector { return Vector(c[0] - other.c[0], c[1] - other.c[1], c[2] - other.c[2]); } + // Arbitrary but functional definition of '<', primarily for use in an std::map. 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; } @@ -30,6 +31,7 @@ struct Vector { return false; } + // Component-wise multiplication with a scalar Vector operator*(float scalar) const { return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar); } diff --git a/Util/kdtree.h b/Util/kdtree.h index b60c5d2..fb9f140 100644 --- a/Util/kdtree.h +++ b/Util/kdtree.h @@ -1,3 +1,5 @@ +#pragma once + #include "geometry.h" #include #include @@ -9,7 +11,7 @@ class KDTree { public: KDTree(std::vector points) { - std::cout << "Starting to build tree with " << points.size() << " points took "; + std::cout << "Building 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(); @@ -109,13 +111,17 @@ class KDTree { void intersect_ray_recurse(const Triangle *&nearest_triangle, Vector &result, Ray ray, Node *node, int depth, float &nearest) { - // Exit condition: There was no collision + // Exit condition: This node was iterated towards, but does not exist if (node == nullptr) { return; } // Check for a collision here + // Iterate over all Triangles which this Point is involved in for (const Triangle *triangle : node->point->triangles) { Vector current_result(0, 0, 0); float current_distance; + + // If we have a collision, and it is closer to the ray origin than the closest previous + // collision, remember it if (ray.intersects_triangle(triangle, current_result, current_distance)) { if (current_distance < nearest) { nearest = current_distance; @@ -125,14 +131,16 @@ class KDTree { } } - // Is the left or right child node closer to this point? + // Is the ray origin within the left or right child node bounding box? Node *near = ray.origin[node->axis] > node->point->pos[node->axis] ? node->right : node->left; Node *far = near == node->right ? node->left : node->right; if (ray.direction[node->axis] == 0.0) { + // The ray is parallel to the splitting axis, so we only need to check within this box. intersect_ray_recurse(nearest_triangle, result, ray, near, depth + 1, nearest); } else { + // Calculate the distance from the ray origin to the splitting axis float t = (node->point->pos[node->axis] - ray.origin[node->axis]) / ray.direction[node->axis]; diff --git a/main.cpp b/main.cpp index 9cbc802..8e7a387 100644 --- a/main.cpp +++ b/main.cpp @@ -204,11 +204,11 @@ int main(int argc, char **argv) { Entity *sun = world->create(); sun->assign(glm::normalize(glm::vec3(1.0, 1.0, 1.0))); - Entity *kdtree_vis = world->create(); - // We're done loading geometry -> build the collision structure collision_system->build(); + // Save the visualized kdtree as another entity + Entity *kdtree_vis = world->create(); kdtree_vis->assign(collision_system->kdtree->get_lines()); Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs"); @@ -229,15 +229,16 @@ int main(int argc, char **argv) { world->tick(delta); renderSystem->render(world, defaultShader, shadowShader, debugShader, lineShader); + // Animations /* ring->get()->rotate(delta * 100.0, glm::vec3(0.0, 1.0, 0.0)); sun->get()->direction = glm::normalize(glm::vec3( 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))); */ - /* Swap front and back buffers */ + // Swap front and back buffers glfwSwapBuffers(window); - /* Poll for and process events */ + // Poll for and process events glfwPollEvents(); }