#pragma once #include #include // Forward declarations struct Triangle; struct Vector { Vector(float coordinates[3]) : c(coordinates) {} Vector(float x, float y, float z) : c(new float[3]{x, y, z}) {} // Avoid having to write vector.c[index], instead allow vector[index] float operator[](int i) const { return c[i]; } float &operator[](int i) { return c[i]; } Vector operator+(const Vector &other) const { return Vector(c[0] + other.c[0], c[1] + other.c[1], c[2] + other.c[2]); } Vector operator-(const Vector &other) const { 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 { return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar); } Vector cross(const Vector &other) { return Vector(c[1] * other[2] - c[2] * other[1], c[2] * other[0] - c[0] * other[2], c[0] * other[1] - c[1] * other[0]); } float dot(const Vector &other) { return c[0] * other[0] + c[1] * other[1] + c[2] * other[2]; } float *c; }; struct Point { Point(Vector pos) : pos(pos) {} Point(Vector pos, std::list triangles) : pos(pos), triangles(triangles) {} Vector pos; std::list triangles; }; struct Triangle { Triangle(Vector p1, Vector p2, Vector p3) : p1(p1), p2(p2), p3(p3) {} std::vector create_point_objects() { return std::vector{new Point(p1, std::list{this}), new Point(p2, std::list{this}), new Point(p3, std::list{this})}; } Vector p1; Vector p2; Vector p3; }; struct Node { Node(int axis, Point *point, Node *left, Node *right) : axis(axis), point(point), left(left), right(right) {} int axis; Point *point; Node *left; Node *right; }; struct Ray { Ray(Vector origin, Vector direction) : origin(origin), direction(direction) {} Vector origin; Vector direction; bool intersects_triangle(const Triangle *triangle, Vector &result, float &t) { // Ray-triangle-intersection with the Möller–Trumbore algorithm // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm const float EPSILON = 0.0000001; Vector p1 = triangle->p1; Vector p2 = triangle->p2; Vector p3 = triangle->p3; Vector edge1 = p2 - p1; Vector edge2 = p3 - p1; Vector h = direction.cross(edge2); float a = edge1.dot(h); if (a > -EPSILON && a < EPSILON) return false; // This ray is parallel to this triangle. float f = 1.0 / a; Vector s = origin - p1; float u = f * s.dot(h); if (u < 0.0 || u > 1.0) return false; Vector q = s.cross(edge1); float v = f * direction.dot(q); if (v < 0.0 || u + v > 1.0) return false; // At this stage we can compute t to find out where the intersection point is on the // line. t = f * edge2.dot(q); if (t > EPSILON) { result = origin + direction * t; return true; } else { // This means that there is a line intersection but not a ray intersection. return false; } } };