@@ -824,8 +824,6 @@ class FBXTreeParser {
824824 indices : [ ] ,
825825 weights : [ ] ,
826826 transformLink : new Matrix4 ( ) . fromArray ( boneNode . TransformLink . a ) ,
827- // transform: new Matrix4().fromArray( boneNode.Transform.a ),
828- // linkMode: boneNode.Mode,
829827
830828 } ;
831829
@@ -918,8 +916,6 @@ class FBXTreeParser {
918916
919917 } ) ;
920918
921- this . bindSkeleton ( deformers . skeletons , geometryMap , modelMap ) ;
922-
923919 this . addGlobalSceneSettings ( ) ;
924920
925921 sceneGraph . traverse ( function ( node ) {
@@ -942,6 +938,13 @@ class FBXTreeParser {
942938
943939 } ) ;
944940
941+ // Bind skeletons after transforms are applied so that bind matrices
942+ // are computed from the final scene state. This ensures the rest pose
943+ // is correct even when the FBX file's Cluster TransformLink matrices
944+ // differ from the reconstructed bone transforms (common in files
945+ // without a BindPose section).
946+ this . bindSkeleton ( deformers . skeletons , geometryMap , modelMap ) ;
947+
945948 const animations = new AnimationParser ( ) . parse ( ) ;
946949
947950 // if all the models where already combined in a single group, just return that
@@ -1466,6 +1469,26 @@ class FBXTreeParser {
14661469
14671470 const skeleton = skeletons [ ID ] ;
14681471
1472+ // Compute bone inverses from TransformLink rather than from the
1473+ // bones' current matrixWorld. The TransformLink matrices represent
1474+ // each bone's global transform at the time the skin weights were
1475+ // painted, which may differ from the scene-reconstructed transforms.
1476+ const boneInverses = [ ] ;
1477+
1478+ for ( let i = 0 , l = skeleton . bones . length ; i < l ; i ++ ) {
1479+
1480+ const inverse = new Matrix4 ( ) ;
1481+
1482+ if ( skeleton . bones [ i ] && skeleton . rawBones [ i ] ) {
1483+
1484+ inverse . copy ( skeleton . rawBones [ i ] . transformLink ) . invert ( ) ;
1485+
1486+ }
1487+
1488+ boneInverses . push ( inverse ) ;
1489+
1490+ }
1491+
14691492 const parents = connections . get ( parseInt ( skeleton . ID ) ) . parents ;
14701493
14711494 parents . forEach ( function ( parent ) {
@@ -1481,7 +1504,19 @@ class FBXTreeParser {
14811504
14821505 const model = modelMap . get ( geoConnParent . ID ) ;
14831506
1484- model . bind ( new Skeleton ( skeleton . bones ) , bindMatrices [ geoConnParent . ID ] ) ;
1507+ // Always provide a bind matrix to prevent bind() from
1508+ // calling calculateInverses() which would overwrite the
1509+ // TransformLink-based bone inverses computed above.
1510+ let bindMatrix = bindMatrices [ geoConnParent . ID ] ;
1511+
1512+ if ( bindMatrix === undefined ) {
1513+
1514+ model . updateMatrixWorld ( true ) ;
1515+ bindMatrix = model . matrixWorld ;
1516+
1517+ }
1518+
1519+ model . bind ( new Skeleton ( skeleton . bones , boneInverses ) , bindMatrix ) ;
14851520
14861521 }
14871522
0 commit comments