There are a few similar posts, but they only deal with one of the three components I'm looking for, and none seem to handle the case of using a fixed step size (they're all about simulations which use a variable deltaTime).
I'm using a fixed step simulation, and my lifelong (bad) habit has been to eschew units and just directly use parameter values which have deltaT "baked in". Now that I'm trying to add support for different fixed rates, it's biting me in the ass! :/
Here's a simplified example of my code, covering all three cases:
run_speed = 2; //velocity, linear
brake_decay = 0.95; //viscous damping, exponential
gravity = 1; //acceleration, quadratic
if(button_pressed) vel_x = run_speed;
else vel_x *= brake_decay;
vel_y += gravity;
pos_x += vel_x;
pos_y += vel_y;
I would like to support different fixed timesteps by scaling my existing parameters:
run_speed = 2 * A_to_B_vel;
brake_decay = 0.95 * A_to_B_damp;
gravity = 1 * A_to_B_acc;
My question is: if my fixed timestep is currently A ms/tick, and I want to switch to a fixed timestep of B ms/tick, how do I calculate these three new scaling factors, such that the object follows the same curve through space and time?
(I realize that the actual positions will vary between A and B since we'll be sampling the trajectory curve at a different rate, I just want the underlying curve itself to be identical regardless of how we sample it.)
A_to_B_vel: this is the case which has been covered by many other "framerate independent" questions, and it's relatively trivial because the relationship is linear: A_to_B_vel = B/A
A_to_B_damp: this seems to have been answered here Frame-rate independant movement with acceleration via the Pow() function. This makes sense since it describes an exponential curve; I'd still appreciate someone breaking down the formula though, because the answer given there involves "referenceFPS" and I'd prefer to stick solely to units of time, ie ms/frame, not frame/sec. (and it's not clear that I can simply substitute one for the other into the formula they give)
A_to_B_acc: this is where it gets confusing! According to the above answer, this should be treated similarly to A_to_B_vel (ie scale by the frame duration), however this is definitely wrong, since I've implemented it and it doesn't work. i.e A_to_B_acc = B/A
doesn't work. My calculus is very rusty, but I would imagine that the scaling factor needs to involve a dT*dT term somewhere, since acceleration changes position quadratically.
Additionally, if anyone could point me towards a resource which explained the underlying calculus here, I would really appreciate it.
Thanks for your time! :) Raigan
referenceFPS = 30f
<==>referenceTimestep = 1f/30f
\$\endgroup\$scaledDamping = Pow(referenceDamping, deltaTime * referenceFPS);
i.e I can't just plug in referenceTimestep and have the result work properly. \$\endgroup\$scaledDamping = Pow(referenceDamping, deltaTime/referenceTimestep);
- you literally only have to change the variable name, and make the*
into a/
. \$\endgroup\$