OpenGL ES (MonoTouch) - ручная реализация борьбы gluUnProject - PullRequest
0 голосов
/ 18 апреля 2011

Я видел эту же тему, обсуждаемую в другом месте, но в большинстве случаев поставщик решений имеет дело с 2D (орто) проекцией, поэтому они затеняют значение Z.Мой мир обладает следующими характеристиками:

  1. Перспективная проекция
  2. Вектор "вверх" камеры всегда равен {0, 1, 0}
  3. Координата Z камеры всегдаположительный (смотрит в сторону Z = 0)
  4. Плоскость, в которой я пытаюсь определить точку попадания, равна Z = 0

Я использую порт gluUnProject, и покаЯ думаю, что моя реализация порта является разумной, возможно, что-то не так с этим.Что я хотел спросить у сообщества, так это то, выглядит ли мой алгоритм ниже.Я определяю мировые координаты при winZ = 0 (ближняя плоскость) и при winZ = 1 (дальняя плоскость).Затем я определяю луч из этих двух точек, нормализуя его, и определяя, при каком значении 't' координата Z этого луча будет равна 0 (в какой точке он пересекает плоскость Z = 0, и это то, что мне нужно),Проблема, однако, заключается в том, что когда я щелкаю около источника (0,0,0), это работает, но как только я начинаю щелкать вдали от источника, ошибка возрастает (например, если правильные мировые координаты должны быть 50, 0, 0 на самом деле это 85, 0, 0. На основании приведенных ниже вычислений.

Если эта процедура ниже, то я могу начать исследовать мою реализацию gluUnProject.

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    var pt = (touches.AnyObject as UITouch).LocationInView(this);

    int[] viewport = new int[4];
    float[] proj = new float[16];
    float[] model = new float[16];

    GL.GetInteger(All.Viewport, viewport);
    GL.GetFloat(All.ProjectionMatrix, proj);
    GL.GetFloat(All.ModelviewMatrix, model);

    float[] near = new float[3];
    float[] far = new float[3];

    Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 0f, model, proj, viewport, out near);
    Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 1f, model, proj, viewport, out far);

    Vector rayDirection = new Vector(far[0] - near[0], far[1] - near[1], far[2] - near[2]);
    rayDirection.Normalize();

    float t = (0 - near[2]) / rayDirection.dZ;

    Vertex end = new Vertex();
    end.X = near[0] + rayDirection.dX * t;
    end.Y = near[1] + rayDirection.dY * t;
    end.Z = 0;
}

1 Ответ

0 голосов
/ 19 апреля 2011

Я реализовал тот же алгоритм с полной версией OpenGL (в комплекте с gluUnProject) и получил желаемый результат. Алгоритм здоров, моя реализация gluUnProject - нет.

...