4
\$\begingroup\$

I am using a 2D camera, which does rotations and zoom. Currently, I am using the following to get my MinX, MinY, MaxX and MaxY...

    public float MinX
    {
        get
        {
            return pos.X - gameEngine.screenWidth / 2;
        }
    }
    public float MaxX
    {
        get
        {
            return pos.X + gameEngine.screenWidth / 2;
        }
    }
    public float MinY
    {
        get { return pos.Y - gameEngine.screenHeight / 2; }
    }
    public float MaxY
    {
        get { return pos.Y + gameEngine.screenHeight / 2; }
    }

How would I now take into account Zoom? Default Zoom is 1. I think this will require Matrices, but any help is appreciated.

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Solution with only Translation and Zoom

It's actually quite simple to implement. The camera's view matrix transforms coordinates from world space to view space. The inverse of the view matrix transforms coordinates from view space into world space.

Using this information, you can get the bounds of your camera, whether it's zoomed or not, with this simple method (I'll use a fictional RectangleF struct as example, I assume you'll understand the logic):

public RectangleF Bounds
{
    get 
    {
        return new RectangleF
        {
            Min = Vector2.Transform(Vector2.Zero, inverseViewMatrix),
            Max = Vector2.Transform(Game.ScreenSize, inverseViewMatrix),
        };
    }
}

Basically you take the top-left and bottom right-corners of the camera in view space (which are always [0,0] and [screenWidth, screenHeight]) and transform them into world space. That's your bounds.

And by the way you can get the inverseViewMatrix by doing a Matrix.Invert(viewMatrix).

Solution with Translation, Zoom and Rotation

You only asked about zooming but this might come in handy too. If you try to do this with rotation mixed in, the process changes a little. In this case instead of only transforming the top-left and bottom-right corners, you need to transform all four corners, and then find the minimum and maximum X and Y values to create your bounding box. Something like:

Vector2 tl = Vector2.Transform(Vector2.Zero, inverseViewMatrix);
Vector2 tr = Vector2.Transform(new Vector2(Game.ScreenSize.X, 0), inverseViewMatrix);
Vector2 bl = Vector2.Transform(new Vector2(0, Game.ScreenSize.Y), inverseViewMatrix);
Vector2 br = Vector2.Transform(Game.ScreenSize, inverseViewMatrix);
Vector2 min = new Vector2(MathHelper.Min(tl.X, MathHelper.Min(tr.X, MathHelper.Min(bl.X, br.X))), MathHelper.Min(tl.Y, MathHelper.Min(tr.Y, MathHelper.Min(bl.Y, br.Y))));
Vector2 max = new Vector2(MathHelper.Max(tl.X, MathHelper.Max(tr.X, MathHelper.Max(bl.X, br.X))), MathHelper.Max(tl.Y, MathHelper.Max(tr.Y, MathHelper.Max(bl.Y, br.Y))));
RectangleF bounds = new RectangleF {Min = min, Max = max};

What this does is basically find the smallest AABB that can completely fit the OBB that would be formed by the four corners of your camera.

\$\endgroup\$
1
  • \$\begingroup\$ No problem! I've had to figure all of this for my projects before, so I remembered the process well. :-P \$\endgroup\$ Dec 31, 2011 at 2:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .