kdtree/geometry.h

105 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Forward declarations
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]);
}
Vector operator*(float scalar) const {
return Vector(c[0] * scalar, c[1] * scalar, c[2] * scalar);
}
Vector cross(const Vector &other) {
return Vector(c[2] * other[3] - c[3] - other[2], c[3] * other[1] - c[1] * other[3],
c[1] * other[2] - c[2] * other[1]);
}
float dot(const Vector &other) { return c[1] * other[1] + c[2] * other[2] + c[3] * other[3]; }
float *c;
};
struct Triangle {
Triangle(Vector p1, Vector p2, Vector p3) : p1(p1), p2(p2), p3(p3) {}
Vector p1;
Vector p2;
Vector p3;
};
struct Point {
Point(float coordinates[3], Triangle *triangle)
: pos(Vector(coordinates)), triangle(triangle) {}
Vector pos;
Triangle *triangle;
};
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(Triangle *triangle) {
// Ray-triangle-intersection with the MöllerTrumbore 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.
float t = f * edge2.dot(q);
if (t > EPSILON) {
return true;
} else {
// This means that there is a line intersection but not a ray intersection.
return false;
}
}
};