【问题标题】:Ray-picking in OpenGL ES 2.0OpenGL ES 2.0 中的光线拾取
【发布时间】:2012-12-20 13:15:31
【问题描述】:

我正在尝试在 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]);

}

x 和 y 浮点数是手指按下屏幕位置的 x 和 y 坐标。从MainActivity调用函数onClick。

在

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

mMVPMatrix 是模型视图矩阵。 mProjectionMatrix 是投影矩阵,viewport 的值是 {0,0,screenhwidth,screenheight}。

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

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

我的问题/主题是我不知道我是否走在正确的轨道上?我是否得到了正确的想法,或者我似乎误解了什么? 或者有没有其他方法可以实现对三角形的触摸检测?

感谢您的帮助或指导!

【问题讨论】:

  • 只看一些样本坐标我无法告诉你你的结果是否正确。

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


【解决方案1】:

有一个出色的 Android OpenGL 框架,名为 Rajawali。支持物体拾取,the sample code看起来很简单,你可以试试。

【讨论】:

  • 感谢您的回复,但我希望能够自己实现一些东西,而不需要使用 Android API 提供的其他框架:)
【解决方案2】:

我相信你们很多人都误解了一点(或者我可能有^^)。近坐标和远坐标用于构建您的光线段以针对您的多边形/命中框进行测试。该段位于所谓的world space 中,要针对您的顶点/模型进行测试,您需要通过将它们乘以它们的 mModelView 矩阵(具有它们的所有变换)将它们从模型空间(加载时它们所在的位置)转换为世界空间,旋转等)。您链接的那篇文章似乎已经理解了这一点^^ 有道理还是我错过了什么?

给你的奖励链接:http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter0.htm

【讨论】:

  • 是的,但是 x 和 y 坐标来自触摸事件。那应该是什么模型矩阵?这让我有点困惑......
  • 您不需要模型矩阵。那是在世界空间中。您需要使用模型视图矩阵将您正在测试的网格数据转换为世界空间。^^(来自您链接的示例的matrixGrabber.mModelView)
  • 感谢您的回复,好久没上网了...所以你的意思是我只要把三角形的坐标转换到世界空间,然后检查手指触摸是否与那个?
  • 基本上^^ 你得到的近和远坐标是世界空间中“触摸射线”的开始和结束,所以你应该能够将你的模型/三角形移动到世界空间和然后测试射线段是否与它相交并且鲍勃是你的叔叔!^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
相关资源
最近更新 更多