Dynamically add bones to skinned mesh

Hey,
I was wondering if there is some way to update (add,remove) mesh bones after they’ve been added once with this code.

mesh.add(rootBone);
mesh.bind(skeleton);

You have to consider (at least) two things when updating a skeleton:

  • You also have to update the geometry of the skinned mesh. To be more precise, the skinIndex and skinWeight attributes always have to reflect the amount and correct influence of bones.
  • When you just add bones to a skeleton, the boneMatrices property of Skeleton does not automatically update. I guess it’s better to create a new Skeleton when the bone hierarchy changes and then perform a new SkinnedMesh.bind().
1 Like

Hey Michael,
can you please also clarify algorithm for skinIndices and skinWeights calculation from bones position and rotation?
Assuming that my object is 2D I’m guessing it should be some distance calculation from bones position to vertex position, is it so?
Also I’m not sure how to understand this code from examples source. Can’t see how this code is related to bones coordinates.

let geometry = this.geometry,
    position = geometry.attributes.position;
let vertex = new Vector3();
let skinIndices = [];
let skinWeights = [];
for (let i = 0; i < position.count; i++) {
    vertex.fromBufferAttribute(position, i);
    let y = (vertex.y + sizing.halfHeight);
    let skinIndex = Math.floor(y / sizing.segmentHeight);
    let skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight;
    skinIndices.push(skinIndex, skinIndex + 1, 0, 0);
    skinWeights.push(1 - skinWeight, skinWeight, 0, 0);
}

Thanks in advance.

Where does this code snippet come from?

https://threejs.org/docs/scenes/bones-browser.html
Line 113

Well, this code is very specific for this cylinder geometry. It does not work with arbitrary geometries.

The best solution is to author the skinning data in a DCC tool if possible. But since you want to add bones dynamically, you can indeed try to compute the distance between bones and vertices. Based on the distance, you can figure out the four most closest bones for each vertex. This should allow you to derive the mentioned skinning data. However, I’m not sure how “good” the final animation will look like. TBH, apart from the code in the bones browser, I’ve never seen this done elsewhere.

Some time ago I experimented with bones and skeleton. Perhaps there is a suggestion.
Some comments in German - can surely be translated easily.
A little lower on my side. https://hofk.de/main/threejs/

2020-01-24_16.59.46 2020-01-24_17.00.07

See also in the Collection of examples from discourse.threejs.org

2020-01-24_17.09.41
https://hofk.de/main/discourse.threejs/2018/Xindex2018.html
https://codepen.io/hofk/pen/eWdZMb

4 Likes