使用OpenTK将屏幕点转换为世界点

时间:2017-10-02 09:01:41

标签: c# .net opengl graphics opentk

我正在尝试使用OpenTK制作2D画布。为此,我将相机眼睛放在点(0,0,100),我已将相机目标位置设置为(0,0,0),将相机向上矢量设置为(0,1,0)。此外,我有一些轴来帮助可视化。结果可以在下一张图片中看到:

2D canvas

我只允许两个动作:

  • 放大/缩小:我只是更改相机眼睛的Z分量
  • 水平位移:我更改了相机眼睛和目标
  • 的X分量

此时一切正常。现在,当我点击屏幕时,我得到一个2D点,​​我想要更改为我的世界空间坐标。为此,我构建了一个透视矩阵和一个视图矩阵:

Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / (float)6.0, 1, 0.1f, 1000f);

Matrix4 view = LookAt(Vector3 eye, Vector3 target, Vector3 up);

public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up)
    {
        Vector3 f = (target - eye).Normalize();
        Vector3 s = f.Cross(up).Normalize();
        Vector3 u = s.Cross(f).Normalize();

        Matrix4 rotation = new Matrix4(
             s.X,  s.Y,  s.Z, 0.0,
             u.X,  u.Y,  u.Z, 0.0,
            -f.X, -f.Y, -f.Z, 0.0,
             0.0,  0.0,  0.0, 1.0);
        Matrix4 translation = new Matrix4(
            1.0, 0.0, 0.0, -eye.X,
            0.0, 1.0, 0.0, -eye.Y,
            0.0, 0.0, 1.0, -eye.Z,
            0.0, 0.0, 0.0, 1.0);
        return rotation * translation;
    }

现在我有两个矩阵,我尝试使用下一个代码将我的屏幕坐标转换为我的世界坐标:

view.Transpose(); // Apparently openGl works with the transpose of the view
Vector3 point = new Vector3(e.Point.X, e.Point.Y, 0);
Vector4 worldPoint = UnProject(ref perspective, ref view, ref size, point);

private static Vector4 UnProject(ref Matrix4 projection, ref Matrix4 view, ref Size viewport, Vector3 mouse)
    {
        Vector4 vec;

        vec.X = 2f * mouse.X / (float)viewport.Width - 1;
        vec.Y = -(2f * mouse.Y / (float)viewport.Height - 1);
        vec.Z = 2f * mouse.Z - 1f;
        vec.W = 1f;

        Matrix4 viewInv = Matrix4.Invert(view);
        Matrix4 projInv = Matrix4.Invert(projection);

        Vector4.Transform(ref vec, ref projInv, out vec);
        Vector4.Transform(ref vec, ref viewInv, out vec);

        vec.X /= vec.W;
        vec.Y /= vec.W;
        vec.Z /= vec.W;

        return vec;
    }

进行一些测试,我已经意识到它对屏幕的中心点有效(它总是点[Eye.X,0]),但它不适用于其他点。

此外,看起来变换后的点不会随缩放而缩放。如果我不移动屏幕的中心,屏幕的边缘总是具有相同的值(如果我缩小很多,边缘之间的差异应该比放大时大得多)。

修改

我的问题已被标记为可能重复,但该帖子正在解决另一个问题。此外,该问题的链接已被打破,已超过5年。

0 个答案:

没有答案