So I noticed then when I use assetManager.loadModel() on my scene exported from blender that the object names are not kept. Seems that only the names of the meshes is remembered. i.e. if I import this gltf (extract): Gltf Extract the children of the scene is called ‘link_MetalDoor’ and not ‘MainDoorR’. However, I need the name of the object in my game so that I can use it for logic and other purposes. Is there a way to get that information? Can I register some kind of extension or whatever for the gltf loader?
I remember there are some limitations on what blender exports. I just had an issue where I wanted the mesh names to persist from blender in my character model, but I could not get blender to export the names to the actual gltf file, it was creating names such as modelname.###. But I believe that mesh names have been fixed in the gltf plugin.
Is your issue that blender will not put the node names in the gltf file, or that jme is not using them?
The names are fine in the gltf file. It’s just that they are not stored in the imported scene. Every object in the scene gets the name of the mesh and not the object
Yes, there were several changes to gltf in 3.4.0, as @pspeed said, check using it. Also, what version of blender are you using, as different versions have different gltf plugins and store the data differently.
The last time I tried with JME 3.4 I think it was using mesh names not the object names for Geometries, not sure why. Howeever node names seems to work fine.
The reason I asked about 3.4 is because I partially remember exactly this bug being fixed but I can’t be sure and don’t have time to trawl through git commits to see. And anyway, upgrading to 3.4 is at least a good thing to try anyway.
Just tried 3.4 and it’s the same thing. After loadModel() objects are named after the mesh in blender and not the object. i.e. my Door1, Door2, MainDoorR are all called ‘link_MetalDoor’. So nothing changed here.
BTW to illustrate this. This is how it looks in Blender:
Note that at this moment I’m using the “extras” and “logic” to fix this problem. So the problem is actually ‘solved’ in a way. Just curious why the gltf loader seems to behave differently for me as people here say that for them the objects are named like the objects in the gltf
Probably. Note though that’s a behaviour change and it would also mean that the name of the mesh is then no longer available (I don’t think the JME mesh can have a name?)
OK, I think I have identified the source of the confusion. If you look in your gltf file, you will find the primitives section. Each mesh will get a primitives section, and it appears to be named that of the mesh (which makes sense since it is defining the sub meshes which jme will turn into individual meshes.)
The importer uses the names of the mesh when creating the geometries for it:jmonkeyengine/GltfLoader.java at d5f74b99fb00f3967559e31eb8bb8994c1aeb6fe · jMonkeyEngine/jmonkeyengine · GitHub
I will test tomorrow and look at making a pull request.
EDIT: The tricky part is when there is only one mesh. The importer will not create the node and instead attach a geometry to the scene instead (with the name of the mesh of course). The proper behavior is probably to create a node with the name of an object, then create the geometry in it, since that is what the gltf file is describing.
Perhaps this would be a better version of it:
Spatial spatial;
JsonObject nodeData = nodes.get(nodeIndex).getAsJsonObject();
JsonArray children = nodeData.getAsJsonArray("children");
Integer meshIndex = getAsInteger(nodeData, "mesh");
String nodeName = getAsString(nodeData, "name");
if (meshIndex != null) {
assertNotNull(meshes, "Can't find any mesh data, yet a node references a mesh");
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
Geometry[] primitives = readMeshPrimitives(meshIndex);
//Let's make the parent Node and attach the geometries to it
Node node = new Node();
for (Geometry primitive : primitives) {
node.attachChild(primitive);
}
spatial = node;
if (nodeName == null) {
spatial.setName(readMeshName(meshIndex));
} else {
spatial.setName(nodeName);
}
}
EDIT 2: I see as I was writing this post @Ali_RS also pulled up the source code