bool Face::triangle_intersect(const Ray &r, Hit &h, Vertex *a, Vertex *b, Vertex *c, bool intersect_backfacing) const { // compute the intersection with the plane of the triangle Hit h2 = Hit(h); if (!plane_intersect(r,h2,intersect_backfacing)) return 0; // figure out the barycentric coordinates: glm::vec3 Ro = r.getOrigin(); glm::vec3 Rd = r.getDirection(); // [ ax-bx ax-cx Rdx ][ beta ] [ ax-Rox ] // [ ay-by ay-cy Rdy ][ gamma ] = [ ay-Roy ] // [ az-bz az-cz Rdz ][ t ] [ az-Roz ] // solve for beta, gamma, & t using Cramer's rule glm::mat3 detA_mat(a->get().x-b->get().x,a->get().x-c->get().x,Rd.x, a->get().y-b->get().y,a->get().y-c->get().y,Rd.y, a->get().z-b->get().z,a->get().z-c->get().z,Rd.z); float detA = glm::determinant(detA_mat); if (fabs(detA) <= 0.000001) return 0; assert (fabs(detA) >= 0.000001); glm::mat3 beta_mat(a->get().x-Ro.x,a->get().x-c->get().x,Rd.x, a->get().y-Ro.y,a->get().y-c->get().y,Rd.y, a->get().z-Ro.z,a->get().z-c->get().z,Rd.z); glm::mat3 gamma_mat(a->get().x-b->get().x,a->get().x-Ro.x,Rd.x, a->get().y-b->get().y,a->get().y-Ro.y,Rd.y, a->get().z-b->get().z,a->get().z-Ro.z,Rd.z); float beta = glm::determinant(beta_mat) / detA; float gamma = glm::determinant(gamma_mat) / detA; if (beta >= -0.00001 && beta <= 1.00001 && gamma >= -0.00001 && gamma <= 1.00001 && beta + gamma <= 1.00001) { h = h2; // interpolate the texture coordinates float alpha = 1 - beta - gamma; float t_s = alpha * a->get_s() + beta * b->get_s() + gamma * c->get_s(); float t_t = alpha * a->get_t() + beta * b->get_t() + gamma * c->get_t(); h.setTextureCoords(t_s,t_t); assert (h.getT() >= EPSILON); return 1; } return 0; }
bool Face::triangle_intersect(const Ray &r, Hit &h, Vertex *a, Vertex *b, Vertex *c, bool intersect_backfacing, bool* backfacing_hit) { *backfacing_hit = false; // compute the intersection with the plane of the triangle Hit h2 = Hit(h); if (!plane_intersect(r,h2,intersect_backfacing, backfacing_hit)) return 0; // figure out the barycentric coordinates: Vec3f Ro = r.getOrigin(); Vec3f Rd = r.getDirection(); // [ ax-bx ax-cx Rdx ][ beta ] [ ax-Rox ] // [ ay-by ay-cy Rdy ][ gamma ] = [ ay-Roy ] // [ az-bz az-cz Rdz ][ t ] [ az-Roz ] // solve for beta, gamma, & t using Cramer's rule double detA = Matrix::det3x3(a->get().x()-b->get().x(),a->get().x()-c->get().x(),Rd.x(), a->get().y()-b->get().y(),a->get().y()-c->get().y(),Rd.y(), a->get().z()-b->get().z(),a->get().z()-c->get().z(),Rd.z()); if (fabs(detA) <= 0.000001) return 0; assert (fabs(detA) >= 0.000001); double beta = Matrix::det3x3(a->get().x()-Ro.x(),a->get().x()-c->get().x(),Rd.x(), a->get().y()-Ro.y(),a->get().y()-c->get().y(),Rd.y(), a->get().z()-Ro.z(),a->get().z()-c->get().z(),Rd.z()) / detA; double gamma = Matrix::det3x3(a->get().x()-b->get().x(),a->get().x()-Ro.x(),Rd.x(), a->get().y()-b->get().y(),a->get().y()-Ro.y(),Rd.y(), a->get().z()-b->get().z(),a->get().z()-Ro.z(),Rd.z()) / detA; //Case of an intersection if (beta >= -0.00001 && beta <= 1.00001 && gamma >= -0.00001 && gamma <= 1.00001 && beta + gamma <= 1.00001) { h = h2; // interpolate the texture coordinates double alpha = 1 - beta - gamma; double t_s = alpha * a->get_s() + beta * b->get_s() + gamma * c->get_s(); double t_t = alpha * a->get_t() + beta * b->get_t() + gamma * c->get_t(); h.setTextureCoords(t_s,t_t); assert (h.getT() >= EPSILON); return 1; } return 0; }