- Вам необходимо снять проекцию 2D экранные координаты в 3D координаты в пространстве.
- Вам нужно решить систему уравнений, чтобы найти реальную точку в 3D из 3 лучей, которые вы получили на первом шаге.
Вы можете найти исходный код для gluUnProject
здесь . Я также привожу здесь свой код:
public Vector4 Unproject(float x, float y, Matrix4 View)
{
var ndcX = x / Viewport.Width * 2 - 1.0f;
var ndcY = y / Viewport.Height * 2 - 1.0f;
var invVP = Matrix4.Invert(View * ProjectionMatrix);
// We don't z-coordinate of the point, so we choose 0.0f for it.
// We are going to find out it later.
var screenPos = new Vector4(ndcX, -ndcY, 0.0f, 1.0f);
var res = Vector4.Transform(screenPos, invVP);
return res / res.W;
}
Vector3 ComputeRay(Camera camera, Vector2 p)
{
var worldPos = Unproject(p.X, p.Y, camera.View);
var dir = new Vector3(worldPos) - camera.Eye;
return new Ray(camera.Eye, Vector3.Normalize(dir));
}
Теперь вам нужно найти пересечение трех таких лучей. Теоретически этого было бы достаточно, чтобы использовать только два луча. Это зависит от положения ваших камер.
Если бы у нас была арифметика с плавающей запятой бесконечной точности и ввод был без шума, это было бы тривиально. Но в действительности вам может понадобиться использовать простую числовую схему, чтобы найти точку с соответствующей точностью.