diff --git a/src/Triangle.cpp b/src/Triangle.cpp index 14a300e..42538ff 100644 --- a/src/Triangle.cpp +++ b/src/Triangle.cpp @@ -3,12 +3,57 @@ #include // hint bool Triangle::intersect( - const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const + const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const { - //////////////////////////////////////////////////////////////////////////// - // Replace with your code here: - return false; - //////////////////////////////////////////////////////////////////////////// -} + /* 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; + 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; +} \ No newline at end of file