0
\$\begingroup\$

I'm not sure if 'reconstruct' is the correct term for this but essentially what I am trying to do is calculate vertex positions (that are already calculated via shader) on the CPU for the purpose of ray tracing. I need to know the locations of the models so I can detect if my ray passes through them. It would be nice if I could retrieve the values from memory after the the shader has calculated them but it doesn't seem possible - or advisable.
What I have so far looks like it should work but when I trace my ray (that does pass directly through the model) none of the vertices fall inside the model.

Create the ray (Tested by drawing a line between far/near and it works fine):

public float[] getPickingVector(float[] modelview,
                                float[] projection,
                                int[] viewport,
                                float winX,
                                float winY) throws Exception {

    float[] mat4Tmp1 = new float[16];
    float[] mat4Tmp2 = new float[16];
    float[] vec4Tmp2 = new float[4];

    FloatUtil.mapWinToObjCoords(winX, winY, 0, modelview, 0, 
            projection, 0, 
            viewport, 0, 
            nearVector, 0, 
            mat4Tmp1, mat4Tmp2);

    FloatUtil.mapWinToObjCoords(winX, winY, 1, modelview, 0, 
            projection, 0, 
            viewport, 0, 
            farVector, 0, 
            mat4Tmp1, mat4Tmp2);

    // save the results in a vector, far-near
    destVector[0] = farVector[0] - nearVector[0];
    destVector[1] = farVector[1] - nearVector[1];
    destVector[2] = farVector[2] - nearVector[2];

    return destVector;
}

'Reconstruct' the model vertices by reading back the values of the vertex buffer that are keyed on the index buffer. I have stepped through the loop and the code does read back the vertex buffer values in the correct order:

//check by pairs of triangles that create a square.
public boolean findIntersection(Wh w, float[] mvp){

    float[] a = new float[4];
    float[] b = new float[4];
    float[] c = new float[4];

    boolean rslt = false;

    //init boundary vars.
    float[] tmp = {-2000,-2000,-2000};
    float[] tmp2 = {2000,2000,2000};


    //loop thru each triangle.  Arrays a,b and c each represent
    //a vertex of one triangle.  The are 12 in total creating a
    //box.
    for ( int i = 0; i < w.idxBuffer.length; i += 3  ){
         a[0] = w.vertBuffer[ (w.idxBuffer[i + 0] * 3) + 0];
         a[1] = w.vertBuffer[ (w.idxBuffer[i + 0] * 3) + 1];
         a[2] = w.vertBuffer[ (w.idxBuffer[i + 0] * 3) + 2];
         b[0] = w.vertBuffer[ (w.idxBuffer[i + 1] * 3) + 0];
         b[1] = w.vertBuffer[ (w.idxBuffer[i + 1] * 3) + 1];
         b[2] = w.vertBuffer[ (w.idxBuffer[i + 1] * 3) + 2];
         c[0] = w.vertBuffer[ (w.idxBuffer[i + 2] * 3) + 0];
         c[1] = w.vertBuffer[ (w.idxBuffer[i + 2] * 3) + 1];
         c[2] = w.vertBuffer[ (w.idxBuffer[i + 2] * 3) + 2];
         a[3] = 1;
         b[3] = 1;
         c[3] = 1;

         //****Here is where I suspect my problem is **********
         //To rebuild the vertices I multiply the vertex from the 
         //vertex buffer by the model/view/projection matrix, mimicking
         //what is done in the shader:
         //      gl_Position = MVP * vec4(VertexPosition,1.0);
         //My hope is that this will provide me with the correct positioning
         //of the model so the ray trace will work.
         FloatUtil.multMatrixVec(mvp, a, am);
         FloatUtil.multMatrixVec(mvp, b, bm);
         FloatUtil.multMatrixVec(mvp, c, cm);

         //The following creates max/min boundaries used to test for
         //a point being inside the box.
         //high x values
         if (tmp[0] < am[0]){tmp[0] = am[0];}
         if (tmp[0] < bm[0]){tmp[0] = bm[0];}
         if (tmp[0] < cm[0]){tmp[0] = cm[0];}

        //high y values
         if (tmp[1] < am[1]){tmp[1] = am[1];}
         if (tmp[1] < bm[1]){tmp[1] = bm[1];}
         if (tmp[1] < cm[1]){tmp[1] = cm[1];}

        //high z values
         if (tmp[2] < am[2]){tmp[2] = am[2];}
         if (tmp[2] < bm[2]){tmp[2] = bm[2];}
         if (tmp[2] < cm[2]){tmp[2] = cm[2];}

         //low x values
         if (tmp2[0] > am[0]){tmp2[0] = am[0];}
         if (tmp2[0] > bm[0]){tmp2[0] = bm[0];}
         if (tmp2[0] > cm[0]){tmp2[0] = cm[0];}

        //low y values
         if (tmp2[1] > am[1]){tmp2[1] = am[1];}
         if (tmp2[1] > bm[1]){tmp2[1] = bm[1];}
         if (tmp2[1] > cm[1]){tmp2[1] = cm[1];}

        //low z values
         if (tmp2[2] > am[2]){tmp2[2] = am[2];}
         if (tmp2[2] > bm[2]){tmp2[2] = bm[2];}
         if (tmp2[2] > cm[2]){tmp2[2] = cm[2];}

    }

    //The following traces the ray until one of the points falls
    //within the boundaries of the box.
    float fract = (nearClippingDistance / (farClippingDistance));

    System.out.println("x:" + tmp[0] + "  " + tmp2[0]);
    System.out.println("y:" + tmp[1] + "  " + tmp2[1]);
    System.out.println("z:" + tmp[2] + "  " + tmp2[2]);
    //boolean init = false;

    float idx = 0;
    float[] mult = new float[3];
    float[] t = new float[3];
    for (idx = fract; idx <= 1; idx += fract) {
        mult[0] = farVector[0] * idx;
        mult[1] = farVector[1] * idx;
        mult[2] = farVector[2] * idx;
        VectorUtil.addVec3(t, nearVector, mult);

        System.out.println("x:" + t[0] + "  y:" + t[1] + "  z:" + t[2]);

        if (((t[0] <= tmp[0]) && (t[0] >= tmp2[0])) && 
            ((t[1] <= tmp[1]) && (t[1] >= tmp2[1])) && 
            ((t[2] <= tmp[2]) && (t[2] >= tmp2[2]))){
            //ray intersects this box.
            rslt = true;

        }
    }  

    return rslt;

}

I have also tried many open source libraries that provide bounding box detecting / plane intersection / ray tracing but none of them work I think because my vertex values are somehow incorrect. Does anyone see a problem with what I am doing here?

\$\endgroup\$
4
\$\begingroup\$

It would be nice if I could retrieve the values from memory after the the shader has calculated them but it doesn't seem possible - or advisable

But, it IS possible, and I would advise it:

https://www.opengl.org/wiki/Transform_Feedback

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.