How do I calculate the boundary of the game window after transforming the view?

Posted by Cypher on Game Development See other posts from Game Development or by Cypher
Published on 2012-10-06T00:01:38Z Indexed on 2012/10/06 3:50 UTC
Read the original article Hit count: 333

Filed under:
|
|
|

My Camera class handles zoom, rotation, and of course panning. It's invoked through SpriteBatch.Begin, like so many other XNA 2D camera classes. It calculates the view Matrix like so:

public Matrix GetViewMatrix() {
    return Matrix.Identity
        * Matrix.CreateTranslation(new Vector3(-this.Spatial.Position, 0.0f))
        * Matrix.CreateTranslation(-( this.viewport.Width / 2 ), -( this.viewport.Height / 2 ), 0.0f)
        * Matrix.CreateRotationZ(this.Rotation)
        * Matrix.CreateScale(this.Scale, this.Scale, 1.0f)
        * Matrix.CreateTranslation(this.viewport.Width * 0.5f, this.viewport.Height * 0.5f, 0.0f);
}

I was having a minor issue with performance, which after doing some profiling, led me to apply a culling feature to my rendering system. It used to, before I implemented the camera's zoom feature, simply grab the camera's boundaries and cull any game objects that did not intersect with the camera.

However, after giving the camera the ability to zoom, that no longer works. The reason why is visible in the screenshot below. The navy blue rectangle represents the camera's boundaries when zoomed out all the way (Camera.Scale = 0.5f). So, when zoomed out, game objects are culled before they reach the boundaries of the window. The camera's width and height are determined by the Viewport properties of the same name (maybe this is my mistake? I wasn't expecting the camera to "resize" like this).

screenshot

What I'm trying to calculate is a Rectangle that defines the boundaries of the screen, as indicated by my awesome blue arrows, even after the camera is rotated, scaled, or panned.

Here is how I've more recently found out how not to do it:

public Rectangle CullingRegion {
    get {
        Rectangle region = Rectangle.Empty;

        Vector2 size = this.Spatial.Size;
        size *= 1 / this.Scale;

        Vector2 position = this.Spatial.Position;
        position = Vector2.Transform(position, this.Inverse);

        region.X = (int)position.X;
        region.Y = (int)position.Y;
        region.Width = (int)size.X;
        region.Height = (int)size.Y;

        return region;
    }
}

It seems to calculate the right size, but when I render this region, it moves around which will obviously cause problems. It needs to be "static", so to speak. It's also obscenely slow, which causes more of a problem than it solves.

What am I missing?

© Game Development or respective owner

Related posts about XNA

Related posts about 2d