我为每个世界,视图和投影变换都有一个SlimDX矩阵。根据{{3}},投影变换将坐标保留在(-1,1)^ 3立方体中。
我认为通过将相对于渲染目标的鼠标位置转换为投影空间(即将其缩放到(-1,1)范围并将其固定在z轴上的-1)然后应用反转的世界观投影。
以下代码显示了我的尝试。我的测试是运行应用程序并使用鼠标滚轮放大和缩小,看看打印的X坐标是否改变,同时将鼠标光标保持在窗口的左边缘 - 它不会在某处出现错误。
form.MouseMove += (obj, eargs) =>
{
SlimDX.Matrix worldview = SlimDX.Matrix.Multiply(SlimDX.Matrix.Identity, viewMatrix);
SlimDX.Matrix worldviewprojection = SlimDX.Matrix.Multiply(worldview, projectionMatrix);
worldviewprojection.Invert();
var pointX = (float)((2.0 * ((float)eargs.Location.X) / (float)form.Width) - 1.0f);
var pointY = (float)((2.0 * (((float)eargs.Location.Y) / (float)form.Height)) - 1.0f) * -1.0f;
var mouseInProjectionSpace = new Vector4(pointX, pointY, -1.0f, 1.0f);
var mouseInWorldSpace = Vector4.Transform(mouseInProjectionSpace, worldviewprojection);
Console.WriteLine(mouseInWorldSpace);
};
form.MouseWheel += (_, __) =>
{
if (__.Delta > 0)
cam.Z /= 2.0f;
else
cam.Z *= 2.0f;
viewMatrix = GetView(cam);
Console.WriteLine("zzz="+cam.Z);
};
任何帮助表示赞赏
答案 0 :(得分:0)
你的z错了,因为在投影空间z是0(近平面)到1(远平面)
所以它确实:
Vector2 mouse = //Normalized as -1 to 1 (as you did)
Vector3 orig = new Vector3(mouse.X,mouse.Y,0.0f);
Vector3 far = new Vector3(mouse.X,mouse.Y,1.0f);
//This gets mouse position on near plane
Vector3 origin = Vector3.TransformCoordinate(orig,worldviewprojectioninverse);
//This gets mouse position on far plane
Vector3 posfar = Vector3.TransformCoordinate(far,worldviewprojectioninverse);