1
General / Re: Fluent Movement
« on: October 05, 2016, 01:14:27 am »
I often try to understand what's happening by translating the code/varables into understandable statements.
This is what i get:
Maybe while i wrote this down i actually understand somewhat how this works..
Basically we try to do some assuming to what our next state will look like to interpolate the rendering.
Like if we move an object from 0 to 100 with a speed of 100 per second we can achive this fluently IF we have constant 0.01 timegap (ALWAYS).
Which is not the case so it could be, that we have, with any reason we don't now, accumulated about 0.05 timegap because of an update which just took more time... we would do 5 updates in the next loop which would lead to move the object 5 units with one step.
The whole problem is, if one update would tike 0.05 seconds, we would not even be able to draw in that time so the ball would always jump...
The only way to solve it, is to actually do the update not in the same thread as the drawing.
Because this code right obove, is in one thread, so if our update for example is doing a constant 30 fps because it takes so long, our drawing would take too 30 fps instead of 60 for example with VSync on a 60Hz monitor.
Please correct me if i understand something wrong here... I'm just confused.
The more i think about it the more sense does it make but in the same time it doesn't because of logic flaws in my head.
This is what i get:
double t = 0.0; // time since beginning (useful for timed events/skill refresh/etc. would not work those times should be saved between sessions... then i don't get the point of know this
double dt = 0.01; // my fixed timegap for physics (0.01 seconds which basically means i have a tick rate of 100)
double currentTime = hires_time_in_seconds(); // used to calculate the actual timegap
double accumulator = 0.0; // used to accumulate time because the actual timegap is very often much lower then 0.01 seconds
State previous; // still don't get... why i'd need this here.. Probably abstraction
State current; // same as above
while ( !quit )
{
double newTime = time(); // this is used to calculate the timegap
double frameTime = newTime - currentTime; // this is the actual timegap
if ( frameTime > 0.25 ) // why should we max it out to 0.25? If this happens, there's something strange...
frameTime = 0.25; // probably the only reason why this could happen if we have some heavy loading within the loop which should be avoided...
currentTime = newTime; // this is used for the next timegap calculation clearly...
accumulator += frameTime; accumulate timegap because it is often lower then 0.01
while ( accumulator >= dt )
{
previousState = currentState; // still probably just some abstraction layer for states
integrate( currentState, t, dt ); // why would the update method would need the current state.. the method should update the current state so it knows the current state or am i wrong here?
t += dt; // accumulate t obiously
accumulator -= dt; // so we had an actualy update gap so we have to lower the accumulator.. otherwise endless loop
}
const double alpha = accumulator / dt; // why?
State state = currentState * alpha +
previousState * ( 1.0 - alpha ); // why?
render( state ); // rendering is "assuming" what will happen next with the currentState/Alpha/PreviousState thing.. this is a rather pretty complex task to do if you have ton's of informations going on here..
}
double dt = 0.01; // my fixed timegap for physics (0.01 seconds which basically means i have a tick rate of 100)
double currentTime = hires_time_in_seconds(); // used to calculate the actual timegap
double accumulator = 0.0; // used to accumulate time because the actual timegap is very often much lower then 0.01 seconds
State previous; // still don't get... why i'd need this here.. Probably abstraction
State current; // same as above
while ( !quit )
{
double newTime = time(); // this is used to calculate the timegap
double frameTime = newTime - currentTime; // this is the actual timegap
if ( frameTime > 0.25 ) // why should we max it out to 0.25? If this happens, there's something strange...
frameTime = 0.25; // probably the only reason why this could happen if we have some heavy loading within the loop which should be avoided...
currentTime = newTime; // this is used for the next timegap calculation clearly...
accumulator += frameTime; accumulate timegap because it is often lower then 0.01
while ( accumulator >= dt )
{
previousState = currentState; // still probably just some abstraction layer for states
integrate( currentState, t, dt ); // why would the update method would need the current state.. the method should update the current state so it knows the current state or am i wrong here?
t += dt; // accumulate t obiously
accumulator -= dt; // so we had an actualy update gap so we have to lower the accumulator.. otherwise endless loop
}
const double alpha = accumulator / dt; // why?
State state = currentState * alpha +
previousState * ( 1.0 - alpha ); // why?
render( state ); // rendering is "assuming" what will happen next with the currentState/Alpha/PreviousState thing.. this is a rather pretty complex task to do if you have ton's of informations going on here..
}
Maybe while i wrote this down i actually understand somewhat how this works..
Basically we try to do some assuming to what our next state will look like to interpolate the rendering.
Like if we move an object from 0 to 100 with a speed of 100 per second we can achive this fluently IF we have constant 0.01 timegap (ALWAYS).
Which is not the case so it could be, that we have, with any reason we don't now, accumulated about 0.05 timegap because of an update which just took more time... we would do 5 updates in the next loop which would lead to move the object 5 units with one step.
The whole problem is, if one update would tike 0.05 seconds, we would not even be able to draw in that time so the ball would always jump...
The only way to solve it, is to actually do the update not in the same thread as the drawing.
Because this code right obove, is in one thread, so if our update for example is doing a constant 30 fps because it takes so long, our drawing would take too 30 fps instead of 60 for example with VSync on a 60Hz monitor.
Please correct me if i understand something wrong here... I'm just confused.
The more i think about it the more sense does it make but in the same time it doesn't because of logic flaws in my head.