Hi all,
How does one remove all bones in a skeleton without glitching the attached meshes?
Original
Then after skeleton.bones.length = []
Here’s a PG https://playground.babylonjs.com/#SYQW69#997
Hi all,
How does one remove all bones in a skeleton without glitching the attached meshes?
Original
Then after skeleton.bones.length = []
Here’s a PG https://playground.babylonjs.com/#SYQW69#997
This is expected
A skeleton cannot have 0 bone. It requires at least one
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
Ok, but then how do I handle this case?
Before:
After mesh.skeleton = null
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 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
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
yea gotcha, my question is how do I effectively save it so that it doesn’t affect other things
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?
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?
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!!
I’m glad we find a way to do what you wanted!
Really cool buddy!
I actually found a related bug with computeBonesUsingShaders in this thread, linking it here in case
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