Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::view.zoom() sync with framerate...  (Read 2581 times)

0 Members and 1 Guest are viewing this topic.

Deftwun

  • Newbie
  • *
  • Posts: 27
    • View Profile
sf::view.zoom() sync with framerate...
« on: May 07, 2012, 06:34:03 am »
Anyone have a suggestion as how to do this? Similar to how you would keep a sprite moving at constistent speed independent of frametime. I'm trying something like this...

Code: [Select]
///CAMERA CONTROLS (main app update loop)
if (IsKeyDown[sf::Keyboard::Subtract])      mCamera.ZoomOut();


///Camera Class
Camera::ZoomOut(){
    mview.zoom(1 + mApp->GetFrameTime());
}

This wont quite cut it though. If the framerate is 1000 fps the factor is 1.001 or100.1% of original viewport size.
If it is 60 fps it is 101%.

Since a higher framerate means ZoomOut() gets called more often I was thinking that It would naturally appear to zoom at the same speed but It seems thats not the case.

So basically I'm not sure what kind of math to use here to get a consistent zoom factor across different framerates and my brain is hurting a little bit. Any thoughts?

« Last Edit: May 07, 2012, 06:37:32 am by Deftwun »

Deftwun

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: sf::view.zoom() sync with framerate...
« Reply #1 on: May 07, 2012, 06:42:07 am »
 ::)... another case of overthinking a simple problem. You dont need to multiply by frametime at all. It will zoom consistently with a factor (aka percentage) alone. Man I need to reread what I write before hitting submit next time.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: sf::view.zoom() sync with framerate...
« Reply #2 on: May 07, 2012, 10:59:06 am »
Actually your question is legit. Indeed the zooming is dependant on the frametime. What you do is multiplying with delta T:

mview.zoom( ZOOM_FACTOR * delta_t );

If delta_t is in seconds, ZOOM_FACTOR will be the zoom factor that'll be applied in one second.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::view.zoom() sync with framerate...
« Reply #3 on: May 07, 2012, 11:26:45 am »
Quote
If delta_t is in seconds, ZOOM_FACTOR will be the zoom factor that'll be applied in one second.
It's more tricky. Since zooming is internally a multiplication and not an addition (as moving or rotating would be), the result is completely different; multiplying the zoom factor by the elapsed time would make it tiny very fast.

Look:
// Moving at 100 pixels/sec in one step (elapsed time is 1)
position = 0;
position += 100 * 1;
// position == 100

// Moving at 100 pixels/sec in two steps (elapsed time is 0.5)
position = 0;
position += 100 * 0.5;
position += 100 * 0.5;
// position == 100

// Zooming by 0.8/sec in one step (elapsed time is 1)
zoom = 1;
zoom *= 0.8 * 1;
// zoom == 0.8

// Zooming by 0.8/sec in two steps (elapsed time is 0.5)
zoom = 1;
zoom *= 0.8 * 0.5;
zoom *= 0.8 * 0.5;
// zoom == 0.16 !!!
Laurent Gomila - SFML developer

Deftwun

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: sf::view.zoom() sync with framerate...
« Reply #4 on: May 08, 2012, 01:16:01 am »
Yes that is exactly what I found. With a framerate of 1000 fps I would have a very slow zoom speed when I multiplied my zoom factor by the delta time. At 60 fps it would look normal. However the strange thing is that it works just fine on either framerate if i just put in my zoom factor.  Maybe there is a slight difference but I cant notice any. I must say I dont completely understand the math behind why it appears the same but it does...

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: sf::view.zoom() sync with framerate...
« Reply #5 on: May 08, 2012, 08:09:33 am »
Absolutely true, sorry for pointing out a wrong suggestion.

However zooming is still dependant on the frametime. If you simulate a very low or very high frametime then I bet it's recognizable.

What about using a different approach by modifying the zoom factor and setting it then instead of calling ZoomIn/Out() multiple times? Like:

zoom_factor += x * delta_t;

view.setZoom( zoom_factor );
 

If I'm not completely wrong (again ;)), that should do the trick. And in addition to that, you even have more control about the change rate more directly.