Hi,
I’m stuck on a skinning issue I can’t resolve despite extensive debugging. I have a character rig exported from Blender 5.0.1 to GLB, loaded via SceneLoader.ImportMesh. The skeleton has 100 bones, properly linked to the mesh (confirmed via Weight Paint in Blender — vertex groups exist and have correct non-zero weights for the bones I’m testing).
The problem: when I rotate a bone in JavaScript (e.g. Spine_01), the rotation value changes correctly in memory (confirmed via console.log every frame, values oscillate as expected), but the mesh never visually deforms. The skeleton lines (via SkeletonViewer) also stay frozen in rest pose.
What I’ve already ruled out:
- The bone uses
rotationQuaternion(not Eulerrotation) — I update the quaternion correctly each frame, confirmed by logging it changes. squelette.prepare()called every frame — no effect.- No animations or Animatables running that could override it (
scene.animatables.length === 0,getAnimationRanges()empty). - Tried
registerBeforeRenderandregisterAfterRender— same result. numBoneInfluencersis 4 (default),needInitialSkinMatrixis false.- Tested on a manually-built mesh + skeleton (cylinder, 2 bones, manual
MatricesIndicesKind/MatricesWeightsKind) in the same project — this one animates perfectly with the exact same quaternion code. - Tested the exact same minimal skinning code in the official Playground — works perfectly.
- Tested with a second, completely different GLB export (older Sketchfab rig, different bone names) — same frozen behavior.
- Weight Paint in Blender confirms gradient weights exist on the relevant bone for the relevant mesh.
So the manual skinning approach works fine in this exact environment, but imported GLB skinned meshes stay frozen no matter what I do to the bones in code, even though the bone data updates correctly in memory.
Babylon.js version: 9.12.1, WebGL2.
I’d really appreciate help inspecting the GLB file itself if anyone has bandwidth — I suspect something in the Blender glTF export (inverse bind matrices? duplicate bone indices?) but I can’t pinpoint it from the JS side alone. I can provide the .glb file directly.
Playground reproducing the working manual-skinning case (for comparison).
Playground reproducing the issue with the imported GLB:
Playground showing the same quaternion bone rotation code working with a manually created skeleton (cylinder test):