Reset rest pose of skinned mesh programmatically

Hi all,

I have a issue in my current project and I am mentioning the steps I am following:

Step 1: I am importing a skinned model using ImportMesh in glb format (these are exported from Blender)

Step 2: Once imported I am changing the bone position using scene.getTransformNodeByName(bone.name); (basically the user can input some parameters to change them, so it is a bit dynamic here)


So here it is transforming properly

Step 3: Then I am using the BABYLON.GLTF2Export to export it to .glb file. Now when viewing the file in a normal gltf viewer it works correctly
Using this tool to view: https://gltf-viewer.donmccurdy.com/

Step 4: When I open the same file in Google’s Sceneviewer Preview tool it is in it’s rest pose as defined in Blender when exporting

Sceneviewer Preview Link- Scene Viewer

Rest pose in Sceneviewer Preview

So essentially what I am trying to achieve here is to Reset the rest pose with the dynamic values when the user is exporting to GLB so that it works correctly with the Sceneviewer tool. Sceneviewer has a problem with skinned meshes so I think resetting the rest pose to the user defined values is the only idea that I got right now.

I have a seen a lot posts which got resolved relating to bones and skeletons by @Deltakosh @bghgary
It would be great if you can help me resolve the issue as I am on a deadline to complete this today
Thank you

Maybe you can try to go through each bone, get their current (local) transform matrix and call bone.setRestPose (or maybe bone.setBindPose) with this matrix and see how it comes… No guarantee, though, it’s mostly a shot in the dark…

1 Like

Many thanks for the answer.

I tried both bone.setRestPose and bone.setBindPose
bone.setBindPose does work for babylon but the values are not preserved for the exported GLB

I am calling the below code in the onSuccess callback of the ImportMesh
Attaching code for reference:

 // Getting Local Matrix and storing in bone Bind pose
   skeletons.forEach(skel => {
                skel.bones.forEach(bone => {
                    var localMatrix = bone.getLocalMatrix();
                    bone.setBindPose(localMatrix);
                    // bone.setRestPose(localMatrix);
                });
            }); 

    // Return to rest - to check whether the change is reflected
            skeletons.forEach(skel => {
                skel.bones.forEach(bone => {
                    bone.setRestPose(bone.getBindPose());
                });
                skel.returnToRest();
            });

The code I am using for downloading the glb

BABYLON.GLTF2Export.GLBAsync(scene, "scene").then((glb) => {         
            glb.downloadFiles();
        });

The exported GLB does not change in the Sceneviewer Preview

Maybe try to use the matrix retrieved through bone.getTransformNode() as you are directly modifying the transform node matrix.

From a quick scan, it doesn’t look like we read the bind or rest pose on export and thus changing them won’t do anything. @Drigax may know more.

Currently it doesn’t appear that we are using the rest pose at export. Currently we export our skeletons to glTF using the current pose of the bones in this frame. Though the behavior you’re seeing is a bit confusing, I’m not sure why the rest of the pose is changing…

I suppose we should change the exporter behavior to use the rest pose instead of the current frame’s pose, though.

@mohan_yadav, can you create a playground where you load, modify and export an asset that reproduces this? I’ve never quite seen this in the test skeletons I’ve worked with.