Я видел эту же тему, обсуждаемую в другом месте, но в большинстве случаев поставщик решений имеет дело с 2D (орто) проекцией, поэтому они затеняют значение Z.Мой мир обладает следующими характеристиками:
- Перспективная проекция
- Вектор "вверх" камеры всегда равен {0, 1, 0}
- Координата Z камеры всегдаположительный (смотрит в сторону Z = 0)
- Плоскость, в которой я пытаюсь определить точку попадания, равна 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;
}