视野和坐标翻译

时间:2011-02-16 16:56:14

标签: c# graphics xna

在我的程序中,我有输入和输出。输入是2D位置,范围从(0,0)到(240,360)。我的输出是在XNA中生成的3D世界。

但是,我还没弄清楚如何将点从2D网格转换为3D。我希望能够转换点,以便(0,0)导致XNA显示相机可以看到的左上角的工作点。同样,我希望(240,360)的点出现在相机可以看到的右下角。 Z值将为零(它会改变,但这超出了这个问题的范围)。

如何判断相机视角的位置? 以下是我在3D世界中绘制对象的方法。

        Vector3 camPos = new Vector3(0.0f, 0.0f, 500.0f);

        Matrix view = Matrix.CreateLookAt(camPos, Vector3.Zero, Vector3.Up);
        Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.DisplayMode.AspectRatio, 1, 10000);
        Matrix ballWorld = Matrix.Identity;

        //rotate it so that it is always facing foward
        ballWorld.Forward = direction;
        ballWorld.Up = Vector3.Up;
        ballWorld.Right = Vector3.Cross(direction, Vector3.Up);

        foreach (SphereObject so in blobs) {
            Matrix sphereWorld = ballWorld;
            sphereWorld *= Matrix.CreateTranslation(so.Position);
            sphereWorld *= Matrix.CreateScale(so.Scale);

            so.SphereModel.Draw(sphereWorld, view, proj);
        }

这里我从2D平面获取点并创建SphereObject

    public void CreateNewBlob(System.Drawing.Point p) {
        Random rand = new Random();

        SphereObject so = new SphereObject(model, new Vector3(p.X, p.Y, 0));
        so.SetColor(new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble()));

        blobs.Add(so);
    }

2 个答案:

答案 0 :(得分:0)

如何将2D点映射到视口,然后从该点取消投影光线,并使用它根据远剪裁平面找到光线上最远的可见点?

        float farplane = 1000;

        Matrix proj = Matrix.CreateLookAt(Vector3.Zero, Vector3.Forward, Vector3.Up);
        Matrix view = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.GraphicsDevice.Viewport.AspectRatio, 1, farplane);

        Vector2 Coord = new Vector2(10,10);     //between 0,0 and 240,360

        Coord.X = Coord.X * (GraphicsDevice.Viewport.Width / 240);
        Coord.Y = Coord.Y * (GraphicsDevice.Viewport.Height / 360);

        Ray r = ProjectRayFromPointOnScreen((int)Coord.X, (int)Coord.Y, proj, view);

        Vector3 ballpos = r.Position + (r.Direction *= (farplane - 1)); //Move just inside the far plane so its not clipped by accident

    public Ray ProjectRayFromPointOnScreen(int x, int y, Matrix ProjectionMatrix, Matrix ViewMatrix)
    {
        Vector3 nearsource = new Vector3(x, y, 0);
        Vector3 farsource = new Vector3(x, y, 1);

        /* The Unproject method: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.viewport.unproject.aspx */

        GraphicsDevice graphics = this.GraphicsDevice;

        Vector3 startpoint = graphics.Viewport.Unproject(nearsource,
                                                         ProjectionMatrix,
                                                         ViewMatrix,
                                                         Matrix.Identity);
        Vector3 endpoint = graphics.Viewport.Unproject(farsource,
                                                       ProjectionMatrix,
                                                       ViewMatrix,
                                                       Matrix.Identity);

        Vector3 direction = endpoint - startpoint;
        direction.Normalize();

        Ray r = new Ray(startpoint, direction);
        return r;
    }

这似乎有效,但我不确定您在应用中尝试达到的效果。 祝你好运!

答案 1 :(得分:0)

您确定不想使用orthographic projection吗?

enter image description here

相关问题