OpenGL ES 2.0 Ray Picking, дальняя точка

Помогите мне пожалуйста с лучевой сборкой

float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(35.0f), aspect, 0.1f, 1000.0f);

GLKMatrix4 modelViewMatrix = _mainmodelViewMatrix;


    // some transformations

_mainmodelViewMatrix = modelViewMatrix;

_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

_modelViewProjectionMatrix и _normalMatrix помещены в шейдер

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

и в конце касания

GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
                                             (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1)   ,  //1 - 2 * position.y / self.view.bounds.size.height,
                                               -1,
                                               1);
GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);


GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

Как я могу получить дальнюю точку? И моя ближняя точка верна или нет?

Спасибо!

2 ответа

Решение

Мы можем нарисовать линию от ближней к дальней точке.

  GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
                                                 (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1),  
                                                   -1,
                                                   1);

    GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);

    GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    near_point.v[3] = 1.0/near_point.v[3];
    near_point = GLKVector4Make(near_point.v[0]*near_point.v[3], near_point.v[1]*near_point.v[3], near_point.v[2]*near_point.v[3], 1);

    normalisedVector.z = 1.0;
    GLKVector4 far_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    far_point.v[3] = 1.0/far_point.v[3];
    far_point = GLKVector4Make(far_point.v[0]*far_point.v[3], far_point.v[1]*far_point.v[3], far_point.v[2]*far_point.v[3], 1);

Похоже у тебя

GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   -1, 1);

(phew) для вычисления нормализованных координат устройства ближайшей точки.

Чтобы получить дальнюю точку, просто поменяйте местами -1 координата Z для 1:

GLKVector4 normalisedFarVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   1, 1);

И примените то же самое обратное преобразование к этому. Это должно делать свое дело.

Фон: при нормальных обстоятельствах, окончательные координаты, полученные GL для превращения фрагмента в пиксель, являются так называемыми нормализованными координатами устройства. Они лежат в кубе, углы которого находятся в (-1,-1,-1_ и (1,1,1). Таким образом, центр экрана (0,0,z), верхний левый угол (-1,1,z) и т. Д. Координаты преобразуются таким образом, что точка, лежащая на ближней плоскости, будет иметь координату z, равную 1, а точка, лежащая непосредственно на дальней плоскости, будет иметь координату az, равную -1. Это числа, которые используются для проверки глубины, если она включена.

Так что, как вы можете догадаться, когда вы хотите преобразовать местоположение экрана обратно в точку в трехмерном пространстве, у вас на самом деле есть несколько точек на выбор - линия, фактически вытягивающаяся из ближней плоскости в дальнюю плоскость. В нормированных координатах устройства это линия, растягивающаяся от z=-1 до z=1. Итак, процесс идет так:

  • преобразовать координаты x и y в нормализованные координаты устройства x'и y'
  • Для каждого из z' = 1 и z' = -1:
    • преобразовать координаты в нормализованные координаты устройства ( формулу см. здесь)
    • применить обратную матрицу проекции
    • применить обратную матрицу модель / представление (как это было до любых преобразований для каждого объекта)

Результатом являются две координаты вашей линии в трехмерном пространстве.

Другие вопросы по тегам