This repository has been archived on 2024-12-30. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
2024CG-project-render/lab1/Triangle.cpp
Tibo De Peuter d9cf26902e
Some checks failed
CMake / build (zip, zip, [self-hosted Linux], raytracing, ux) (push) Has been cancelled
CMake / build (zip, zip, [self-hosted Windows], Release/raytracing.exe, win) (push) Has been cancelled
chore: Cleanup
2024-10-25 17:50:44 +02:00

58 lines
1.7 KiB
C++

#include "Triangle.h"
#include "Ray.h"
#include <Eigen/Geometry> // hint
bool Triangle::intersect(
const Ray &ray, const double min_t, double &t, Eigen::Vector3d &n) const {
/* Based on
* Fundamentals in Computer Graphics - Fourth Edition, Chapter 4.4.2. Ray-Triangle Intersection.
* Steve Marschner & Peter Shirley
*/
Eigen::Vector3d a = std::get<0>(corners);
Eigen::Vector3d b = std::get<1>(corners);
Eigen::Vector3d c = std::get<2>(corners);
Eigen::Vector3d e = ray.origin;
Eigen::Vector3d d = ray.direction;
/* Using Cramer's rule. */
/* Calculate the determinant of A. */
Eigen::Matrix3d A;
A.col(0) = a - b;
A.col(1) = a - c;
A.col(2) = d;
const double determinant_A = A.determinant();
Eigen::Matrix3d t_matrix;
t_matrix.col(0) = a - b;
t_matrix.col(1) = a - c;
t_matrix.col(2) = a - e;
t = t_matrix.determinant() / determinant_A;
if (t < min_t) return false;
Eigen::Matrix3d gamma_matrix;
gamma_matrix.col(0) = a - b;
gamma_matrix.col(1) = a - e;
gamma_matrix.col(2) = d;
double gamma = gamma_matrix.determinant() / determinant_A;
if (gamma < 0 || gamma > 1) return false;
Eigen::Matrix3d beta_matrix;
beta_matrix.col(0) = a - e;
beta_matrix.col(1) = a - c;
beta_matrix.col(2) = d;
double beta = beta_matrix.determinant() / determinant_A;
if (beta < 0 || beta + gamma > 1) return false;
/* Calculate the surface normal vector using the cross product of two edges.
* See https://en.wikipedia.org/wiki/Cross_product#Computational_geometry */
Eigen::Vector3d edge1 = a - b;
Eigen::Vector3d edge2 = a - c;
n = edge1.cross(edge2).normalized(); /* Don't forget to normalize the vector. */
return true;
}