Joint with child of zero mass, problems?

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Joint with child of zero mass, problems?

Postby JoshKlint » Sat May 10, 2025 9:30 pm

I'm seeing some mysterious behavior when I use a dCustomSliderActuator joint with a child body that has zero mass. I am using this for sliding doors. The mass has to be set to zero when the doors are fully closed, to prevent objects from forcing the doors open.

The problem is calling my player to fall through the floor, I think due to failed calls to NewtonConvexCast() for checking the floor. I also sometimes experience my application freeze up with very high CPU usage, and Visual Studio just says "the application is in break mode".

I added a check for zero mass in the SubmitAngularRow function, but it does not prevent the problem.
Code: Select all
void dCustomSliderActuator::SubmitAngularRow(const dMatrix& matrix0, const dMatrix& matrix1, dFloat timestep)
{
   float mass, ixx, iyy, izz;
   NewtonBodyGetMass(this->m_body0, &mass, &ixx, &iyy, &izz);
   if (mass <= 0.0f) return;

Can you please tell me if this is triggering a problem you would understand, and if there is anything I can do to avoid it? The problem has been going on for over a year and it's a big issue for my game, because about 10% of the time the player falls through the floor when opening a door. It's very hard to reproduce this bug reliably, so it is very hard to solve.
JoshKlint
 
Posts: 184
Joined: Sun Dec 10, 2017 8:03 pm

Re: Joint with child of zero mass, problems?

Postby JoshKlint » Sun May 11, 2025 8:46 pm

Even after disabling this, I still saw the same problem, just less frequently. I was also experiencing a deadlock once every 20 runs or so. These problems went away when I set the max physics threads to one. I think I will need to have a closer look at my overlap and contact callbacks.
JoshKlint
 
Posts: 184
Joined: Sun Dec 10, 2017 8:03 pm

Re: Joint with child of zero mass, problems?

Postby Julio Jerez » Sun May 11, 2025 11:02 pm

that code seems form 3.xx
but for any version, you can't have a joint that link two bodies with zero mass.
that generates a divide by zero in the mass matrix.

why do you have to change the mass to zero when the door is close?
you just let it set and it should work.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joint with child of zero mass, problems?

Postby JoshKlint » Tue May 13, 2025 9:16 am

If the player pushes against the door, they can still make it move and sometimes even open it, even if the maximum force of the joint is very big.

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?
JoshKlint
 
Posts: 184
Joined: Sun Dec 10, 2017 8:03 pm

Re: Joint with child of zero mass, problems?

Postby Julio Jerez » Tue May 13, 2025 12:38 pm

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.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron