Выбор лучей в OpenGL ES 2.0

Я пытаюсь реализовать выбор лучей в 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 того места, где палец нажимал на экран. Функция onClick вызывается из файла MainActivity.

In

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

mMVPMatrix — это матрица представления модели. mProjectionMatrix — это матрица проекции, а viewport имеет значения {0,0,ширина экрана,высота экрана}.

Пример вывода, который я получаю (прикоснулся к середине экрана):

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

Мой вопрос/тема в том, что я не знаю, на правильном ли я пути? Я правильно понял или мне кажется, что я что-то не так понял? Или есть другие способы добиться обнаружения касания треугольников?

Спасибо за любую помощь или руководство!


person Araw    schedule 06.01.2013    source источник
comment
Глядя только на некоторые выборочные координаты, я не могу сказать, правильны ли ваши результаты.   -  person keaukraine    schedule 15.01.2013


Ответы (2)


Существует отличная платформа OpenGL для Android, которая называется Rajawali. Он поддерживает выбор объектов, пример кода выглядит очень просто, попробуйте.

person molnarm    schedule 12.01.2013
comment
Спасибо за ваш ответ, но я надеялся, что смогу реализовать что-то самостоятельно, без использования другого фреймворка, кроме того, что предлагается в Android API :) - person Araw; 13.01.2013

Я полагаю, что многие из вас немного неправильно поняли (или, может быть, я ^^). Ближние и дальние координаты используются для построения вашего сегмента луча для тестирования ваших полигонов/хитбоксов. Сегмент находится в так называемом мировом пространстве и для проверки ваших вершин/моделей вам нужно будет преобразовать их из пространства модели (в котором они находятся при загрузке) в мировое пространство, умножив их на их матрицу mModelView (в ней есть все их преобразования, повороты и т. д.). Эта статья, на которую вы ссылаетесь, кажется, проходит через этот момент ^^ Имеет смысл или я что-то пропустил?

бонусная ссылка для вас: http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter0.htm

person Matthew Clark    schedule 15.01.2013
comment
Да, но координаты x и y взяты из события касания. Какой должна быть модельная матрица для этого? Вот это меня немного смущает... - person Araw; 15.01.2013
comment
Для этого вам не нужна модельная матрица. То есть в мировом пространстве. Вам нужно преобразовать данные сетки, которые вы тестируете, в мировое пространство, используя его матрицу просмотра модели. ^^ (matrixGrabber.mModelView из приведенного вами примера) - person Matthew Clark; 16.01.2013
comment
Спасибо за ваш ответ, какое-то время не был в сети ... То есть вы имеете в виду, что мне нужно только преобразовать координаты треугольника в мировое пространство, а затем проверить, пересекается ли с ним касание пальца? - person Araw; 18.01.2013
comment
в основном ^^ Ближние и дальние координаты, которые вы получаете, являются началом и концом сенсорного луча в мировом пространстве, поэтому вы должны иметь возможность перемещать свою модель/треугольник в мировое пространство, а затем проверять, пересекается ли сегмент луча с ним. а Боб твой дядя!^^ - person Matthew Clark; 19.01.2013