gltf-pipeline
gltf-pipeline copied to clipboard
Special characters in filenames cause incorrect operation
Version: 4.1.0
Issue Description:
I have a GLB file that, when uploaded and viewed for textures on the [BabylonJS Sandbox](https://sandbox.babylonjs.com/) and subsequently exported (as GLB), results in the internal texture names being renamed to the format blob:https:__sandbox image.png
. This poses a problem when I use the command gltf-pipeline -i xxx.glb -t -o xx.gltf
.
On macOS, filenames containing the :
character get replaced with /
, which leads to an error when running gltf-pipeline -i output.gltf -o output.glb
, as the actual filename doesn't match the one inside the .gltf file. However, this can be manually fixed by adjusting the .gltf file itself.
On Windows, executing gltf-pipeline -i xxx.glb -t -o xx.gltf
results in an error: (node:2128) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'C:\Users\test\Desktop\glb\blob:https:__sandbox image_3.png’
.
The probable cause seems to be the incompatibility of the :
character with the Windows file system.
Expected Result:
I'd like the process to handle glb file unpacking and packing smoothly, even when filenames contain special characters.
Possible Solution:
I attempted to access the source code:
In bin/gltf-pipeline.js
, I adjusted the saveSeparateResources
method:
tsxCopy code
if (Object.prototype.hasOwnProperty.call(separateResources, relativePath)) {
const resource = separateResources[relativePath];
// Replace special characters
const dirname = path.dirname(relativePath);
const basename = path.basename(relativePath).replace(/[<>:"/\\|?*#]/g, '_');
const sanitizedPath = path.join(dirname, basename);
const resourcePath = path.join(outputDirectory, sanitizedPath);
resourcePromises.push(fsExtra.outputFile(resourcePath, resource));
}
I also made changes in lib/addPipelineExtras.js
:
tsxCopy code
//before
function addPipelineExtras(gltf) {
ForEach.shader(gltf, function (shader) {
addExtras(shader);
});
ForEach.buffer(gltf, function (buffer) {
addExtras(buffer);
});
ForEach.image(gltf, function (image) {
addExtras(image);
});
addExtras(gltf);
return gltf;
}
// after
function addPipelineExtras(gltf) {
ForEach.shader(gltf, function (shader) {
addExtras(shader);
});
ForEach.buffer(gltf, function (buffer) {
addExtras(buffer);
});
ForEach.image(gltf, function (image) {
if (image.name) {
image.name = image.name.replace(/[<>:"/\\|?*#]/g, '_');
}
addExtras(image);
});
addExtras(gltf);
return gltf;
}
This approach provisionally addressed the issues I encountered. Perhaps another potential solution could be to use the encodeURIComponent(fileName) and decode method? But who's to say?