Three.js: GLTFLoader/SkinnedMesh: Mesh rotated by +/- 90º

Created on 1 Feb 2020  ·  7Comments  ·  Source: mrdoob/three.js

Description of the problem

As reported in https://github.com/KhronosGroup/glTF-Blender-IO/issues/856, the model below appears rotated by 90º around the X axis in three.js, when any of the included animations are played. In several other viewers (BabylonJS, glTF-Sample-Viewer, Blender), the model appears upright.

^The second link also contains a second version of the model, game_man_packed.glb. The only difference is that the second has been optimized by gltfpack — and for some reason it then renders correctly. 🤔

| expected | three.js |
|----|---|
| babylon | three |

The glTF validator reports several possible issues with this model (joint weights should be normalized, and so on) but nothing that looked like an obvious cause to me.

For a quick way to preview the problem, drag the model into https://threejs.org/editor/ or https://gltf-viewer.donmccurdy.com/, then play the Idle animation (or any animation with an obvious upright pose). In my viewer, the model itself is accessible as content from the JS console.

Three.js version
  • [ ] Dev
  • [x] r113
  • [ ] ...
Bug

Most helpful comment

Wow... that's... yeah. Confirmed, renaming the node (I edited the original .glb by hand) fixes the issue.

(╯°□°)╯︵ ┻━┻

Either we need to escape this name in PropertyBinding.sanitizeNodeName, or remove the special case entirely. I think I'd vote for the latter.

Thanks for finding that! Had not occurred to me at all.

All 7 comments

It's resting... 🤡

The only difference is that the second has been optimized by gltfpack — and for some reason it then renders correctly. 🤔

I've tried to compare both glb files today but noticed that the asset data are extensively change by gltfpack. Meaning geometry, transformation and even the animation data are different. That makes it really hard to compare both assets. Although they represent the same character, they are totally different from a technical point of view.

The other github issue in context of glTF-Blender-IO mentions a rotation of the root bone by 90° around the x axis. Indeed, removing this transformation makes the animation look correct. There must be a place in the three.js code base where this transformation is not honored correctly.

^That 90º rotation sounds like the right place to look, yes. The glTF skinning spec mentions that:

Client implementations should apply only the transform of the skeleton root [joint] node to the skinned mesh while ignoring the transform of the skinned mesh node.

As far as I can tell we're doing that – moving the SkinnedMesh has no effect (except to trigger frustum culling at some point) and moving the root bone does. Why it's 90º off, I'm still not sure.

It seems it works if the bone root is renamed to something different. Can someone please verify^^? This is my updated glb exported from Blender 2.81a: game_man_sketchbookb1.glb.zip

Notice that root has a special semantics in the three.js animation system. I've not debugged this in detail so far but I guess there is a side effect.

Wow... that's... yeah. Confirmed, renaming the node (I edited the original .glb by hand) fixes the issue.

(╯°□°)╯︵ ┻━┻

Either we need to escape this name in PropertyBinding.sanitizeNodeName, or remove the special case entirely. I think I'd vote for the latter.

Thanks for finding that! Had not occurred to me at all.

"root" name issue has been discussed here, too https://github.com/mrdoob/three.js/issues/16693

We should finally fix this issue for the next release. I think I still favor an enhancing of PropertyBinding.sanitizeNodeName().

Was this page helpful?
0 / 5 - 0 ratings