What is wrong with this model, why so slow?

New PG is below:

I already want to learn about web workers so I will deep dive. But someone experienced this before can get things faster :smiley:

Just le me know if you want me to cc some good people who will be able to give you proper advise on this…

That would be great actually

Sure will do. Meanwhile, just opened your PG (with a new object) and OUCH this one shows another issue. I have way too many drawcalls on this object. At some point, I am afraid some will require a rework using instances or thin instances. May be it would be better to start working with the original object from the first PG. And I actually, would like to be able to compare the results. If possible?

Edit: And question, what are all these transformNodes here for?

I changed the first object because merge meshes function works really smooth with that one. But here you can find the same PG with that object:

As you see there are many parts of this assembly like bolts, nuts, etc. They are all transformNodes and I am using them to attach gizmos to parts.

Stupid question. Why not attach the gizmo to the mesh?

Else, should I understand that in your project you can move (disassemble, reassemble) all parts down to each single bolt and screw? If so, we need to find a way to identify these common meshes (create a library) and work them as instances or thin instances because else, I am afraid this will never provide a good user XP

Exactly! Every part is moveable, rotatable. And parts come as transformNodes from GLB export so I can use them. The reason why I attach the gizmos to transformNodes was this ( since transformNode is parent of all part meshes)
But now since there is only one mesh for every part I can attach to mesh I guess.

Yes, this will already remove all these useless transform nodes (unless you need some to move groups of parts?) But this is only the ez part and will definetely not solve the main issue.
Now, before we move on with more design thinking: Can I somehow assume that the name of these transformNodes (the first part, not the number) would be a partID and would be the same in all objects using this part? Like we could identify a 6M bolt in any object by the name of the transformNode. Because this would be the first requirement we would need if we wanted to swap all duplicate parts (nodes/meshes) for instances.

Name of transformNodes changes according to part and they are important. I am also showing them to users. They could be detailed like: M5 Washer 5mm x 10mm x 1mm .(Not always like ‘NAU10’)
They can be same if there are more than one of that part but I will solve this by adding order number to name.

So, can I understand that each transform node of a same (root) name within the object is (currently) a copy of this mesh? In case, we can use the name of the transformNode to generate instances for all duplicates of this root name, position and angle them (zero them) at the transformNode and then get rid off the transformNode?

Yes it has to be copy. For instance there could be 100 same bolts.
As long as their positions and rotations are the same we could do anything since they are visually identical.

Providing you didn’t rescale/rotate/position the mesh within the transformNode? In case, this solution would be a bit tricky to work but would work I suppose.

I am not sure I got the question. But I am not changing any rotation, position or scale at first. But user can click on a part, than gizmo appears. And they can move or rotate the part.
So at initial, it has to be loaded as it was.

The question was: Is the mesh (currently meshes, called 'primitives) inside a transformNode always at zero (position, rotation, scaling) or in other words equivalent to the values of the transformNode?
I checked a few and it seems like it would be the case, but if a mesh has on import different values then the transformNode (in other words, if it’s transformed within the parent) then we would also need to account this.

Edit: or we might want to account it anyways to make sure.

Oh okay. No they are not transformed within the parent.

I mean let’s say meshes within a bolt are always same relative position.

Ok. I suppose it can still be improved/amended later on if it appears necessary.
Well, I guess with this we sort of have the base of a plan:
Aside from what we already have (or amended from what we already have).

  1. Get children of transformNode
  2. Unparent from transformNode
  3. Get the root name only (first node) for each part
  4. Create the Merge of the first mesh only [0]
  5. Create x instances of merged mesh for length of rootname (from 1 to x) with same name
  6. Position/scale/rotate (transform) each instance to use the values of their transformNode
  7. Dispose duplicate meshes
  8. Dispose parent (transformNode)

Do you feel comfortable trying this solution?
I would actually do it with a dummy/simple version of an object for a start.

Let me know if you are OK to try this or if you want me to callin people for help for this part.
I guess in the process, optimization will come only after (after same parts have been replaced with instances).

Yess! I will give it a try to create instances.

But I am still worried about merge mesh function blocking. Do you know anyone worked with web workers for BJS?

Yes, but I would advise to first work the method and present with a cleaner (and simpler) version.
I believe the base is really to be able to identify and replace all of these duplicate parts with instances for a start. Eventually, can next be improved using thininstances. And when the time will come, I shall make sure you get the help you need for optimizing, if that’s ok with you?

Edit: Again, make it just a dummy and a base. It will avoid doing additional work for nothing.

1 Like

@Evgeni_Popov @lucas-divinestar @Pryme8 I have started trying to help here with an issue regarding large and fully editable models from manufacturer, I suppose. Together, we have managed to investigate the first part and are about to solve a number of problems, by merging meshes and replacing duplicate meshes with instances. This part is underway.

However, due to the very large number of imported meshes and nodes, it will likely require another level of backend optimization.

QUESTION: Is it possible to use web workers to merge meshes or in the preparation phase?
Any other solution you can think of to improve performance and reliability on load and build?
Thanks a lot for your time and invaluable input. And, have a great WE :sunglasses:

@mawa
It is theoretically possible.
If you somehow have access to the raw data of the mesh (positions, uvs ,indices, normals, and so on) you could combine them together into one big array for each in the worker thread and send it over using the transferable API.
What you would probably want to do is insatiate an Uint32Array for positions, indices, and nomrals and a Float32Array for colors and uvs. This would just be the total length of each mesh attribute added together times 4 to get the correct byte size.
From there you can just loop through the data and add it to the new array.
The indices might be more tricky cause you will have to remap them (if the mesh is using them).
And if the all positions are in “Mesh Space” not “World Space” that might be tricky as well.

I believe if you can use the .babylon format you can get direct access to that data as it is all stored as JSON. You could request and parse all the data in the worker, combine it together, and then transfer it to the main thread.

They have a plugin in blender to export models as a .babylon file.

Another option would be to straight up import babylon.js into a web worker and use the merge meshes function. You may have to pass it an extra canvas though.

Off Screen Canvas - Babylon.JS Docs

2 Likes