KhronosGroup / glTF-Blender-IO

Blender glTF 2.0 importer and exporter
https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html
Apache License 2.0
1.49k stars 317 forks source link

Feature request: Export joints at bone tails #1261

Closed rdb closed 2 months ago

rdb commented 3 years ago

Is your feature request related to a problem? Please describe. The glTF exporter currently exports each bone as one joint, positioned at the head of the bone. This is adequate for simple animations, but causes significant problems with techniques such as IK. The following illustration shows how an engine will read the bone structure: image Because the head of each child bone is positioned relative to the head of the parent bone, pulling on a child bone will cause the bone to split (see animation at the bottom).

Describe the solution you'd like I think there are two ways to solve this issue:

  1. Place an extra joint at the root, and place each subsequent joint at the tail end of each bone. This solution minimizes the creation of additional joints.
  2. Place a dummy joint at the end of each joint that has multiple child bones. Connected child bones will be parented to the end joint and get a position of (0, 0, 0). This solution will increase the number of joint, but better deals with disconnected bones.

I would personally suggest option 2 (enabled using an exporter option), which is probably easier to implement as well. Additionally, the Blender glTF importer could recognise this structure and use it to reconstruct bone lengths and connectedness without having to rely on heuristics, enabling better round-tripping.

If there is agreement on how this should be done, I would be happy to see if I can find some time to work on this.

Describe alternatives you've considered The FBX exporter does appear to support this feature via the "Add Leaf Bone" option. However, the engine I am using does not have a reliable FBX importer.

I have attempted to change the IK algorithm to try to regard all child joints as being positionally linked. This is fragile since various non-Blender glTF sample models will break with that approach, and furthermore, it will fail for disconnected bones.

Additional context This animation demonstrates the issue when attempting to perform IK: ezgif-1-5578f4b47322

julienduroure commented 3 years ago

Before investigate your proposal, a question : did you test the "export only deformation bones" ? It solves most of constraint by issue (including IK ones)

rdb commented 3 years ago

@julienduroure That seemed to create an additional leaf bone at the end of each chain, but it did nothing to solve the primary issue, namely that the child joints are attached to the head of the parent bone and therefore the parent bone gets split into 3 bones.

julienduroure commented 3 years ago

I am not sure to fully understand. Can you please share your example .blend file, it will help taking to same thing :)

rdb commented 3 years ago

Certainly. thingy.zip The structure of the exported joints is as follows:

 Bone  rot 0 -90 0
   Bone.001  trans 0 0 1
     Bone.002  trans 0 0 1
       Bone.006  trans 0 0 1
   Bone.003  rot 0 0 -38.3962 trans 0 0 1
     Bone.004  rot 0 0 38.3962 trans 0 0 1.12738
   Bone.005  rot 0 0 90 trans 0 0 1

As you can see, as child of "Bone" there are "Bone.001", "Bone.003", "Bone.005", each having a translation of (0, 0, 1). An engine performing IK will read this as three bones going from (0, 0, 0) to (0, 0, 1). I think my illustration in the original report shows this best. This structure would resolve this ambiguity:

 Bone  rot 0 -90 0
   Bone_end  trans 0 0 1
     Bone.001  trans 0 0 0
       ...
     Bone.003  rot 0 0 -38.3962 trans 0 0 0
       ...
     Bone.005  rot 0 0 90 trans 0 0 0
julienduroure commented 3 years ago

You're example file is not animated. What is your issue ? Bone hierarchy issue or animation issue ?

I tried to animate, and seems that https://gltf-viewer.donmccurdy.com/ and https://sandbox.babylonjs.com/ can read it correctly. See glb file in attachment:

thingy_animated.glb.zip

rdb commented 3 years ago

Thanks, but this is not a bug but a feature request. The request is for a feature that inserts additional joints to allow encoding bone tails, to help IK algorithms. It's not related to animation.

lemonJumps commented 11 months ago

Hi just wanted to add that adding leaf bones would be really really helpful for game developers specifically.

There are two parts to this really. The first one is that FBX does have this option and I've seen this used extensively for placing things like finger tip colliders, or wheel colliders, where the previous bone is used for both wheel pivot and rotation, in engines like godot and unity. (I'm speaking as a someone who's working on godot games, and makes vrchat avatars in unity)

An example of such car rig (the "wheel.b.r" bone ends are where the wheel collider would be placed): image

The second one is that FBX implementations everywhere really really suck, with issues ranging from scale settings not updating, to straight up crashes when you update the model. hence why people want to use glb/gltf (including me), but then gltf exporter doesn't create leafbones.

So the current work around is either add these bones manually or add them during asset preparation in the engine. I'd love if this was just a tickbox in blender, it would save me and no doubt others a lot of time.

lemonJumps commented 11 months ago

Actually... I've been thinking about this. Since in blender, you can specify both bone tip and bone root, wouldn't these ends of bones be considered joints, like gltf joints?

This actually feels like a bug, or at least wrong somewhat wrong.

amarraff commented 8 months ago

Hello, Godot game dev here. I just ran into an issue with my armature in-engine due to this; I am trying to make a ragdoll effect for my mesh, but the hand, feet, and head bones (all "tail bones") of my skeleton are not visible, even though they're in the armature's hierarchy in Godot. So, auto-generating physical bones did not generate one for any of those bones. I had to add physical bones for them manually. It would be a nice time saver if this behavior was changed to include the last bones on each chain. It is also just strange to see the skeleton not include those bones when checking to make sure it looks humanoid. The core is there, but none of the "tails."

julienduroure commented 8 months ago

This FBX feature (Add leaf bone : Append a final bone to the end of each chain to specify last bone length) is planned on glTF for Blender 4.2. Development is in progress

There is no plan to add it for each bone, only for the leaf bones

amarraff commented 8 months ago

There is no plan to add it for each bone, only for the leaf bones

I'm sorry, I'm not quite understanding what you mean. What do you mean by this?