Sign in to follow this  
Headkaze

Getting maximum zoom distance

Recommended Posts

I have a 2d platformer game for the iPhone that uses perspective setup using gluPerspective(). It has a camera that zooms in and out of the gameplay. Recently I've added support for VGA output and this has meant the maximum zoom distance from the action is sometimes showing the edges of the levels (if you can imagine the background is made up of tiles it begins to show black strips where the level ends).

I use the following function to know how much of the display area is showing on a given zoom level.

static inline SizeF getDisplaySize(GLfloat fovy, GLfloat zoom, SizeF screenSize)
{
GLfloat height = tanf(fovy / 2.0f * PI / 180.0f) * zoom * 2.0f;
GLfloat width = height * (screenSize.width / screenSize.height);

return SizeFMake(width, height);
}





Currently I use the following to calculate zoom limits

void Camera::SetZoomLimits(int min, int max)
{
m_minZoom = min;
m_maxZoom = max;

SizeF minDisplaySize = getDisplaySize(FOV, m_minZoom, g_screenSize);
SizeF maxDisplaySize = getDisplaySize(FOV, m_maxZoom, g_screenSize);
SizeF levelSize = SizeFMake(g_levelData->Width / SCALE_PIXEL, g_levelData->Height / SCALE_PIXEL);

while(minDisplaySize.width > levelSize.width || minDisplaySize.height > levelSize.height)
{
m_minZoom--;

minDisplaySize = getDisplaySize(FOV, m_minZoom, g_screenSize);
}

while(maxDisplaySize.width > levelSize.width || maxDisplaySize.height > levelSize.height)
{
m_maxZoom--;

maxDisplaySize = getDisplaySize(FOV, m_maxZoom, g_screenSize);
}
}





This does what I want but I would like a function that returns "zoom" given the level size rather than using loops.

[Edited by - Headkaze on December 5, 2010 3:17:09 PM]

Share this post


Link to post
Share on other sites
Still trying to solve this. I understand I can split the screen into two right triangles and use trig to calculate the camera distance.

So basically what I need to know is how to calculate the adjacent side of a right triangle given the opposite side and angle.

angle = FOV / 2 = 15 / 2 = 7.5
Opposite side = MIN(levelWidth, levelHeight) / 2 = 512 / 2 = 256
Calculate adjacent side which should be the maximum zoom distance

Share this post


Link to post
Share on other sites
Quote:
Original post by dpadam450
http://www.tutorvista.com/math/find-angle-using-tangent

Work back from the angle and opposite side to find the adjacent.


Those examples show you how to get the angle. I already have the angle. All the examples I've found all seem to show how to get the adjacent side from hypontenuse and opposite sides, never from angle and opposite side. What is the formula?

EDIT: Nevermind found it. adj = opp / tan(angle). from http://www.ict-teacher.com/Mathstutor/Trigonometry%28i%29.html

Share this post


Link to post
Share on other sites
Still having problems with this. Passing in the level size is not enough because the maximum zoom will change based on the screen resolution.

For example for a level size of 512 x 1024 and a screen resolution of 1280 x 720 the maximum zoom should be 17.

For the same level at 480 x 320 the maximum zoom is 30.

How can I calculate this?

Share this post


Link to post
Share on other sites
I was going to say this before because your doing this problem wrong. You need a standardized frame so that your level sizes aren't in pixels but in a universal coordinate system. I'm assuming your using glOrtho(0,width, 0 height)?

I mean you can still get it done somehow your way, but it is much easier if you use glOrtho(0,1, 0, 1); Keep that the same no matter what resolution, and just change the glViewport. If your objects/level are located by pixels, just scale them so they map to the other system.

Your maximum zoom was not easily understandable. How is the zoom 17?

Share this post


Link to post
Share on other sites
It's primarily a 2d game but has 3d models and needs perspective. There are multiple background layers at different distances to the camera. The main layer (which has the platforms) is at Z=0. The camera is minZoom to maxZoom and will interpolate it's position based on the player.

To calculate the size of the display I use getDisplaySize().

Depending on the screen resolution sometimes the camera zooms out too far and you can see the edges of the background quads. So the function SetCameraLimits needs to check that the zoom limits arn't too far out.

Currently the function I have works but I loop through to figure out if the displaySize is greater than the levelSize and if so subtract one from the zoom limit in a while loop (all this code is in the first post).

I would like a function that takes the level size, screen resolution and gives me a maximum zoom limit.

Share this post


Link to post
Share on other sites
Hi

Not really sure what you mean with zoom 30,17,etc. aren't you calculating the projection matrix using field of view angles?

If so, you could measure the distance between camera and farthest plane (a)
and half the width of the farthest plane (b) use atan to calculate the half fov angle (c) double it and use that to feed the projection matrix. Do the same with the height.


. +
. |
. b
. |
C+------------ a ------------+
|
|
|
+


c = atan(b/a)

The closer you move the camera, the smaller a will be => zoom will decrease.
The farther you get away, the greater a will be => zoom will increase.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this