OpenGL 取消投影鼠标光标以查找与某个对象的相对位置?

OpenGL Unprojecting mouse cursor to find relative position to a certain object?

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

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

中的相同高度

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

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" Vector 中的值非常小 - 总是。我本以为我会得到更大的 z 值,因为我的近平面(透视投影)是 0.5f 而我的远平面是 1000f。

我怎样才能知道鼠标光标是 left/right (-x, +x) 还是 behind/in 播放器 (-z, +z) 前面? (我知道玩家的位置)

我的错误在哪里?

And how can I find out if the mouse cursor is left/right (-x, +x) or behind/in front of (-z, +z) the player?

反方向做。将玩家的位置投射到屏幕上。所以你可以很容易地比较玩家的位置和鼠标的位置:

// 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;