Three.js: GLTFLoader animation: bind matrices are *always* identity.

Created on 18 Apr 2018  路  3Comments  路  Source: mrdoob/three.js

Description of the problem

It appears that when GLTFLoader creates SkinnedMesh's, and binds them, the 'matrixWorld' upon binding is always identity:
https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/GLTFLoader.js#L2823

From debugging (r89), it seems that mesh.parent == null, and thus mesh.matrixWorld is identity (and will still be even after you call updateMatrixWorld).

This results in animations being incorrect when the original mesh transform is not identity. SkinnedMesh.bindMatrix ends up being identity, resulting in incorrect skinning math.

We have implemented a successful work around by calling updateMatrixWorld and then bind on our own. But the loader should do this by default.

Three.js version
  • r89
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS

Most helpful comment

We tried this and it works, so I'll close this. Thanks!

All 3 comments

Related: https://github.com/KhronosGroup/glTF/pull/1195

Implementation Note: Client implementations should apply only the transform of the skeleton root node to the skinned mesh while ignoring the transform of the skinned mesh node.

OK...I see. I guess we should take the advice of the other implementation note then:

"Implementation Note: The matrix defining how to pose the skin's geometry for use with the joints ("Bind Shape Matrix") should be premultiplied to mesh data or to Inverse Bind Matrices."

Namely, exporting inverse bind matrix as (boneFromWorld) * (worldFromModel).

We'll give this a shot. I'm curious what the pros/cons of this, but it seems Unity does the same thing.

We tried this and it works, so I'll close this. Thanks!

Was this page helpful?
0 / 5 - 0 ratings