1

I Have never done raytracing before, and need some help with it.

The current program lets you click on the screen and select a color that you can "color" different triangles with.

But to select which triangle to color i will have to "shoot a ray" from the screen where the click was and check what the first thing it hits is.

The view can also rotate, so i might have to do a rotation matrix or something on the ray before i shoot it.

can someone point me in the right direction?

So far i have tried shoting a ray straight forward from the screen

    code
    glm::vec3 raystart((sdlEvent.x-halfScreenWidth)/halfScreenWidth,
                      (sdlEvent.y-halfScreenHeight)/halfScreenHeight,0.0f);
    glm::vec3 raydirection(0.0f,0.0f,-1,0f);

i have a feeling this is where stuff goes wrong. But i dont know.

After that it checks whether or not the vector(my ray) will ever hit(aka dot product)

    float dotproduct = glm::dot(rayStart,glm::vec4(normal.x,normal.y,normal.z,1));

and checks how long time it takes before it hits the plane.

    float t=((data.at(i*3).x*normal.x+data.at(i*3).y*normal.y+
    data.at(i*3).z*normal.z-normal.x*rayStart.x-
    normal.y*rayStart.y-normal.z*rayStart.z)/dotproduct);

Where normal is the normal of the plane.

then it checks where the collisions happens and if it collides inside the triangle or not.

     float colitionx = rayStart.x+t*directionVector.x;
                float colitiony = rayStart.y+t*directionVector.y;
                float colitionz = rayStart.z+t*directionVector.z;
                glm::vec3 colitionPoint(colitionx,colitiony,colitionz);
                cout << abs(triangleArea(data.at(i*3),data.at(i*3+1),data.at(i*3+2))-triangleArea(data.at(i*3),colitionPoint,data.at(i*3+2))-
                       triangleArea(data.at(i*3),colitionPoint,data.at(i*3+1))-triangleArea(data.at(i*3+1),colitionPoint,data.at(i*3+2))) << endl;
                if(abs(triangleArea(data.at(i*3),data.at(i*3+1),data.at(i*3+2))-triangleArea(data.at(i*3),colitionPoint,data.at(i*3+2))-
                       triangleArea(data.at(i*3),colitionPoint,data.at(i*3+1))-triangleArea(data.at(i*3+1),colitionPoint,data.at(i*3+2)))<0.1f)
                {
                    cout << "hit!!!\n";
                    return true;
                }

triangleArea is just the areal of the triangle where the first one is the big triangle(the one that i am checking), the rest are small triangles inside or outside of it, made by connecting the 3 points.

I forgot to mention that data.at(i) is the vectors of the points in the triangle(3 for each triangle)

TriangleArea:

    float MainWindow::triangleArea(glm::vec3 coordinatep1, glm::vec3 coordinatep2, glm::vec3 coordinatep3)
    {
    float lengthP1P2=sqrt((coordinatep2.x-coordinatep1.x)*(coordinatep2.x-coordinatep1.x)+
                      (coordinatep2.y-coordinatep1.y)*(coordinatep2.y-coordinatep1.y)+
                      (coordinatep2.z-coordinatep1.z)*(coordinatep2.z-coordinatep1.z));
    float lengthP2P3=sqrt((coordinatep3.x-coordinatep2.x)*(coordinatep3.x-coordinatep2.x)+
                      (coordinatep3.y-coordinatep2.y)*(coordinatep3.y-coordinatep2.y)+
                      (coordinatep3.z-coordinatep2.z)*(coordinatep3.z-coordinatep2.z));
    float lengthP3P1=sqrt((coordinatep1.x-coordinatep3.x)*(coordinatep1.x-coordinatep3.x)+
                      (coordinatep1.y-coordinatep3.y)*(coordinatep1.y-coordinatep3.y)+
                      (coordinatep1.z-coordinatep3.z)*(coordinatep1.z-coordinatep3.z));
    float area = (lengthP1P2+lengthP2P3+lengthP3P1)/2;
    return (sqrt(area*(area-lengthP1P2)*(area-lengthP2P3)*(area-lengthP3P1)));
    }
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • Firstly, you will have to get the ray using the camera position and the pixel position the user clicked in the near place. Afterwards, you will have to apply the inverse of the transformation (camera + projection) in order to have the ray in the same coordinate system as the triangles. – wendelbsilva Nov 26 '13 at 23:46
  • Theres another old approach to do picking using colors and 2 passes. First pass you give 1 color to each triangle (need to set distinct colors to all triangles). Then, you render to texture and check the color at the position the user clicked. Ofcourse, this approach can be easy but theres some problems on it. – wendelbsilva Nov 26 '13 at 23:47
  • The problem is, if two of the triangles have the same color(ie if the user clicks a color then clicks 2 triangles) it will start grouping those together. – Thomas E. Y. Lund Nov 26 '13 at 23:50
  • Thats correct, for that solution the number of colors are limited to the combination of different RxGxB. – wendelbsilva Nov 26 '13 at 23:54
  • BTW, for the picking using ray, after finding the ray you need to remove the transformation (camera transformation + projection) using the inverse of the matrix. I have to go now you there are some questions in SO that you can see some explanations. Like this [one](http://stackoverflow.com/questions/2093096/implementing-ray-picking). gl; – wendelbsilva Nov 26 '13 at 23:57

0 Answers0