Removing all bones in a skeleton causes glitch

Hi all,

How does one remove all bones in a skeleton without glitching the attached meshes?

Original
image

Then after skeleton.bones.length = []

Here’s a PG https://playground.babylonjs.com/#SYQW69#997

@Deltakosh @Evgeni_Popov

This is expected
A skeleton cannot have 0 bone. It requires at least one

1 Like

Ok, what’s the best way to rid a mesh of its skeleton?
I’ve tried doing mesh.skeleton = null but that runs into all sorts of issues

mesh.skeleton = null is the way to go :slight_smile:

1 Like

Ok, but then how do I handle this case? :slight_smile:

Before:
image

After mesh.skeleton = null
image

Becomes a very small dot due to how the skeleton was scaled

I know there is the mesh.computeBonesUsingShaders = false hack but was wondering if there’s a better way

Well this is not a hack :slight_smile: you want to get rid of the skeleton after forcing it to bake its value into the mesh

Why don’t you like the solution I gave you?

probably due to a lack of knowledge about computeBonesUsingShaders on my side I guess :sweat_smile:
So basically, if anytime a skeleton is removed, we have to always use mesh.computeBonesUsingShaders = false?

Yes, if you want to force the CPU to compute the transformation and apply them to your mesh

By default bones are evaluated at the GPU level which means that the CPU has no idea how the final mesh will look like. In your case (as I assume you want to save the mesh with the transformation applied), you need the local CPU data to be updated to save it

1 Like

yea gotcha, my question is how do I effectively save it so that it doesn’t affect other things :smiley:

let’s say I remove the skeleton using mesh.skeleton = null, then use mesh.computeBonesUsingShaders = false (since = true will cause the mesh in this example to scale very small), how do I save the mesh data into the transforms so that mesh.computeBonesUsingShaders = true/false will be the same?

My worry as a dev is that if mesh.computeBonesUsingShaders = true again, it will cause the mesh to scale again, not to mention if this might impact exports GLTF etc, or cause other unintended side effects

One example of an unintended side effect is this PG, I try to bakeCurrentTransformIntoVertices but unfortunately it bakes it to the state where mesh.computeBoneShaders = true, even if I had set it to false. So it seems that the skeleton is still impacting the mesh data one way or another even though mesh.skeleton = null

I have looked into the source code but just wondering if there is a more dev friendly way to properly get rid of a skeleton while preserving the mesh vertices data? :pray:

There is a misunderstanding here. If skeleton is null then computeBonesUsingSHaders has no impact as there is no skeleton. That property is simply asking the system to compute the skeleton deformation using the CPU or the GPU

You cannot have both. Either there is a skeleton and then the deformation is applied at render time (using CPU or GPU) and in this case the mesh vertex data is un changed OR you want to get rid of the skeleton and then you have to bake the skeleton deformation INTO the vertex data and then you will lose the original data

Does it make sense?

1 Like

If skeleton is null then computeBonesUsingSHaders has no impact as there is no skeleton.

Ok I think that’s where my confusion/misunderstanding arises from
In this thread below, the solution is mesh.computeBonesUsingShaders = false to deal with a similar issue, so I thought that computeBonesUsingShaders = false/true were different

“then you have to bake the skeleton deformation INTO the vertex data”

Right! That’s actually what I meant by ‘preserve’ i.e. baking it to ‘preserve’ the shape, not to preserve the original data.

How do I do this?

Is it
const verts = mesh.getPositionData(true, true) mesh.setVerticesData('position', verts)

Indeed that seemed to have done the trick https://playground.babylonjs.com/#SYQW69#1006

const verts = mesh.getPositionData(true, true)
mesh.setVerticesData('position', verts)
mesh.skeleton = null
mesh.createNormals()

@Deltakosh thanks so much again!!

1 Like

I’m glad we find a way to do what you wanted!

Really cool buddy!

2 Likes

I actually found a related bug with computeBonesUsingShaders in this thread, linking it here in case :slight_smile:

This solution did not work for a mesh that had its Plugin Material enabled. But I could not replicate this in a Playground so it is probably more complex.

Anyway, whenever you experience a 1-frame vertex explosion right into the camera when trying to unassign a skeleton and the above solution does not work, try this:

 private bakeSkeleton(actor : ActorBase, doesNeedExtendedCleanup : boolean) {
    const coroutine = function*() {
        const rootMesh = actor.getRootMesh();  
        const mainMesh = actor.getCharacterMesh();
  
        //Prevents possible vertex explosion (probably if anim still running)
        actor.animations.destroy();
  
        //Prevents some vertices to explode into player's face
        if(doesNeedExtendedCleanup) {
            mainMesh.resetDrawCache();
        }

        //(...)            

        //"Bake" skeleton to vertices
        mainMesh.computeBonesUsingShaders = false;

        //Prevents 1-fame flickering of mesh               
        if(doesNeedExtendedCleanup && mainMesh.subMeshes) {
            for(const subMesh of mesh.subMeshes) {
                mainMesh.render(subMesh, false);
            }                    
        }                

        //Prevents mesh from going to T-Pose
        yield;

        mainMesh.skeleton = null;    

        actor.skeleton.dispose();
    };
  
    return scene.onBeforeRenderObservable.runCoroutineAsync(coroutine());
}

Hopefully saves anyone hours of debugging :sleeping: