Issues with Ragdolls (physics v2)

after a few days of trying to use the ragdoll feature, I concluded that it’s not really usable in its current state as of 6.48.1.
I’m leaving my findings to inform other people before they waste time, and hopefully as a improvement roadmap :slight_smile:
I tried to list them by order of importance:

  • The current implementation only supports box shapes and ball and socket joints. This is not documented but the joint, min & max options are not actually used in the code.
    I found out this presentation from the author of box2d which shows a more typical setup for humanoid ragdolls: sphere & capsules as shapes, cone joint and hinge joints.
    The ball and socket joints have no angle limit which makes the limbs go rogue too easily.
    The older library for physics V1 mentioned in this forum topic seems to behave better and maintain some rigidity.
    There is no cone joint in the docs but I’m guessing it could be done with a 6DOF constraint.

  • When the ragdoll is moved away from the original position, there are camera culling issues and the mesh can disappear. Here is a repro playground: activate the ragdoll then apply a few impulses until the ragdoll falls down. The mesh will become invisible
    This problem & solution is described on page 34 of Erin Catto’s doc.

  • There an issue when some scale is applied along the hierarchy, which is typical with mixamo models exported to .fbx and then converted to .glb
    Here is a playground with the Elf from the asset library: when ragdoll is activated, the scale of the model is changed.

  • There is no function to disable to ragdoll and dispose() looks incomplete as it’s not disposing its transform nodes nor relinking the bones back to their original transform nodes

  • When a mesh is attached to a bone (e.g. a hat attached to the head) it won’t work out of the box. A workaround is to fetch the ragdoll transform node from private fields and set it as a new parent for the mesh (and revert when you disable the ragdoll). It would help to be able at least to get a transform node or aggregate by their bone name.

cc @Cedric

The playground Babylon version is still in 6.47… Maybe there is an impact…

I wasn’t sure ragdoll would get a lot of traction but I’m glad it does :slight_smile:
Definitely a list of things to put in the roadmap for a second version.
The scaling/hierarchy lefthandness/righthandness is the feature that seems the most difficult to me.
It’s more or less related to transform_node. Maybe injecting physics data into the transform instead of the bone would be better.
for the dispose, I’d like to hear from users. re-linking transform will make the skeleton to move back to animated state. so it can be weird to see it pop up animated.
Maybe intermediate states so it’s possible to re-use physics/skeleto datas instead of disposing/re-creating things.

I’m not sure I get all context for the scaling/hierarchy/LH/RH problems but what I can say is I try to remove as much as possible these __root__ nodes the glb importer is adding. This is kind of trivial by calling setParent(null) for all its children.
I honestly don’t know what the real problem is with the elf as the scaling seems to be 1 for all nodes. I tried before with YBot export from mixamo (fbx converted to glb so an armature scale of 0.01) and the same issue was present (of course with a much more dramatic x100 effect). This scaling is not a problem in my setup as I make sure to reset all scaling to 1 when creating characters (it’s generally causing lots of issues) but it could be a clue for other issues in the ragdoll code.

For the dispose, an abrupt pop up back to animated would not really be an issue in my use case where the ragdoll is activated upon death and disabled upon character recycling.
Erin Catto is mentioning the inverse problem page 36

When we spawn a ragdoll, we have to create the bodies where the character’s
bones are currently located. There is no guarantee that the animated pose
conforms to the ragdoll constraints, so joints may be stretched and joint limits
may be violated.

We could go through all the joints and try to fix them up by shifting the
bodies. However, if you have a good physics engine, it will smoothly eliminate
the joint errors over time so you don’t have to worry about this problem too

So what’s difficult for creating a ragdoll from an animated pose might be also difficult in the other way.
It seems the solution turns around a progressive blending between physics bone position and animation bone position and that looks like an optional feature. Well, now that I think about it, it doesn’t seem so complex to add a weight property and interpolate with the original (animated) bone transforms in _syncBonesAndBoxes()

The L/RH issue is, at least in part, because of negative scaling. When importing a GLB in LH scene, the root node has a rotation and a scaling of (1,1,-1).
Depending on the stack of manipulation in the engine, that negative scale can be lost. For example when decomposing a world matrix in orientation/translation/scaling.
It’s mostly when converting from world coordinates of the bodies to bone local coordinates .

I had way less troubles doing the bones to bodies coordinate conversion.

I’m pretty confident in Havok ability to resolves joints errors over time. At least, I didn’t get a case where that can be an issue. Moreover, it’s possible to disable collsions between bodies joined together.

If you want to try to do the body->bone coordinates conversion in left handness scene, I can show you where to look at. I believe at the end, it might only be like 5 to 10 Lines to fix :slight_smile:

1 Like