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;
我有一个在屏幕上移动的播放器对象。摄像头是固定摄像头,俯视玩家(暗黑破坏神一样)。
现在我想让播放器对象向鼠标光标方向旋转。播放器并不总是在屏幕中央(对于这种情况我已经有了解决方案)。 为了做到这一点,我想我需要将鼠标光标投影到我的玩家所在的相同高度(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;