Using BABYLON.GLTF2Export.GLBAsync I am getting a warning:
Joint indices conversion needed: some joint indices are stored as floats in Babylon but GLTF requires UNSIGNED BYTES. We will perform the conversion but this might lead to unused data in the buffer.
I am guessing this refers to the bone matrices? I do not touch any of these. They come straight out of Blender (and there from the GLB exporter).
Can I fix the issue, well ideally, on Blender level?
Otherwise, I would prefer to fix it on loading (saving is taking already too long ). And then ideally as soon as possible in the GLTF loader - something like when it parses the string and decides which ArrayBuffer to use. Then use the Uint one instead of a Float. Can I intercept this somehow?
Best wishes
Joe
Just want to mention, I have no clue where to debug. I did a fulltext search (for different parts of the warning message) in the Babylon repo (including node_modules). No results
Yes, that warning pops up because the glTF format requires joint indices (MatricesIndices in Babylon) to be unsigned bytes or shorts, but yours are being stored as floats. So, on export, they are automatically converted to the right integer type. The “unused data” part of the warning means a new buffer was allocated for this converted data, leaving the original float data behind. It’s a safe heuristic to avoid messing with other mesh data.
What’s really curious is why you’re seeing this at all. You’re right that both the Blender exporter and the Babylon loader should handle these indices as integers automatically. The fact that they are floats by the time you re-export suggests something is awry during Blender export or after the loading process.
Could you share the glTF you’re loading? That would be the fastest way to see what’s going on and make sure we’re not missing a bug.
Regarding your other question about intercepting the loading process: while there isn’t a direct glTF loader extension hook for this specific scenario, you could manually convert the MatricesIndices vertex buffer to uint8 or uint16 after the model has loaded. But doing this without leaving unused data is a bit more involved. Because vertex attributes (like positions, normals, and joint indices) can exist in the same ArrayBuffer, you would need to reallocate and rebuild this buffer, then reassign vertex attributes appropriately.
The model comes straight out of Blender (no automation involved; lastest Blender download). It is already a Float32Array. Not sure how to read the raw gltf data (re float vs int indices).
Judging from the raw file, Blender is using the correct data type, so we can rule that out. The issue in that playground isn’t that Babylon is storing the wrong buffer type, though-- it’s that getVerticesData returns the data as a FloatArray, which causes the test to fail.
Here’s an updated playground that uses the same check as the exporter:
Why do you need clone and makeUnique? Mesh.makeGeometryUnique takes different branches depending on whether I call it on the source or on the clone. I am guessing the branch in question is a reference counter.
Why is the buffer floatified? Tracing it back to Geometry.copy, it makes a call to Geometry.getVerticesData (the one, Alex pointed out earlier, always floatifies the buffer)! Replacing it with Geometry.getVertexBuffer makes the playground pass: https://playground.babylonjs.com/#88CB6A#186
But now, if you console log the clone’s geometry, all vertex buffers are ints (even the UVs)? How can this even render?
It gets worse though: while the playground passes, the change crashes my local project:
First crash was when calling mesh.getVerticesData(VertexBuffer.ColorKind) with “RangeError: Offset is outside the bounds of the DataView”.
Next crash with same error, when calling Mesh.MergeMeshes (cannot hotfix this, so full stop here ).
You’re spot on about geometry.copy float-ifying the data via getVerticesData!
Regarding getData(), it returns the full underlying buffer, which can be shared across vertex buffers. This isn’t immediately obvious from the code doc (I’ll make sure to clarify that). A good example of when this would cause problems can be seen in this glTF with interleaved vertex data: https://playground.babylonjs.com/#88CB6A#188