Skip to main content
GameDev.net gamedev.net
🔒 Locked

Accuracy of physics constraints

Started by jcabeleira Jul 6 at 6:49 PM 3 replies 350+ views
Original Post
jcabeleira
jcabeleira

Hello all, I've observed some weird behavior on my physics engine that I think is not a bug but a limitation of how constraints are usually defined and implemented in physics engines. But I might have understood the whole theory wrong so I'd like to hear your opinion on it.

So, let me present my case with a simple example: imagine we have a static wall (no constraints, just static geometry) and we throw a ball at it. Given that the wall is static all the collision energy is transferred back to the ball which ends up doing all the bouncing back

Now, lets replace the wall by a dynamic object of the same shape but with a finite mass and a fixed/weld constraint to make it static. So now when we throw a ball at it this is what happens in a sequential solver:

  1. The energy of the impact is transferred to both objects according to their mass ratio and the objects start moving away from each other

  2. The wall is now moving which violates the fixed constraint, so the constraint kicks in to apply an impulse that negates that velocity and make it static again

  3. The wall is now static and the ball is bouncing back like the first scenario, but the ball is moving slower than before because only part of the collision energy was transferred to it

So, essentially, the problem is that the constraints correct and negate invalid motion but don't necessarily react to the forces that caused the violation. In some circumstances, the sequential impulse solver might still apply additional collision impulse to the ball, but it will never be the full collision energy as if the wall was really static.

Is my understanding correct or am I missing something?

JoeJ
JoeJ

jcabeleira wrote:

The wall is now static and the ball is bouncing back like the first scenario, but the ball is moving slower than before because only part of the collision energy was transferred to it

That's not correct, but you can still do it if it works well enough.
I know a similar example from the Newton physics engine i'm using. In this engine kinetic bodies do not have infinite mass, but some value given by the user, meant to be high enough so it can push back any dynamic body. Otherwise it works as you described - the energy applied to the kinetic body is lost afaik. So it's wrong in the same way, but works well enough in practice.

But i would be still worried about making dynamic bodies temporally static assuming their constraints are all resolved and they should not move. The simple example you give may work, but a complicated example with many other bodies involved may break and behave weird.

The correct way would ofc. be like: The wall body is dynamic and never becomes static. The contact energy from the ball should be reflected by 100% only due to the forces applied from the fixed joint to the wall in response to the ball collision. But ofc. this requires more solver iterations to converge towards correct results.
Ideally you also have some given max force the fixed joint can apply, so huge forces can be prevented. The wall may bend under a heavy object, but that's better than blowing up the whole simulation up due to a heavy object propelled around from huge forces. Though, ofc. such limits increase costs too.

There surely is no single right answer to your question. Different engines make different trade offs about performance vs. accuracy, and they use different hacks to fix one problem for eventually introducing another.


LorenzoGatti
LorenzoGatti

Perfectly elastic bouncing would probably be, in turn, inconvenient and unrealistic. If your system doesn't lose energy, not only it never reaches a rest state, but small errors such as rounding the wrong way can cause a spurious accumulation of energy and visible instability. Before depriving your game of a slightly inelastic wall, think what other options for removing energy you have.

Omae Wa Mou Shindeiru
Aressera
Aressera

jcabeleira wrote:

  1. The energy of the impact is transferred to both objects according to their mass ratio and the objects start moving away from each other

  2. The wall is now moving which violates the fixed constraint, so the constraint kicks in to apply an impulse that negates that velocity and make it static again

  3. The wall is now static and the ball is bouncing back like the first scenario, but the ball is moving slower than before because only part of the collision energy was transferred to it

This is just one iteration of the sequential impulse solver. To get accuracy you need to repeat steps 1 to 3 until the applied impulse (or velocity delta) shrinks below an error threshold. For good convergence, it helps a lot to randomize the order in which constraints are solved on each iteration, so that no single constraint can dominate the others. What this is doing is solving a system of linear equations to satisfy all velocity constraints. Once you have more than one constraint in an island (the collision constraint and the rigid constraint in your example), you need to iterate to get correct global behavior.

For the case of elastic collisions, you get the correct bounce velocity by determining what it should be based on the mass ratio and coefficient of restitution in a pre-step before any iterations (this is also where accumulated impulse from the previous frame is applied to warm-start the solver). Then, each iteration tries to make the relative velocity along the normal direction equal to that predetermined bounce speed by applying impulses, rather than just ensuring the velocity is separating the objects.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.