在OpenGL ES 2.0中进行射线挑选

时间:2013-01-06 18:24:22

标签: android opengl-es-2.0 ray-picking

我正在尝试在OpenGL ES 2.0中实现光线拾取,以确定是否已单击某个对象。到目前为止,我只是想检查是否按下了特定的三角形。 我正在使用此网站作为动机http://android-raypick.blogspot.ca/2012/04/first-i-want-to-state-this-is-my-first.html

这是我到目前为止所做的:

public void onClick(float x, float y)
{
    float[] temp = new float[4];
    float[] temp2 = new float[4];
    System.out.println("X coordinate: " + x);
    System.out.println("Y coordinate: " + y);
    float[] pos = new float[4];

    y = (float) viewport[3] - y;

    int res = GLU.gluUnProject(x, y, 1.0f, 
            mMVPMatrix, 0,
            mProjectionMatrix, 0,
            viewport, 0, 
            temp, 0);

    Matrix.multiplyMV(temp2, 0, mMVPMatrix, 0, temp, 0);
    float[] nearCoOrds = new float[3];

    if(res == GLES20.GL_TRUE)
    {
        nearCoOrds[0] = temp2[0] / temp2[3];
        nearCoOrds[1] = temp2[1] / temp2[3];
        nearCoOrds[2] = temp2[2] / temp2[3];
        System.out.println("Near0: " + nearCoOrds[0]);
        System.out.println("Near1: " + nearCoOrds[1]);
        System.out.println("Near2: " + nearCoOrds[2]);
    }

    res = GLU.gluUnProject(x, y, 0,
            mMVPMatrix, 0,
            mProjectionMatrix, 0,
            viewport, 0,
            temp, 0);

    Matrix.multiplyMV(temp2,0,mMVPMatrix, 0, temp, 0);
    float[] farCoOrds = new float[3];

    if(res == GLES20.GL_TRUE)
    {
        farCoOrds[0] = temp2[0] / temp2[3];
        farCoOrds[1] = temp2[1] / temp2[3];
        farCoOrds[2] = temp2[2] / temp2[3];
        System.out.println("Far0: " + farCoOrds[0]);
        System.out.println("Far1: " + farCoOrds[1]);
        System.out.println("Far2: " + farCoOrds[2]);
    }

    float[] coords = new float[3];

    coords[0] = farCoOrds[0]-nearCoOrds[0];
    coords[1] = farCoOrds[1]-nearCoOrds[1];
    coords[2] = farCoOrds[2]-nearCoOrds[2];

    System.out.println("REAL COORDS 0: " + coords[0]);
    System.out.println("REAL COORDS 1: " + coords[1]);
    System.out.println("REAL COORDS 2: " + coords[2]);

}

xy浮点数是手指按下屏幕的x和y坐标。函数onClickMainActivity

调用

 GLU.gluUnProject(x, y, 1.0f, 
            mMVPMatrix, 0,
            mProjectionMatrix, 0,
            viewport, 0, 
            temp, 0);

mMVPMatrix是Modelview矩阵。 mProjectionMatrix是投影矩阵,viewport的值为{0,0,screenhwidth,screenheight}。

我得到的输出示例(触摸屏幕中间):

REAL COORDS 0: -0.21542415
REAL COORDS 1: 0.31117013
REAL COORDS 2: 9.000003

我的问题/主题是我不知道我是否在正确的轨道上?我有没有正确的想法,或者看起来我误解了什么? 或者还有其他方法可以在三角形上实现触摸检测吗?

感谢您提供任何帮助或指导!

2 个答案:

答案 0 :(得分:1)

Android版有一个优秀的OpenGL框架Rajawali。它支持对象选择,the sample code看起来很简单,你应该尝试一下。

答案 1 :(得分:0)

我相信很多人误解了一下(或许我有^^)。 near和far坐标用于构建光线段以针对您的多边形/命中框进行测试。该片段名为world space,为了测试您的顶点/模型,您需要将它们从模型空间(它们在加载时所处的位置)转换为世界空间,方法是将它们与mModelView矩阵相乘(具有全部它们的变形,旋转等)。你链接的那篇文章似乎是通过这一点^^有意义还是我错过了什么?

奖金链接:http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter0.htm