2
\$\begingroup\$

Is there a reason why retrieving velocity of a 3d object in a game engine vs deriving it from position updates is preferable?

I am currently polling position at every step and deriving current velocity, however, there is also a "get velocity" option. I already need position but I'm wondering if the velocity in the game engine is preferable for some reason like it has less latency than the derivative.

\$\endgroup\$
  • \$\begingroup\$ Hmm, the derivative velocity could be frame dependent, because actual object velosity could be multiplied by deltaTime. \$\endgroup\$ – Ocelot Jan 26 '18 at 15:24
  • \$\begingroup\$ Yes, the velocity I'm calculating takes into count the deltaT as well. So it is average velocity over the frame period. \$\endgroup\$ – JeffV Jan 26 '18 at 15:30
  • 8
    \$\begingroup\$ Anyway, how do you calculate the position updates without calculating velocity in the first place? \$\endgroup\$ – Ocelot Jan 26 '18 at 15:35
  • \$\begingroup\$ Opposite, I collect position from the engine and calculate velocity from that. v = (p0-p1)/dt; where p0 is current position. \$\endgroup\$ – JeffV Jan 26 '18 at 17:22
10
\$\begingroup\$

In the vast majority of situations, calling getVelocity is a vastly preferable approach.

  • You don't have to be polling objects on the off chance that next frame you are going to need a velocity (which requires the position from last frame). If I have 10,000 objects and nee the velocity of 10 of them on any given frame, there's no point in storing off 10,000 old positions.
  • The derived velocity you are getting is an "average velocity" over the frame. In many models, you want an instantaneous velocity.
  • In many physics based systems, the equations of motion actually calculate the new position using the velocity, not the other way around.
  • A velocity can be defined in the first frame, but you can't derive a velocity until the second frame.
  • Instantaneous velocities often have properties. For example, the velocity of an object in orbit is always 90 degrees from the direction from the object to the planet. This will not always be true with the average velocities you can get from a derived velocity.
  • a getVelocity function permits running the physics models at rates that are different from the frame rate. This can be useful if you need higher quality integration in your motion model.

I think you may be in a corner case where you happen to what to do all the extra effort required the derive an average velocity, so for you the two approaches are very similar. In most situations, they are not as similar.

\$\endgroup\$
  • \$\begingroup\$ Your orbit example is incorrect for any orbit except a circular one, and the two extreme points on an elliptical. Better is something like edge on a disc (wheels etc.). \$\endgroup\$ – Nij Jan 27 '18 at 1:28
  • \$\begingroup\$ @Nij Good catch. I was initially thinking of acceleration, which IS always towards the center, but then I tried to change thinking to velocity to match the OP's question better. \$\endgroup\$ – Cort Ammon - Reinstate Monica Jan 27 '18 at 3:37
  • \$\begingroup\$ Even then, acceleration is to the centre of mass, which is never the centre of a circular or (except for pure coincidence) elliptical orbit. \$\endgroup\$ – Nij Jan 27 '18 at 3:46
3
\$\begingroup\$

Deriving velocity from position is actually used in some games & parts of games, when the implementation uses Verlet integration or similar techniques.

Here we replace a conventional Euler integration step

$$\begin{align} \vec v_{t+1} &= \vec v_t + \vec A(t) \Delta t \\ \vec p_{t+1} &= \vec p_t + \vec v_t \Delta t \end{align}$$

(where \$\vec A(t)\$ is a function returning the average acceleration during the update at time \$t\$)

With a formula like this:

$$\vec p_{t+1} = 2 \vec p_t - \vec p_{t-1} + \vec A(t) \Delta t^2$$

So here we store \$\vec p_{t-1}\$ instead of \$\vec v_t\$ from one frame to another, effectively reconstructing \$\vec v_t \Delta t\$ from \$\vec p_t - \vec p_{t-1}\$

This entails an assumption that last update's \$\Delta t\$ is the same as this one, so when going this route you'll definitely want to use a fixed timestep to avoid strange and hard-to-debug divergence. (There are ways to approximately correct for time variations, but this only reduces the problem rather than eliminating it the way a fixed timestep does, and more simply too)

Verlet integration has good numerical stability compared to explicit Euler, and it's even time reversible, which is a neat trick.

It's also a really nice system to use when you want to implement custom constraints on objects - like keeping objects a minimum/maximum/fixed distance apart. You can apply your integration step, then snap your resulting position to the closest point satisfying the constraint, and you're done. The object's velocity implicitly reacts to the constraint because it's calculated from the position. This can make even complicated constraints & combinations very simple to author.

But, the behaviour of those constraints is not always physically plausible.

Imagine an object is at the rightmost extent of its constrained space, travelling rightward. In the next update, its integration takes it past its constrained envelope, and the constraint snaps it back to the edge - the same position it was in at the last timestep. Now in the next timestep, subtracting the two previous positions gives us zero: any momentum & energy the object had has simply vanished, rather than rebounding or transferring to another body in a physically-conserved way.

So, Verlet integration is not energy-preserving, and it's more challenging to represent realistic elastic collisions with it, or other situations where the velocity changes discontinuously. (This is related to Cort Ammon's point that comparing positions is implicitly working with average velocity, when many applications want an instantaneous velocity)

For some applications, this is actually desirable: the energy leak acts as a damper and improves the stability of the simulation, reducing jitter or spontaneous launching-to-infinity glitches you might see in other setups.

Myself, I like using Verlet integration when I need some simple dynamic/reactive movement with constraints for visual effects, where physically correct collision response isn't a big deal and I can afford some leakage, like particle systems or googly / bobblehead effects. Here the simplicity of the code even in the presence of constraints (like springs / limits on the bobble swing range) is a big win, and the stability properties mean I don't need to worry as much about the effect freaking out under varying sim conditions, letting me play with more extremes and not get bogged down in parameter fine-tuning.

\$\endgroup\$
  • \$\begingroup\$ You can adjust the "previous" position by subtracting the would-be velocity: if an object went from $a$ to $b$ (so the velocity $v=b-a$), but has to be moved back to $m$ (between $a$ and $b$), you assign $m+(b-a)$ to the $x_{prev}$ and then $m$ to $x_{curr}$, so the constraint is satisfied, but on the next step the velocity will be $m-(m+(b-a))=-(b-a)$ — the object is reflected perfectly elastically. \$\endgroup\$ – Joker_vD Jan 27 '18 at 0:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.