1
votes

I've been trying to combine these two samples from David Amador:

http://www.david-amador.com/2010/03/xna-2d-independent-resolution-rendering/

http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/

Everything is working fine except I'm having some difficulty getting the mouse coordinates. I was able to get them for each individual sample, but my math for taking both into account seems to be wrong.

The mouse coordinates ARE correct if my virtual resolution and normal resolution are the same. It's when I do something like Resolution.SetVirtualResolution(1920, 1080) and Resolution.SetResolution(1280, 720, false) when the coordinates slowly get out of sync as I move the camera.

Here is the code:

    public static Vector2 MousePositionCamera(Camera camera)
    {
        float MouseWorldX = (Mouse.GetState().X - Resolution.VirtualWidth * 0.5f + (camera.position.X) * (float)Math.Pow(camera.Zoom, 1)) /
            (float)Math.Pow(camera.Zoom, 1);

        float MouseWorldY = ((Mouse.GetState().Y - Resolution.VirtualHeight * 0.5f + (camera.position.Y) * (float)Math.Pow(camera.Zoom, 1))) /
        (float)Math.Pow(camera.Zoom, 1);

        Vector2 mousePosition = new Vector2(MouseWorldX, MouseWorldY);
        Vector2 virtualViewport = new Vector2(Resolution.VirtualViewportX, Resolution.VirtualViewportY);
        mousePosition = Vector2.Transform(mousePosition - virtualViewport, Matrix.Invert(Resolution.getTransformationMatrix()));

        return mousePosition;     
    }

In resolution I added this:

virtualViewportX = (_Device.PreferredBackBufferWidth / 2) - (width / 2);
virtualViewportY = (_Device.PreferredBackBufferHeight / 2) - (height / 2);

Everything else is the same as the sample code. Thanks in advance!

1

1 Answers

2
votes

Thanks to David Gouveia I was able to identify the problem... My camera matrix was using the wrong math.

I'm going to post all of my code with the hopes of helping someone who is trying to do something similar.

Camera transformation matrix:

        public Matrix GetTransformMatrix()
        {
            transform = Matrix.CreateTranslation(new Vector3(-position.X, -position.Y, 0)) * Matrix.CreateRotationZ(rotation) *
                        Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) * Matrix.CreateTranslation(new Vector3(Resolution.VirtualWidth
                            * 0.5f, Resolution.VirtualHeight * 0.5f, 0));

            return transform;
        }

That will also center the camera. Here's how you get the mouse coordinates combining both the Resolution class and camera class:

    public static Vector2 MousePositionCamera(Camera camera)
    {
        Vector2 mousePosition;
        mousePosition.X = Mouse.GetState().X;
        mousePosition.Y = Mouse.GetState().Y;

        //Adjust for resolutions like 800 x 600 that are letter boxed on the Y:
        mousePosition.Y -= Resolution.VirtualViewportY;

        Vector2 screenPosition = Vector2.Transform(mousePosition, Matrix.Invert(Resolution.getTransformationMatrix()));
        Vector2 worldPosition = Vector2.Transform(screenPosition, Matrix.Invert(camera.GetTransformMatrix()));

        return worldPosition;     
    }

Combined with all of the other code I posted/mentioned this should be all you need to achieve resolution independence and an awesome camera!