I'm trying to render a dodecahedron triangle mesh and the triangles seem flipped or mirrored somehow. The first picture is what I should be getting, the second picture is what I'm getting and the last picture is if I only render the first triangle face of the mesh from the obj file. I'm attempting to use Barycentric coordinates and Cramer's rule to find the determinant and solve for beta, gamma, and t (the depth of the ray at the point of intersection). I think the mistake is in how I read in the triangle's vertices or how I build the other functions and compute the determinant.
This function is called during a loop of all the objects in a scene and compares the closest hit point found in the mesh to a global HitRecord (h) that was passed in and has a h.t parameter that has the depth (t) of the ray hit point of any other objects checked before the current mesh.
bool Mesh::hit(Ray r, HitRecord & h){
double closest_sofar = 0.0;
vec3 normal;
size_t size = m_faces.size();
for(int i = 0; i < size; ++i){
Triangle t = m_faces[i];
glm::vec3 a = m_vertices[t.v1];
glm::vec3 b = m_vertices[t.v2];
glm::vec3 c = m_vertices[t.v3];
glm::vec3 answer = a - r.r_origin;
vec3 A = a-b;
vec3 B = a-c;
vec3 D = r.r_direction;
double det = dot(cross(A, B), D);
if(det == 0.0 || det == -0.0) { continue; }
double beta = dot(cross(answer, B), D) / det;
double gamma = dot(cross(A, answer), D) / det;
double closest = dot(cross(A, B), answer) / det;
if((1.0 > beta > 0.0) &&
(1.0 > gamma > 0.0) &&
(1.0 > 1.0 - beta - gamma > 0.0) &&
(closest_sofar == 0.0 || closest_sofar > closest > 0.0)){
closest_sofar = closest;
normal = normalize(cross(A, B));
}
else { continue; }
}
if(closest_sofar == 0.0) {
return false; }
if(h.t == 0.0 || closest_sofar < h.t){
h.t = closest_sofar;
h.normal = normal;
return true;
}
else{ return false; }
}
a<x<b
evaluates to(a<x)<b
, where the first expression is a true or false, so you get0<b
or1<b
. Instead you wanta<x && x<b
. It is also enough to check only0<closest && closest<closest_so_far && 0<beta && 0<gamma && beta+gamma<1
. $\endgroup$closest_so_far
to infinity, then you wouldn't need such checks. $\endgroup$