Search code examples
c#matrixxnacamera

XNA/C# 2D Coordinate Scaling in World Matrix to 3D View Matrix?


This is my Transform. I got it from an example of a simple 2D camera.

    public Matrix Transform(GraphicsDevice graphicsDevice)
    {
        float ViewportWidth = graphicsDevice.Viewport.Width;
        float ViewportHeight = graphicsDevice.Viewport.Height;

        matrixTransform =
          Matrix.CreateTranslation(new Vector3(-cameraPosition.X, -cameraPosition.Y, 0)) *
              Matrix.CreateRotationZ(Rotation) *
              Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
              Matrix.CreateTranslation(
                    new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
        return matrixTransform;
    } 

If I understand it correctly, it allows for a roll(rotation), sprite scale change on zoom, and translation between world and camera for simple up, down, left, right controls. However, it does not alter the Z depth.

But what I need is for the game world to zoom, not just the sprites drawn. And I assume in order to do this I need to change the Z distance between the camera and the world matrix.

I am VERY NEW to programming and have only a simple understanding of matrix in general. I have even less understanding as to how XNA uses them in the draw method. And so far I feel like pulling my hair out from a fruitless search for answers... I just need the world coordinates to scale on zoom, so that before my mouse at a pre-zoom X.60 Y.60 will be at X.600 Y.600 post-zoom (ie: zoom level 0.1). But my mouse has not moved, only the world got bigger in view (or shrank).


Solution

  • I know this question is old, but this is in case anyone comes across this problem and can't find a solution. @RogueDeus was trying to convert scaled input coordinates when he was zooming in or out with his camera. In order to scale the mouse, all you need is to get the inverse matrix of the scale.

    So if his scale matrix was created as this:

    Matrix.CreateScale(zoom, zoom, 0);
    

    The mouse coordinates should be inverse scaled and shifted by the necessary translation:

    float ViewportWidth = graphicsDevice.Viewport.Width;
    float ViewportHeight = graphicsDevice.Viewport.Height;
    
    Matrix scale = Matrix.CreateScale(zoom, zoom, 0);
    Matrix inputScalar = Matrix.Invert(scale);
    
    ...
    
    public MouseState transformMouse(MouseState mouse)
    {
        /// Shifts the position to 0-relative
        Vector2 newPosition = new Vector2(mouse.X - ViewportWidth,
                                          mouse.Y - ViewportHeight);
    
        /// Scales the input to a proper size
        newPosition = Vector2.Transform(newPosition, InputScalar);
    
        return new MouseState((int)newPosition.X, (int)newPosition.Y,
                              mouse.ScrollWheelValue, mouse.LeftButton,
                              mouse.MiddleButton, mouse.RightButton,
                              mouse.XButton1, mouse.XButton2);
    }