   Smooth movement with fixed time step?
  I''m updating physics 50 times per second and in some situations the jerky movement is noticeable. Framerate can be as high as 1000, but when I''m for example sliding down the console, I can see how it jumps a little by little...Is it somehow possible to make the movement smooth with fixed time steps?   Business is business and Moses is Moses[Homesite]   
  you can always keep the physics update on the 50fps cycle and then try some kind of dead reckoning interpolation in your render loop.  when the physics does it''s update again you just correct the position of the object as it was interpolated during the render loop.If you''re worried that the interpolation will mess with your collision detection and whatnot, just do the interpolation with the object mesh and not with it''s collision bounds.  So basically you make a split in your logic between rendered things and physics things.  physics things update on a fixed timescale and rendered things update as fast as they can based on the last known physics calculation and current acceleration/velocity vectors.-me  ;quote:Original post by Palidine  you can always keep the physics update on the 50fps cycle and then try some kind of dead reckoning interpolation in your render loop.  when the physics does it''s update again you just correct the position of the object as it was interpolated during the render loop.If you''re worried that the interpolation will mess with your collision detection and whatnot, just do the interpolation with the object mesh and not with it''s collision bounds.  So basically you make a split in your logic between rendered things and physics things.  physics things update on a fixed timescale and rendered things update as fast as they can based on the last known physics calculation and current acceleration/velocity vectors.-me    Javier Arevalo detailed a method of accomplishing this in a Tip of the Day over at Flipcode. Works pretty well, and it''s the main loop structure I use in most of my games. GolemBlender--The Gimp--Python--Lua--SDLNethack--Crawl--ADOM--Angband--Dungeondweller;  Do you mean you notice jerks because A) The physics update frame takes much longer than the other frames so you notice the framerate pop or B) Objects render into impossible positions briefly, which your physics then suddenly corrects.If its A) well, that''s really hard  If its B) then it''s definitely easier.  You can have your objects'' rendering position lag "Real-Time" by the amount of time between physics updates.  So you need to store the position/velocity/orientation of the objects after their most recent physics update, AND the update before that one, and interpolate between those positions for rendering, while keeping track of their -actual- positions for internal logic.  The downside is that the controls might feel a little laggy, but I mean, a 20 ms lag should be so not noticeable. ;  Also make sure you''re using queryPerformanceCounter (?) and not timeGetTime or TickCount.I''ve had issues with the slower ones causing jerkiness and oscillations in speeds of things. ;  It seems I have to use that interpolation thing, but I don''t have a clue how  I''ll have to start finding some tuts about that, if there exists any...   Business is business and Moses is Moses[Homesite]   ;  The article I linked earlier talks about how interpolation works.Basically, the game logic (physics, etc...) updates at a fixed time interval--say, 50 updates per second. However, we shouldn''t restrain drawing to 50 fps if the video hardware can handle faster. At any given point in time when the scene is being drawn, we are actually in between frames by some amount. If we maintain game state for CurrentFrame and NextFrame, we can calculate exactly how far into the next frame we are, generate an interpolation factor in the range [0,1], and apply it to our rendering. If the camera moves 15 world units to get to the NextFrame, we multiply 15 by this interpolation factor and add it to our Current position to get the actual position of the camera at the time of that render cycle. If a keyframed object advances one keyframe per update in animation, then we morph between the two keyframes by our interpolation factor to generate the object''s actual animation pose at that time of rendering. Since the screen will probably draw many times before the NextFrame become Current and update generates a new NextFrame, this has the purpose of smoothing out the discrete steps that updating makes. Instead of the camera just jumping 15 world units every frame, making for a jerky scrolling picture, we instead jump by fractions of that amount every time the screen draws, making each jump smaller and far less noticeable. Actual visual frames-per-second do not have to be locked based on the speed of the machine; only game logic updates are locked to some fixed-time update, and the visuals can be drawn as smoothly as the machine is capable of. GolemBlender--The Gimp--Python--Lua--SDLNethack--Crawl--ADOM--Angband--Dungeondweller;  Thanks for the clarification But, do you have any code to study? I just need something to get started...   Business is business and Moses is Moses[Homesite]   ;  Sure, here''s the main loop from the testing prototype of the sequel to my current game:   time0=S->GetTicks();  TicksStart=S->GetTicks();  while(Running)  {    time1 = S->GetTicks();    frameTime = 0;    int numLoops = 0;    /***********************************************************************    Process Input    ***********************************************************************/    /**********************************************************************    Frame-independent input processing    ***********************************************************************/   SDL_Event *event;    while((event=Inp->GetEvent()))    { if(event->type==SDL_KEYDOWN) {   if (event->key.keysym.sym==SDLK_q) Running=0; }}    while ((time1 - time0) > TickTime && numLoops < MaxLoops)    { /***************************************************************** Fixed timestep game logic updating; moving the objects, moving the view, etc... ******************************************************************/  if(Inp->KeyIsPressed(SDLK_LEFT)) {x-=SCROLL_STEP; z+=SCROLL_STEP;} if(Inp->KeyIsPressed(SDLK_RIGHT)) {x+=SCROLL_STEP; z-=SCROLL_STEP;} if(Inp->KeyIsPressed(SDLK_UP)) {x-=SCROLL_STEP; z-=SCROLL_STEP;} if(Inp->KeyIsPressed(SDLK_DOWN)) {x+=SCROLL_STEP; z+=SCROLL_STEP;} TArray.UpdatePos(x,z); time0 += TickTime; frameTime += TickTime; numLoops++;    }    if ((time1 - time0) > TickTime) time0 = time1 - TickTime;    /*********************************************************************    Calculate interpolation factor and render the view    **********************************************************************/   PercentWithinTick = (float)(time1 - time0)/(float)TickTime;    if(PercentWithinTick>1.0f) PercentWithinTick=1.0f;    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); TArray.Render(PercentWithinTick);    // For an interesting test, comment out the above line and uncomment this one:    //TArray.Render(0.0f);    // This will show the difference between interpolated and    // un-interpolated rendering./********************************************************Skeletal Animation Testing stuff.*********************************************************/    Frame1.InterpolateTo(CurrFrame, Frame2, morph);   Skel.PoseBones(CurrFrame, Pose);    morph += morphadd;    if(morph>1.0)    { morphadd *= -1.0; morph=1.0;    }    if(morph<0.0)    { morphadd *= -1.0; morph=0.0;    }    glPushMatrix();    glTranslatef(800.0, 300.0, 800.0);    glScalef(10.0, 10.0, 10.0);  AnimMesh.Render(Orient, Pose, LightVec);    glPopMatrix();   S->Flip();    FrameCount++;  }  It''s ugly, because it''s from a very early prototype version, not a real game yet. But the loop itself is structured pretty much identically to Javier''s. Note that the testing code for skeletal animation resides outside of the framework of interpolation, so it should be ignored.My TArray object in the above code is basically an encapsulation of a heightmap terrain with an included camera position for rendering. The object includes a CurrentPosition and a NextPosition. Each time the object updates (in the call TArray.UpdatePos(x,z), the old NextPostion is set as the CurrentPosition, and a new NextPosition is given as (x,z), which is calculated based on what keys are pressed down.When the terrain object is rendered (TArray.Render(PercentWithinTick)), it is given the floating-point interpolation factor calculated based on how far into the next tick we are. The Render() function performs a simple linear interpolation between CurrentPosition and NextPosition using this interpolant factor, and uses the result as the "real" location at which to place the camera and draw the view.So, with a TickTime of 40 ms, that gives me an update rate of 25 logic updates per second. With a SCROLL_STEP of 8, that means that every update the map view scrolls by 8 world units. If I do not use interpolation (I included lines that can be commented and uncommented to switch between, as a test) then when the view scrolls, it jumps visibly by 8 units every frame. I could be rendering at 900 fps, but most of those drawn frames are wasted, since they are always drawing the exact same rendering state.With interpolation, instead of jumping position every 1/25th of a second, the scrolling view calculates intermediate positions for every rendering frame drawn. Instead of jumping 8 units every 1/25th second, it jumps by fractions of a unit every time the screen is drawn (perhaps every 1/900th second if the card can draw that fast), smoothing out the jumps so that they are not noticeable. The effect is most noticeable when large jumps are involved. For instance, if SCROLL_STEP is 20, then that means the screen view jumps 20 units every frame while scrolling--a very visible, and very ugly effect. With the interpolation, however, this is smoothed out and made cleaner.   GolemBlender--The Gimp--Python--Lua--SDLNethack--Crawl--ADOM--Angband--Dungeondweller;  Thanks again! I'm starting to get a clearer picture about this. I have still few questions (I tried to understand what Javier said in that TOTD, but I'm still confused)Why use the MaxLoops-check? And what should that MaxLoops be assigned to?What's the purpose of this code:if ((time1 - time0) > TickTime) time0 = time1 - TickTime; ?edit: about the linear interpolation... I have really no idea what it is, but after some drawing, I came up with this:x = value ranging from 0 to 1v1 = position vector at frame 1v2 = position vector at frame 2v = the interpolated vectorv = (1 - x)v1 + xv2Does this work in every situation?Business is business and Moses is Moses[Homesite]   [edited by - Miksan on February 6, 2004 5:04:33 PM]