I am currently writing a ray tracer. I have to write a function called ClosestIntersection that checks if a ray intersects with a triangle and it should also return (update to be exact) some information about the closest intersection.
My code:
bool ClosestIntersection(vec3 start, vec3 dir, const vector<Triangle>& triangles, Intersection& closestIntersection)
{
for (int i = 0; i < triangles.size(); i++) {
vec3 v0 = triangles[i].v0;
vec3 v1 = triangles[i].v1;
vec3 v2 = triangles[i].v2;
vec3 e1 = v1 - v0;
vec3 e2 = v2 - v0;
vec3 b = start - v0;
mat3 A(-dir, e1, e2);
vec3 x = glm::inverse(A) * b;
if ((x.x >= 0) && (x.y > 0) && (x.z > 0) && ((x.y + x.z) < 1)) {
closestIntersection.position = x.x*dir;
closestIntersection.distance = x.x;
closestIntersection.triangleIndex = i;
return true;
}
else {
return false;
}
}
}
I have noticed that the if statement in my code never becomes true (AKA returns false every time), the funny thing is all of the conditions in the statment are all true when tested individually but not when they are put together as multiple conditions.
I did find another piece of code on the internet that looks similar to mine (I would say it looks identical).
Other code:
bool ClosestIntersection(vec3 start,
vec3 dir,
const vector<Triangle>& triangles,
Intersection& closestIntersection ){
bool exists = false;
for(int i=0; i<triangles.size(); i++){
using glm::vec3;
using glm::mat3;
vec3 v0 = triangles[i].v0;
vec3 v1 = triangles[i].v1;
vec3 v2 = triangles[i].v2;
vec3 e1 = v1 - v0;
vec3 e2 = v2 - v0;
vec3 b = start -v0;
mat3 A( -dir, e1, e2 );
vec3 x = glm::inverse( A ) * b;
if ( x.x > 0 ){
if (x.y > 0) {
if (x.z > 0) {
if (x.y+x.z < 1){
if (closestIntersection.distance < x.t){
closestIntersection.position = x.x*dir;
closestIntersection.distance = x.x;
closestIntersection.triangleIndex = i;
}
}
}
}
exists = true;
}
}
return exists;
}
This 2nd code works just fine but mine doesn't. The only difference between them that I can see is the if(closestIntersection.distance < x.t)
statement. I have no idea what this statement does because I have no idea what x.t is supposed to represent or return (new to C++). As far as I know a 3D vectors (vec3) XYZ values can be obtained by writing vec3.x, vec3.y or vec3.z but what value is vec3.t supposed to be?
Basically my 2 questions are:
What are the differences between the two code pieces?
What does vec3.t return and what does it represent?
(if you are still confused as to what I am actually doing or need some more context you can read the chapter "2.3 Intersection" in this: https://www.kth.se/social/files/55145c24f276547e50713af4/DH2323%20lab2.pdf PDF. Its a very small amount of text, not long at all)
The problem is not the if
statement. That's a red herring.
The critical difference between the two sets of code is your use of return statements inside the for
loop. What's happening is that your code never really loops: it enters the first iteration of the loop, and then immediately returns true or false. So the logical output of your code is that it checks the first triangle for intersection, and returns whether they intersect or not. But based on your code, it looks like what you want is to find out is "do any triangles intersect, and if so, which one?".
The simplest solution is to do like the second code set, use a bool
to track whether you've found an intersection, and only return that value outside the loop.