PurpleKingdomGames / indigo

An FP game engine for Scala.
https://indigoengine.io/
MIT License
648 stars 60 forks source link

Physics iterations #694

Closed davesmith00000 closed 9 months ago

davesmith00000 commented 9 months ago

This work adds iterative solving to the physics engine.

The idea is very simple but they're good at making it sound complicated, or maybe I'm just not clever enough to really appreciate it. (Very likely.)

In the current version of Indigo we solve all collisions once and average out the result. Surprisingly, this works kind of ok, but it inevitably means that it's possible in a multi collision scenario, to end up in an undesirable state. This is always possible, but we'd like to reduce the likelihood of that happening. But how?

Well it turns out, the easiest thing to do, is to just keep solving. So for each frame, instead of solving all collisions once, we do it repeatedly until one of two states occurs:

  1. Convergence - we reach a state where there are no more collisions to solve.
  2. Divergence - we can't resolve a good state in an acceptable time frame, so we give up and hope it sorts itself out next time.

There is a new maxIterations param in the SimulationSettings and this tells the engine how many times to run the solver per frame. The default is 4, but it makes quite a difference to the hygiene(?) of the results. Now you can trade off accuracy for performance. For example, if all you're doing is spraying bullets and reporting collisions, set iterations to 1 but that's more than good enough; but if you're simulating a bunch of collisions and need more accuracy, dial up the iterations.

Known problem: This is particularly in relation to the sticky corners problem, if the iterations are too high, then sticky corners can become a bigger problem. Experiment and adjust as necessary for now.