Skip to content

Ignore file extension of external glTF buffers#2615

Open
javagl wants to merge 1 commit intojMonkeyEngine:masterfrom
javagl:fix-gltf-bin-file-loading
Open

Ignore file extension of external glTF buffers#2615
javagl wants to merge 1 commit intojMonkeyEngine:masterfrom
javagl:fix-gltf-bin-file-loading

Conversation

@javagl
Copy link
Contributor

@javagl javagl commented Feb 15, 2026

Already mentioned in #2118 (comment) :

A .gltf file may refer to arbitrary external (binary) data, using a URI. The specification recommends to give these files a .bin or .glbin extension, but this is not required.

Right now, trying to load a file where such an external buffer does not have a .bin file extension will cause a crash.

This PR changes the behavior: It causes the actual file extension to be ignored.

I'm not entirely sure whether the approach here is the "right" one (or what the "best" approach is). What I gathered so far:

  • The actual data resolution happens based on an AssetKey
  • By default, this extracts the extension of a given file name, and stores it as its extension
  • Based on that AssetKey, there is a lookup mechanism for loaders, based on the file extension
  • The General.cfg establishes the mapping of
    LOADER com.jme3.scene.plugins.gltf.BinLoader : bin
    to use that BinLoader for assets with the bin extension

The main change here now is that the existing BinDataKey that was used for external glTF buffer references sets its extension to bin, regardless of the actual extension.

I've tested it with these files:

TriangleWithDifferentExternalExtensions-2026-02-15.zip

They can be loaded from the TestGltfLoading class, by putting them into the example data, and loading them with either of

loadModelFromPath("Models/gltf/TriangleWithBin/TriangleWithBin.gltf");
loadModelFromPath("Models/gltf/TriangleWithGlbin/TriangleWithGlbin.gltf");
loadModelFromPath("Models/gltf/TriangleWithNoExtension/TriangleWithNoExtension.gltf");

More generally: Trying to determine a file type based on a file extension is usually brittle and not sufficient in many cases. But... I know that everything that is going beyond that can be tricky. Many files have "magic bytes" that can be used for identifying the file type. But eventually, loaders may have to differentiate between different JSON files, and at this point, there is no way around parsing the whole thing and making guesses (!) based on the presence of absence of certain properties. I think that for the case of the glTF .bin files, the current approach should be OK. One could consider changing the registration and extension to
LOADER com.jme3.scene.plugins.gltf.BinLoader : glbin,
because glbin is ait more specific than bin, but that can be done at any point in time now.

@riccardobl
Copy link
Member

Conceptually it's ok, but i wonder if this could cause unexpected issues since it is faking the file extension.
What if we add the common gltf bin extensions to General.cfg instead?

@javagl
Copy link
Contributor Author

javagl commented Feb 15, 2026

Conceptually it's ok, but i wonder if this could cause unexpected issues since it is faking the file extension.

That's what I've been wondering about, but it's hard (for me) to find a definite answer to that - I'm not familar with the asset manager and loader code, and from a quick dive and a short debuggstepping, it seemed to be a reasonable solution. To my understanding, the extension is only used for the "lookup" of the loader, based on what is defined in the CFG file. (There are some implementations of ~"loaders" that seem to use the extension for other purposes, but the glTF BinLoader just does some instanceof check).

What if we add the common gltf bin extensions to General.cfg instead?

I considered to add bin and glbin there, and I've never seen an example where the binary buffer did not have a .bin file extension. But it is not required to have one. It should (preferably) be possible to load the TriangleWithNoExtension example, which does not use an extension for the binary file.

If the current change is considered to be "too dangerous" (in terms of side-effects), then this could be an option.

@riccardobl
Copy link
Member

riccardobl commented Feb 15, 2026

I'd like to hear others' opinion on this @jMonkeyEngine/contributors .
But the BinLoader and BinDataKey combo is pretty weird here, because they bypass 99% of the asset manager features. I think one option here would be to remove the BinLoader and BinDataKey entirely and replace the call to loadAsset with locateAsset that lets you open an inputstream to the asset without passing through the loaders and caching system.

@javagl
Copy link
Contributor Author

javagl commented Feb 16, 2026

I don't have strong opinions here (due to my lack of background knowledge). But regarding this:

that lets you open an inputstream to the asset without passing through the loaders and caching system.

One reason for using a .gltf with external binary files could exactly be to share these external binary files across multiple .gltf files (which means that some for of caching could make sense)

However, it's certainly not the most important fix, because .gltf files with external buffers are relatively rare (compared to .glb), and in doubt, people can easily change the glTF to use a .bin file extension.

I'll have another look at other glTF-related issues (e.g. models failing to load), maybe there are a few "simple" ones to tackle first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments