Обнаружение касания объекта OpenGL?

Я разрабатываю приложение, которое использует OpenGL для рендеринга изображений.

Теперь я просто хочу определить событие касания на объекте сферы opengl, который я вынул.

Здесь я рисую 4 объекта на экране. теперь, как мне узнать, какой объект был

прикосновения. Я использовал метод onTouchEvent(). Но он дает мне только координаты x и y, но мой

объект рисуется в 3D.

пожалуйста, помогите, так как я новичок в OpenGL.

С наилучшими пожеланиями, ~ Anup enter image description here

Ответ 1

t В Google IO была сессия о том, как OpenGL использовался для Google Body на Android. Выбор частей тела был сделан путем рендеринга каждого из них сплошным цветом в скрытый буфер, а затем на основе цвета, который был на касании x, y соответствующий объект мог быть найден. В целях производительности только небольшая обрезанная область размером 20x20 пикселей вокруг точки касания была сделана таким образом.

Ответ 2

Оба подхода (1. скрытый цветовой буфер и 2. тест пересечения) имеют свои достоинства. 1. Скрытый буфер цвета: считывание пикселей - очень медленная операция. Конечно, переполнение для простого теста пересечения лучей.

  • Тест пересечения лучей с шаром: это не так сложно. Вот упрощенная версия реализации в Ogre3d.

    std::pair<bool, m_real> Ray::intersects(const Sphere& sphere) const
     {
    const Ray& ray=*this;
    const vector3& raydir = ray.direction();
    // Adjust ray origin relative to sphere center
    const vector3& rayorig = ray.origin() - sphere.center;
    m_real radius = sphere.radius;
    
    // Mmm, quadratics
    // Build coeffs which can be used with std quadratic solver
    // ie t = (-b +/- sqrt(b*b + 4ac)) / 2a
    m_real a = raydir%raydir;
    m_real b = 2 * rayorig%raydir;
    m_real c = rayorig%rayorig - radius*radius;
    
    // Calc determinant
    m_real d = (b*b) - (4 * a * c);
    if (d < 0)
    {
        // No intersection
        return std::pair<bool, m_real>(false, 0);
    }
    else
    {
        // BTW, if d=0 there is one intersection, if d > 0 there are 2
        // But we only want the closest one, so that ok, just use the
        // '-' version of the solver
        m_real t = ( -b - sqrt(d) ) / (2 * a);
        if (t < 0)
        t = ( -b + sqrt(d) ) / (2 * a);
        return std::pair<bool, m_real>(true, t);
    }
    

    }

Возможно, необходимо также рассчитать луч, который соответствует позиции курсора. Снова вы можете обратиться к исходному коду Ogre3d: поиск getCameraToViewportRay. В принципе, вам нужна матрица зрения и проекции для вычисления луча (трехмерное положение и трехмерное направление) из 2D-положения.

Ответ 3

В моем проекте решение, которое я выбрал, было:

  • Непроектируйте координаты 2D-экрана виртуальной 3D-линии, проходящей через вашу сцену.
  • Обнаружение возможных пересечений этой линии и объектов сцены.

Это довольно сложный вкус.

Ответ 4

Я сделал это только в Direct3D, а не в OpenGL ES, но это следующие шаги:

  • Найдите ваши модели и проекционные матрицы. Кажется, что OpenGL ES удалил возможность извлекать матрицы, установленные gluProject() и т.д. Но вы можете использовать функции android.opengl.Matrix для создания этих матриц, затем установите с помощью glLoadMatrix().

  • Вызовите gluUnproject() дважды, один раз с winZ = 0, затем с winZ = 1. Передайте ранее вычисленные матрицы.

  • Это выведет 3D позицию из каждого вызова. Эта пара позиций определяет луч в "глобальном пространстве" OpenGL.

  • Выполняйте тест пересечения лучей с шаром по каждой из ваших сфер в порядке. (Ближе всего к камере, иначе вы можете выбрать сферу, которая скрыта за другим.) Если вы обнаружите пересечение, вы коснулись сферы.

Ответ 5

для нахождения точки касания внутри круга или нет.

public boolean checkInsideCircle(float x,float y, float centerX,float centerY, float Radius)
    {
        if(((x - centerX)*(x - centerX))+((y - centerY)*(y - centerY)) < (Radius*Radius))
            return true;
        else
            return false;
    }

где

1) centerX,centerY are center point of circle.
2) Radius is radius of circle.
3) x,y point of touch..