Interpolation using a sprite's previous frame and current frame
- by user22241
Overview
I'm currently using a method which has been pointed out to me is extrapolation rather than interolation. As a result, I'm also now looking into the possibility of using another method which is based on a sprite's position at it's last (rendered) frame and it's current one.
Assuming an interpolation value of 0.5 this is, (visually), how I understand it should affect my sprite's position....
This is how I'm obtaining an inerpolation value:
public void onDrawFrame(GL10 gl) {
// Set/re-set loop back to 0 to start counting again
loops=0;
while(System.currentTimeMillis() > nextGameTick && loops < maxFrameskip) {
SceneManager.getInstance().getCurrentScene().updateLogic();
nextGameTick += skipTicks;
timeCorrection += (1000d / ticksPerSecond) % 1;
nextGameTick += timeCorrection;
timeCorrection %= 1;
loops++;
tics++;
}
interpolation = (float)(System.currentTimeMillis() + skipTicks - nextGameTick) / (float)skipTicks;
render(interpolation);
}
I am then applying it like so (in my rendering call):
render(float interpolation) {
spriteScreenX = (spriteScreenX - spritePreviousX) * interpolation + spritePreviousX;
spritePreviousX = spriteScreenX; // update and store this for next time
}
Results
This unfortunately does nothing to smooth the movement of my sprite. It's pretty much the same as without the interpolation code. I can't get my head around how this is supposed to work and I honestly can't find any decent resources which explain this in any detail.
My understanding of extrapolation is that when we arrive at the rendering call, we calculate the time between the last update call and the render call, and then adjust the sprite's position to reflect this time (moving the sprite forward) - And yet, this (Interpolation) is moving the sprite back, so how can this produce smooth results?
Any advise on this would be very much appreciated.
Edit
I've implemented the code from OriginalDaemon's answer like so:
@Override
public void onDrawFrame(GL10 gl) {
newTime = System.currentTimeMillis()*0.001;
frameTime = newTime - currentTime;
if ( frameTime > (dt*25))
frameTime = (dt*25);
currentTime = newTime;
accumulator += frameTime;
while ( accumulator >= dt )
{
SceneManager.getInstance().getCurrentScene().updateLogic();
previousState = currentState;
t += dt;
accumulator -= dt;
}
interpolation = (float) (accumulator / dt);
render();
}
Interpolation values are now being produced between 0 and 1 as expected (similar to how they were in my original loop) - however, the results are the same as my original loop (my original loop allowed frames to skip if they took too long to draw which I think this loop is also doing).
I appear to have made a mistake in my previous logging, it is logging as I would expect it to (interpolated position does appear to be inbetween the previous and current positions) - however, the sprites are most definitely choppy when the render() skipping happens.