.babylon seralization doesn't included meshes generated with methods from external node projects/dependencies

Hello,

I have been working on a library to make dynamically manipulating the Babylon scene graph easier, and I have run into an issue when it comes to serializing the generated scenes into .babylon files.

It seems that meshes generated with methods from external libraries are not being serialized.

For example, if I have a function I import from another node package such as create(“box”) that wraps meshBuilder.createBox() and generates a box, even though the mesh is rendered in the scene graph, it will not be included in the serialized Babylon file generated from the scene.

Is this an expected behavior? Are there any workarounds?

Thank you

Welcome aboard!

Are you sure the meshes appear in scene.meshes? Only the meshes in this array will be serialized. In addition, the following conditions must be met:

  • mesh.doNotSerialize == false
  • mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADED || mesh.delayLoadState === Constants.DELAYLOADSTATE_NONE

Otherwise, I don’t see why they wouldn’t be serialized. If you have a reproduction somewhere, we could take a look at it.

1 Like

Thank you! Here is what I got,

  let box = myLib.create('box', 'myBox', scene)
  console.log(scene.meshes) //returns [U]
  console.log(box.doNotSerialize) //returns false 
  console.log(box.delayLoadState === Constants.DELAYLOADSTATE_LOADED) //returns false
  console.log(box.delayLoadState === Constants.DELAYLOADSTATE_NONE) //returns true
  console.log(BABYLON.SceneSerializer.SerializeMesh(box).meshes) //returns [{..}] (array length one) 
  console.log(BABYLON.SceneSerializer.Serialize(scene).meshes) //returns [] (empty array)

using mesh builder

  let box = BABYLON.MeshBuilder.CreateBox('babyBox')
  console.log(scene.meshes) //returns [t2]
  console.log(box.doNotSerialize) //returns false 
  console.log(box.delayLoadState === Constants.DELAYLOADSTATE_LOADED) //returns false
  console.log(box.delayLoadState === Constants.DELAYLOADSTATE_NONE) //returns true
  console.log(BABYLON.SceneSerializer.SerializeMesh(box).meshes) //returns [{..}] (array length one) 
  console.log(BABYLON.SceneSerializer.Serialize(scene).meshes) //returns [{..}] (array length one)

I can’t publish the code for now, making reproducing this more difficult. Still, I have isolated the relevant code on the sandbox directly, which does not have this problem, and both meshes are serialized, interestingly enough. Babylon.js Playground

The problem might be indicated by the json object symbols [U] vs [t2]. I am not familiar with what these mean.

@dsaffo
Tough to help without a repro :smiley:
Can you copy & paste the console.log results of each BABYLON.SceneSerializer.SerializeMesh(box)?
Also check & compare the actual contents of scene.meshes[0]

1 Like

Apologies for the constraints :sweat_smile: I understand if this has to wait until I can get things up on a repo.

As for the logs. I made a gist for the serialized meshes: https://gist.github.com/dsaffo/9066c420ac08eb02e2322fe5c5af4a4c

Visually comparing the two mesh objects there doesn’t seem to be any significant differences other than the object symbols U vs t2. The objects seem too big to be pasting around, but I can compare some specific properties if you have any ideas.

Actually, there’s another condition the mesh has to fulfill to be serialized by SceneSerialized.Serialize (and not enforced by SceneSerialized.SerializeMesh), which is that the mesh should be an instance of Mesh:

serializationObject.meshes = [];
for (index = 0; index < scene.meshes.length; index++) {
    const abstractMesh = scene.meshes[index];

    if (abstractMesh instanceof Mesh) {
        const mesh = abstractMesh;
        if (!mesh.doNotSerialize) {
            if (mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADED || mesh.delayLoadState === Constants.DELAYLOADSTATE_NONE) {
                serializationObject.meshes.push(SerializeMesh(mesh, serializationObject));
            }
        }
    }
}

Can you verify what scene.meshes[0].getClassName() and scene.meshes[0] instanceof BABYLON.Mesh return?

I think we are getting warmer!

  console.log(scene.meshes[0].getClassName()) //Mesh
  console.log(scene.meshes[0] instanceof Mesh) //false

instance of Mesh is true when making the mesh directly with MeshBuilder.

The question is, why is the mesh I am returning no longer an instance of BABYLON.Mesh. You can see the sample code of my create function in the playground above. I don’t think I am doing anything explicit to change its class type.

It seems myLib does not create a true Babylon mesh (or an object derived from Mesh). Do you have the source code of it? Can you console.log(myLib.create('box', 'myBox', scene))?

One thing that may explain why it does not work is that myLib is using another set of Babylon packages than your test script? I think (but I’m no expert) that instanceof Mesh will return false if myLib has created a mesh by using another set of Babylon files than the set you use in your test script.

myLib is using the ES6 version, and the test script uses the UMD version of Babylon…Is that what you mean by different packages?

Yes, I think that explains why it doesn’t work. For me, you have to use the same set of files in both cases (whether it’s ES6 or UMD).

Let’s ask @RaananW who should confirm it (or not!).

Both scripts now use the same version of Babylon, but unfortunately, the problem persists.

What is interesting is when I check the mesh in myLib.create() before returning, it is an instance of BABYLON.Mesh, but not after returning the mesh.

Are they also using the same set of files? What I mean is that BABYLON.Mesh in myLib must return the same object as BABYLON.Mesh in the test script, so that BABYLON.Mesh.prototype is the same. At least, I think this is what needs to be done for instanceof Mesh to work in the test script for a mesh created in myLib.

1 Like

Yep. this has to match.
I read the entire thread, but I’ll be honest and say I’m not sure why the architecture is set this way. Why are both umd and es6 used?
Anyhow,

They are both importing Mesh and Meshbuilder from @babylonjs/core if that is what you mean?

@RaananW using both versions wasn’t intentional I updated the library dependencies and test scripts separately but they match now.

Want to share the project architecture? It would be simpler to help if you can

@RaananW I will circle back to this thread once I get things up on a public GitHub.

2 Likes