[SOLVED] Zoom scene with custom pivot

edited January 2012 in Help request
Hello community :)

I have a small problem and i couldn't find a solution in the docs or on this forum.
In my game i have a static background with some kind of sunset. The background is always stretched onto the screen and should not move (working). Then i have a road happens to be on the bottom of the scene. I have two guys running on top of the road (working animation).
As the distance between them becomes bigger, the scene should zoom out to keep them both on screen. (works but not perfectly).

So the zooming part is done by applying zoom to the default camera. It works fine. I also added a low-pass filter to the zoom so it zooms in and out with a fade effect.

Now to the problem.
When I zoom the camera it always zooms around the center of the screen. That's fine but in my case the road and the running dudes are scaled away into the middle of the screen. What i want is zoom them out but keep their feet and the road at the same Y value on the screen. Basically I want to zoom the camera over a custom Pivot.

Any ideas how to do that?

Thanks in advance!
Alex

Comments

  • edited January 2012
    Sounds like you want to both zoom and pan the camera.
    IIRC,
    camera_y' = camera_y - (1/2)*screen_hight*(1 - zoom)

    Where camera_y is your unzoomed camera-y position, and camera_y' is the zoom-compensated position you should set the camera to.
    This will keep the bottom edge of the screen mapped to the same y-coordinate in world-space throughout zooming. If I did the math right that is.
  • edited January 2012
    godexsoft wrote:
    Hello community :)

    Hi Alex!
    I have a small problem and i couldn't find a solution in the docs or on this forum.
    In my game i have a static background with some kind of sunset. The background is always stretched onto the screen and should not move (working). Then i have a road happens to be on the bottom of the scene. I have two guys running on top of the road (working animation).
    As the distance between them becomes bigger, the scene should zoom out to keep them both on screen. (works but not perfectly).

    I know those already work for you, but in case someone stumble upon this thread when trying to achieve static stretched background that works independently from the resolution, the easiest way to do it is to set the background object as a camera child and use relative positioning/scaling to make it go all the way back to the background and stretch to cover the entire camera frustum. Ex.:
    In config:
    
    [MyBackground]
    Graphic = ...
    ParentCamera = MyCamera
    UseParentSpace = both
    Position = (0, 0, 1); Assuming the graphic's pivot is centered
    Scale = 1
    

    That should do the trick, no matter what the resolution is. The only potential issue is that when zooming in/out, the background will appear the same on screen, which is something one might want or not. To easily fix this, simply scaling it with the reciprocal zoom value will make it never actually change size.

    Sorry for the digression. :)
    So the zooming part is done by applying zoom to the default camera. It works fine. I also added a low-pass filter to the zoom so it zooms in and out with a fade effect.

    May I suggest to actually set the camera as a children of a dummy object? (You have to do this in code though, it can't be done directly in config.) This way you won't need to call any camera zoom/position/rotation function but you'll be able to use the object scale/position/rotation one directly, which has the advantage of allowing you to use orxFX on it if you want some canned smooth movement at some point.
    Now to the problem.
    When I zoom the camera it always zooms around the center of the screen. That's fine but in my case the road and the running dudes are scaled away into the middle of the screen. What i want is zoom them out but keep their feet and the road at the same Y value on the screen. Basically I want to zoom the camera over a custom Pivot.

    Any ideas how to do that?

    I think you can do it with a simple wrapper function to the zoom/scale feature.

    First of all, you need to know the vertical distance between the camera's center and your road when zoom/scale == 1.
    Let's call it Y, probably defined in config somewhere and let's assume the camera starts in (0, 0), for the sake of easiness, ie. your road.Y = Y in the world and on screen.

    Then you need to determine what your scale value is, based on the distance between your characters (which you're already doing and smoothing/filtering if I understood correctly, I'm just detailing all the steps for a didactic purpose if another user need it later on).

    When applying your scale/zoom, you'll need to re-position your camera accordingly.

    Let's say we apply a scale S to the camera (ie. zoom = 1 / S).

    That means that your road vertical position on screen, Y', is now Y' = Y / S. You thus need to set your camera Yc at Yc = Y / S - Y * S, ie. Yc = Y (1 / S - S).

    You do the same kind of horizontal correction based on the horizontal center between both characters.

    Hopefully I didn't make any maths mistakes here as I don't have access to a computer to test it for now. :)

    Hope this helps!

    EDIT: I didn't account for the scaled camera frustum size when replacing the camera, it should work fine now. Still on paper though, so let me know if I'm completely off or not. :)
  • edited January 2012
    Guys thanks for your inputs. Iarwain's solution worked. The difference:
    Y = Y' * (1.0f - zm); // Wrong
    vs.
    Y = Y' * (1.0f / zm - zm); // Works fine

    Thanks!
    Alex
  • edited January 2012
    Glad it worked!
Sign In or Register to comment.