Is 3.7 messing with my models?

Today I installed JME 3.7 and tried to fire up UngaMunga. But it broke on loading the model I use for the globe complaining about not able to cast a child within to model to Geometry - in 3.6 that child was a Geometry.

It looks like the gltf/glb loader has changed the way it reads models.

Here is the model in the 3.6 scene-explorer:

And here it is in the 3.7 scene-explorer:

Why is it doing this? I must say it has always been a mystery to me how to predict the model structure turns out when exporting glb’s from Blender. I was blaming Blender, because I had the same problem with JS Three and other platforms.

1 Like

Yes. That’s pretty much always been the case. The trick is to use strategies that don’t require predicting it.

1 Like

There is a limit to what you can do without any knowledge of the model. With the Blender conversion it is even unsure what names will be given to children of the model. The null_0 is absolutely random to me.

What I could do is write a function that iterates a model just to find the geometry-child I need. But this would work for single geometry models. But for loading performance I work a lot with models that hold different sub models that I need to pick out. If I can not trust them to have the same names as I gave them in Blender, I am bound to mess up.

Yes, the latest version of the engine has changed the gltf/glb file loading parser. It now introduces two parent nodes for each geometry and changes their names by adding a numeric suffix preceded by an underscore (e.g., from Cube to Cube_0).

This change could potentially break several previous applications.

I wasn’t very pleased with this update and suggested highlighting this new behavior in the release notes, but unfortunately, that didn’t happen.

Before: 3.6.1-stable

After: 3.7.0-stable

3 Likes

It seems not to do this, the model node was called polymesh but the sub node has an empty name, and the Geometry node is called null_0.

Why does this happen with the geometries/nodes? Is it intentional or a bug? Seems completely pointless and as you said, may break applications. I’m still on 3.6 at the moment and now this makes me question whether I should update or not

The reason that you should not rely on the actual graph layout is that you are depending on 3 intermediate processes, 2 of them being 3rd party.

  • Blender (if you export your model with a different app, results might be different)
  • Blender Exporter (if the maintainer decides to change the exporting behavior)
  • Jme3 importer (As already happend)

At the point you want to store controls within your model you are going to use .j3o anyways, so might be good to make the swap as soon as possible. Write a robust importer that converts the model, makes the necessary changes, additions, tangents/binormals whatever, and save the model in jme’s format

Ah… I do use 3Jo in most cases. But only because people told me it is better. I would be very interested in learning more about the format and the conversion.

Where can I find this information?

Is it intentional or a bug?

Between 3.6.1 and 3.7, a couple dozen changes were made to JME’s glTF importer. Most of these were attempts to solve known issues. At least one bugfix affected the structure of imported models. (I know because it affected Minie’s “candy dish” model.) Fixing bugs takes priority over preserving the importer’s outputs.

I wonder if this could be mitigating by making it easier to get a (recursive) child by name? That might make people less likely to rely on the graph structure in the future

Why are we adding _0 though? That seems unhelpful (I assume it’s for deduping but we could supress the 0th suffix)

I believe Node.getChild(String name) searches all children and not just immediate descendants. Also, there is SceneGraphIterator, which just got added.

1 Like

What could’ve been the bug? This seems like a really strange solution (or workaround rather) to whatever it was

If it does create unnecessary double nodes it sounds indeed strange. @capdevon stated it does, while @Fedor_van_Eldijk stated it does not. It would be helpful to have a screenshot from blender and a dump or whatever from jme so that we all can see what we are actually talking about

In the case of my “candy dish” model, the structural change occurred at “master” commit a0b79a1, in other words PR 2103.

Here’s the YBot model (.gltf) imported into Blender

You can also download it from here

I agree the ‘_0’ suffix is unnecessary and it could be a major cause of backward compatibility problems.

Here is a possible solution for a frequent use case that I am sure many people will have used in their code:

replace this statement:

Node model = (Node) assetManager.loadModel("Models/YBot.gltf");
// v3.6.1-stable -> Alpha_Surface
Geometry body = (Geometry) model.getChild("Alpha_Surface");  

with this statement:


Spatial model = assetManager.loadModel("Models/YBot.gltf");
// v3.7.0-stable -> Alpha_Surface_0
Geometry body = findGeom(model, "Alpha_Surface");

/**
 * Recursively searches for a Geometry object within a Spatial hierarchy.
 *
 * @param spatial The root Spatial object to search.
 * @param name The name or partial name of the Geometry to find.
 * @return The found Geometry object, or null if not found.
 */
  private Geometry findGeom(Spatial spatial, String name) {
      if (spatial instanceof Node) {
          for (Spatial child : ((Node) spatial).getChildren()){
              Geometry result = findGeom(child, name);
              if (result != null) {
                  return result;
              }
          }
      } else if (spatial instanceof Geometry) {
          if (spatial.getName().startsWith(name)) {
              return (Geometry) spatial;
          }
      }
      return null;
  }