Scene newMesh Observable and Mesh observables

I think this is a bug.

what i am attempting to do is use the scene.onNewMeshAddedObservable to track when new meshes are added.

I want to evaluate new meshes and set them up for some application wide animations.

what I found tho, is that there’s a timing issue.

when a mesh is created using MeshBuilder, it immediately triggers the scene.onNewMeshAddedObservable.

this means that setting properties after creating it, such as position or material, or what have you, is missed. This makes sense though, and I don’t consider this the issue. But I wanted to get the extra info for my analysis. My first attempt to fix this involved using a setTimeout with a 50 ms wait, and that works so far, but feels…like it could run into potential bugs.

1

so I thought maybe I could tie in to the Mesh.onReady function. that apparently never fires. bug?

2

then i thought I could use the Mesh.onBeforeRenderObservable with addOnce. my thinking is whatever settings you are doing, probably are done by the time Render is reached.

and this blows up with an exception. so it seems the scene newMeshAdded observable is firing while the object is still being fully created, and the observables are not available to be set. this seems like a bug to me.

demo pg. first load shows the onReady not firing, set showBreak to true to see the observable break

https://playground.babylonjs.com/#QQAGCS

I’m no specialist of Babylon (experts will correct if I’m wrong), but after looking at source code:

  • onNewMeshAddedObservable is called very early in the process of mesh creation: it is called right when you do new Mesh(...) (it is called by the constructor of AbstrachMesh which itself is called at the beginning of the mesh constructor). So, you should not rely on the mesh being constructed at this point, as it’s indeed not the case. It is not a bug, it is by design
  • .onReady function is rarely called by the engine. It is a method of Node, and as I can see it, it is called only by Helpers.photoDome, Helpers.videoDome, CreateGround and CreateGroundFromHeightMap from GroundBuilder and that’s it

If you want to make sure a mesh is ready to be rendered, check mesh.isReady(...) before doing something with it. It’s somewhat harder than having a notification for that (needs some form of polling), but I don’t think a notification exist for that event (the experts will tell).

Note: setTimeout(50ms) is a really bad idea if you assume the mesh is ready to be used! Depending on a countless of factors, it may or may not work. You should at least call mesh.isReady(...) on your callback to be on the safe side.

1 Like

I agree the settimeout of 50ms is bad, that’s why I am looking at the events / observables.

But I want to catch this in the scene. I have a dynamic system, and want to ensure new meshes added later get roped in nicely, and the scene newMeshAdded is a great hook for this.

But calling it so early does me no favors.

The other scene events fire very frequently. I could add the new mesh to a list, and check if it’s ready in scene ondraw or onafter render, and handle it there. But that would incur a lot of frequent if() checks every tick. Seems like a lot of work on the cpu.

I’m not sure what the usecase for addmeshobservable is, but it seems weird to use a non-finished object.

Either way, is there a way to bind to the ready value of a mesh within the scene addmeshobservable?

This is not a bug as explained correctly by @Evgeni_Popov :slight_smile:
Here is my recommendation: use Tools.SetImmediate to be called right after the mesh constructor

https://playground.babylonjs.com/#QQAGCS#1

Note that the mesh could still be not ready (meaning mesh.isReady(...) will return false in the callback) even in this case, as setImmediate is more or less a window.setTimeout(..., 0): textures or shaders could still be in the process of being loaded.

Or did I miss something?

What I did was in my onmeshadded, I basically recursively call settimeout for 50ms as long as isready() returns false. Probably need a counter to avoid endless recursion in a case where a mesh is never ready, but it works. Probably the same amount of cpu work as any observables method, and avoids adding needless checking to the scene render events

1 Like

That is true but the observables will be ready by then