How to attach mesh to the bone the most efficient way?

My goal is to have animated mesh - lets say human - and put somehing dynamically into its hand. I have tried different approaches but all of them seems to be unnecessarily slow.

My goal is to keep FPS > 100 with 100 animated meshes attached with wearable items

  • The scene has 100 moving animated humans (pretty simple models and skeletons), they are moving around and animating while FPS are in 115 - 120 range (my test phone has 120hz screen).
  1. Create 100 instances of sword (simple) and do nothing with them = FPS 115-120 (no noticeable drop)

  2. Create 100 instances of sword and parent them to the mesh itself = FPS 110 - 115 while swords moving around with meshes (small acceptable drop)

So far so good, but then I wanted to put the sword into model´s hand, I tried following

  1. Create 100 instances of sword and attach them to the hand bone of the mesh = FPS 70-75

  2. Create 100 instances of sword and parent them to the TransformNode that is attached to the hand bone of the mesh = FPS 70-75 (this one was expected)

  3. Create Solid Particle System, make the sword mesh as the particles, create TransformNode attached to the model´s hand and then on sps.setParticles function, I copied absolute position and rotation from the node to the particle. Works as expected but also FPS dropped to like 70 - 75.

In all my approaches that really follows hand (3 - 5), FPS dropped drastically - like 40 FPS drop only for copying position / rotation, it feels wrong considering we are talking about only 100 objects (not thousands or tens of thousands)

Considering that my test phone can render 100 moving animated objects at almost 120FPS, I did not expect any noticeable drop actually.

In attempt nr. 2 - the swords were moving around so position of the mesh is copied to the sword and it did not cause any FPS drop - what is the difference between following mesh and following its bone ? It is just copying one position / rotation data from one object to another, or not ?

Is there some different approach that I may try ? It seems weird that I can render 100 animated meshes and 100 swords perfectly at 110+ FPS (around 40.000 faces) and then only making the sword follow the bone (bone that is already being animated) make 40 FPS drop.

Any ideas ?

Note: In reality I would not need 100 equipped models in the scene at one time, the reason I am going this exagerated way is to idenfity FPS drains like this easily.

Thanx very much !

1 Like

I probably solved it - so when someone else run into the same situation, here is the solution, that works as wanted and has like zero impact on performance (which is what I expected from attachToBone in the first place).

    this.handBone.computeWorldMatrix(true);
    const boneMatrix = this.handBone.getWorldMatrix();
    const parentWorldMatrix = this.mesh.getWorldMatrix();

    const localPosition = new Vector3();
    const boneRotationQuaternion = new Quaternion();
    const localScale = new Vector3();
    boneMatrix.decompose(localScale, boneRotationQuaternion, localPosition);

    const parentPosition = new Vector3();
    const parentRotationQuaternion = new Quaternion();
    const parentScale = new Vector3();
    parentWorldMatrix.decompose(parentScale, parentRotationQuaternion, parentPosition);

    const combinedRotation = parentRotationQuaternion.multiply(boneRotationQuaternion);
    const worldPosition = Vector3.TransformCoordinates(localPosition, parentWorldMatrix);

    this.sword.position = worldPosition;
    this.sword.rotationQuaternion = combinedRotation;
1 Like

I’m attaching the diamond meshes to the bones in this demo:

Here is the rigging part:

Why this method does not work: Bones and Skeletons | Babylon.js Documentation

Do we need to fix it?

Hello, it DOES work properly as it was in my attemp number 3. The problem was that it caused huge FPS drop (from 115 to 70 in my case), when I do it manually as stated above, I experienced no FPS drop at all.

Hi Roland, I looked at your code and if I understood it correctly, you are parenting your meshes to the bone right ? I tried it as well but I got the same FPS drop as I had in attachToBone case.

How many objects are you attaching ? In my case I attached only 1 to every aniamted mesh, and there were 100 such meshes.

oh sorry I read quickly!

We can easily optimize the function as the most import problem is the call to prepare:

Isnt that prepare called only once ? At the moment when attachToBone is called ? In such case it wouldnt affect FPS permanently if I didnt miss anything here.

If it was the case you would not see any perf issue. I need a repro to investigate if you can

1 Like

1340 non-instanced boxes - I get 120 FPS on Macbook Pro M4 Max

6700 instanced boxes, doNotSyncBoundingInfo set to true - 120 FPS

@stealman Try to turn off bound info syncing of the attached meshes like I did in the second example

@stealman In this little game I used thin instances manually ‘attached’ to bones. 13.000 cubes at 300 FPS.

This is the piece of code you might be interested in:

@roland Thanx for this - I will try this doNotSyncBoundingInfo = true It might help actually ! In the meantime I came to conclusion, that “manually attached thin instances” as you named it, is the way to go. Tried it yesterday and it is blazing fast !

1 Like

Would you please mark my answer as the solution in this case? Thanks! :handshake: :wink:

1 Like

Done :wink:

That being said I would love to see a PG showing perf regression with the core attachToBone function

1 Like

As you can see it performs well.

Sorry for the offtop.
Do You know guys why in this example mesh selection is taking so much time?

1 Like
2 Likes

You can merge the meshes: