OpenGL Unjectject鼠标光标找到某个对象的相对位置?

时间:2018-01-17 12:04:52

标签: c# opengl coordinates mouse opentk

我有一个玩家对象在屏幕上移动。相机是一个固定的相机,俯视播放器(如暗黑破坏神)。

现在我希望播放器对象朝向鼠标光标旋转。播放器并不总是位于屏幕的中心(对于这种情况,我已经有了解决方案)。 为了做到这一点,我想我需要将鼠标光标投射到我的播放器所在的相同高度(y轴)(y轴是"向上"在我的游戏中)然后检查比较玩家位置,光标位置在世界空间中的相同高度。

到目前为止,我的未投影方法如下所示:

private bool Unproject(float winX, float winY, float winZ, out Vector3 position)
{
    position = Vector3.Zero;
    Matrix4 transformMatrix = Matrix4.Invert(World.CurrentWindow.GetViewMatrix() * World.CurrentWindow.GetProjectionMatrix());

    Vector4 inVector = new Vector4(
        (winX - World.CurrentWindow.X) / World.CurrentWindow.Width * 2f - 1f, 
        (winY - World.CurrentWindow.Y) / World.CurrentWindow.Height * 2f - 1f, 
        2f * winZ - 1f, 
        1f
        );

    Matrix4 inMatrix = new Matrix4(inVector.X, 0, 0, 0, inVector.Y, 0, 0, 0, inVector.Z, 0, 0, 0, inVector.W, 0, 0, 0);
    Matrix4 resultMtx = transformMatrix * inMatrix;
    float[] resultVector = new float[] { resultMtx[0, 0], resultMtx[1, 0], resultMtx[2, 0], resultMtx[3, 0] };
    if (resultVector[3] == 0)
    {
        return false;
    }
    resultVector[3] = 1f / resultVector[3];
    position = new Vector3(resultVector[0] * resultVector[3], resultVector[1] * resultVector[3], resultVector[2] * resultVector[3]);

    return true;
}

现在我为近平面(winZ = 0)和远平面(winZ = 1)取消投影鼠标光标一次。

protected Vector3 GetMouseRay(MouseState s)
{
    Vector3 mouseposNear = new Vector3();
    Vector3 mouseposFar = new Vector3();
    bool near = Unproject(s.X, s.Y, 0f, out mouseposNear);
    bool far  = Unproject(s.X, s.Y, 1f, out mouseposFar);
    Vector3 finalRay = mouseposFar - mouseposNear;
    return finalRay;
}

我的问题是:

我如何知道值是否正确。 " finalRay"中的值矢量非常小 - 总是如此。我原本以为我会得到更大的z值,因为我的近平面(透视投影)是0.5f而我的远平面是1000f。

如何判断鼠标光标是左/右(-x,+ x)还是在(-z,+ z)前面/后面? (我知道球员的位置)

我的错误在哪里?

1 个答案:

答案 0 :(得分:0)

  

如何判断鼠标光标是左/右(-x,+ x)还是在(-z,+ z)前面/后面?

以相反的方向做。将播放器的位置投影到屏幕上。因此,您可以轻松地将播放器的位置与鼠标位置进行比较:

// positon of the player in world coordinates
Vector3 p_ws ....; 

// positon of the player in view space
Vector4 p_view = World.CurrentWindow.GetViewMatrix() * Vector4(p_ws.X, p_ws.Y, p_ws.Z, 1.0);

// postion of the player in clip space (Homogeneous coordinates)
Vector4 p_clip = World.CurrentWindow.GetProjectionMatrix() * p_view;

// positon of the player in normailzed device coordinates (perspective divide)
Vec3 posNDC = new Vector3(p_clip.X / p_clip.W, p_clip.Y / p_clip.W, p_clip.Z / p_clip.W);  

// screen position in pixel
float p_screenX = (posNDC.X * 0.5 + 0.5) * World.CurrentWindow.Width;
float p_screenY = (posNDC.Y * 0.5 + 0.5) * World.CurrentWindow.Height;