我有一个玩家对象在屏幕上移动。相机是一个固定的相机,俯视播放器(如暗黑破坏神)。
现在我希望播放器对象朝向鼠标光标旋转。播放器并不总是位于屏幕的中心(对于这种情况,我已经有了解决方案)。 为了做到这一点,我想我需要将鼠标光标投射到我的播放器所在的相同高度(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)前面/后面? (我知道球员的位置)
我的错误在哪里?
答案 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;