JoshKlint wrote:If I make SubmitAngularRow return early if the child joint has mass zero, will that eliminate the divide by zero? Is there any other place in the code where joint forces get calculated?
No, that is not going to work, you can't have a joint linking two bodies with zero mass.
that's the equivalent of trying to outsmart arithmetic and figure out the solution of y = x / 0. By doing * like
X = y * 0 and deducing that y is 47 simply because when substituting, it generated 0.
And that's just wrong.
What kind of body is your player? I assume kinematic.
In the demos, players are represented as kinematic bodies, but they are not assigned zero mass (ie., infinite mass).
In the SDK, a kinematic body is essentially the same as a dynamic body, except its velocity is not integrated after the solver step.
If a player has infinite mass, here’s what happens during a collision with, for example, a door:
When the player and the door collide for the first time, the solver calculates the forces needed to enforce the joint constraints.
These forces are applied to both the door and the player.
The door will deflect slightly, depending on the joint stiffness.
However, no integration is applied to the player because it's kinematic.
In the following frames, the player continues to push.
With each solver iteration, the door takes the full deflection since it can't push a static body with velocity.
Eventually, one of several things may occur:
The deflection becomes large enough that the player can force the door open.
The collision resolution isn't strong enough, allowing the player to penetrate through the door.
The numerical calculations accumulate enough errors that the solver becomes unstable and fails.
To prevent this, Newton assigns a finite mass to kinematic objects.
When you create your own player controller,
be sure to assign a realistic mass, something appropriate for a human body.
By doing so, the controller can still push against the door.
The solver will calculate the interaction forces:
it will apply the appropriate portion to the door while ignoring the portion intended for the player (since it's kinematic).
In subsequent frames, the door will eventually reach a maximum deflection, where the applied forces are balanced by the door’s resistance.
Note:
In newton 3.xx and even later version of 4:00
the joint where all solved with a direct solver, I call the skeleton solver.
to handle the weakness for contacts, the skeleton solver collected all the immediate contacts and solve them all together.
That was fine, but if you have a case like a stack, the first object that was in contact with any of the objects collected by the skeleton but did not touch the skeleton, they experience deep penetration.
to solve that l, I added a heuristic that I used in newton 1.xx
in newton 1.xx everything was one giant skeleton solver. but that became very slow when adding all many contacts.
Now what it does, is that each skeleton collects up to five layers of contacts.
that way, those contacts are really strong because they go over a direct solver. And the penetration dissipates as the lump of bodies add more mass.
there are some other things that help to not slow down, like in 1.xx the solver was first a conjugate gradient, them Cholesky, which are all expensive. Now is linear time.
you should get the latest 4:00 to get that optimization.