-1

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:

  1. What are the differences between the two code pieces?

  2. 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)

Schytheron
  • 715
  • 8
  • 28
  • It is mathematically not possible for all the statements to be individually true yet logically AND'ing them together is false. – AndyG Apr 12 '17 at 16:48
  • This code doesn't involve OpenGL in any way so I've removed the OpenGL tag. It looks like a software raytracer. – Dietrich Epp Apr 12 '17 at 16:50

1 Answers1

2

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.

Xirema
  • 19,889
  • 4
  • 32
  • 68
  • Ok, that worked. I have some graphical glitches now but before the program refused to draw anything (just showed a black screen). The graphical glitches are likely to be caused by me not checking if the closestIntersection really is the CLOSEST one (I assume the `if(closestIntersection.distance < x.t)` statement is responsible for checking this in the 2nd code piece). One question remains. What does vec3.t represent? Because I have no idea what the `if(closestIntersection.distance < x.t)` statement actually does... – Schytheron Apr 12 '17 at 17:00
  • @Schytheron I don't know either. You'll have to ask whomever wrote the original code. – Xirema Apr 12 '17 at 17:05
  • The vec3 data type is part of the glm library (I think, unless C++ has built in vec3 data types) so its not something that the other guy created himself. I just can't seem to find any documentation on the vec3.t syntax. – Schytheron Apr 12 '17 at 17:11