Add GLB optimizer script

pull/1745/head
Piero Toffanin 2025-09-16 15:27:25 -04:00
rodzic 75179368c1
commit a3852fb4a1
2 zmienionych plików z 112 dodań i 4 usunięć

Wyświetl plik

@ -0,0 +1,104 @@
const { NodeIO, Extension } = require('@gltf-transform/core');
const { KHRONOS_EXTENSIONS } = require('@gltf-transform/extensions');
const { textureCompress, simplify, weld, draco } = require('@gltf-transform/functions');
const { MeshoptSimplifier } = require('meshoptimizer');
const draco3d = require('draco3dgltf');
class CesiumRTC extends Extension {
extensionName = 'CESIUM_RTC';
static EXTENSION_NAME = 'CESIUM_RTC';
read(context) {
const rtc = context.jsonDoc.json.extensions?.CESIUM_RTC;
if (rtc) {
this.rtc = rtc;
}
}
write(context) {
if (this.rtc){
context.jsonDoc.json.extensions = context.jsonDoc.json.extensions || {};
context.jsonDoc.json.extensions.CESIUM_RTC = this.rtc;
}
}
}
async function main() {
const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS)
.registerExtensions([CesiumRTC])
.registerDependencies({
'draco3d.decoder': await draco3d.createDecoderModule(),
'draco3d.encoder': await draco3d.createEncoderModule(),
});
const args = process.argv.slice(2);
let inputFile = '';
let outputFile = '';
let textureSize = 512;
let simplifyRatio = 1;
for (let i = 0; i < args.length; i++) {
if (args[i] === '--input' && i + 1 < args.length) {
inputFile = args[i + 1];
i++;
} else if (args[i] === '--output' && i + 1 < args.length) {
outputFile = args[i + 1];
i++;
} else if (args[i] === '--texture-size' && i + 1 < args.length) {
textureSize = parseInt(args[i + 1]);
if (isNaN(textureSize) || textureSize < 1){
console.log(`Invalid texture size: ${args[i + 1]}`);
process.exit(1);
}
i++;
} else if (args[i] === '--simplify-ratio' && i + 1 < args.length) {
simplifyRatio = parseFloat(args[i + 1]);
if (isNaN(simplifyRatio) || simplifyRatio < 0 || simplifyRatio > 1){
console.log(`Invalid simplify ratio: ${args[i + 1]}`);
process.exit(1);
}
i++;
}
}
if (!inputFile || !outputFile){
console.log('Usage: node glb_optimize.js --input <input.glb> --output <output.glb> [--texture-size <size>]');
process.exit(1);
}
const encoder = require('sharp');
let transforms = [
textureCompress({
encoder,
resize: [textureSize, textureSize],
targetFormat: undefined,
limitInputPixels: true,
}),
draco({
quantizationVolume: "scene"
})
]
if (simplifyRatio < 1){
transforms.unshift(
simplify({
simplifier: MeshoptSimplifier,
error: 0.0001,
ratio: simplifyRatio,
lockBorder: false,
}),
);
transforms.unshift(weld());
}
const document = await io.read(inputFile);
await document.transform(...transforms);
await io.write(outputFile, document);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});

Wyświetl plik

@ -27,15 +27,19 @@
"@babel/preset-env": "^7.0.0-beta.54",
"@babel/preset-react": "^7.0.0-beta.54",
"@babel/runtime": "^7.4.5",
"@gltf-transform/extensions": "^4.2.1",
"@gltf-transform/functions": "^4.2.1",
"async": "^2.1.2",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.4.0",
"babel-loader": "^8.0.0-beta.4",
"buffer": "^6.0.3",
"cheerio": "1.0.0-rc.6",
"clipboard": "^1.7.1",
"css-loader": "^0.25.0",
"d3": "^3.5.5",
"draco3dgltf": "^1.5.7",
"enzyme": "^3.3.0",
"cheerio": "1.0.0-rc.6",
"enzyme-adapter-react-16": "^1.15.1",
"exifr": "^6.0.0",
"fbemitter": "^2.1.1",
@ -48,6 +52,8 @@
"json-loader": "^0.5.4",
"leaflet": "1.3.1",
"leaflet-fullscreen": "^1.0.2",
"meshoptimizer": "^0.25.0",
"mini-css-extract-plugin": "1.6.2",
"object.values": "^1.0.3",
"proj4": "^2.4.3",
"qrcode.react": "^0.7.2",
@ -69,8 +75,6 @@
"url-loader": "^0.5.7",
"webpack": "5.89.0",
"webpack-bundle-tracker": "0.4.3",
"webpack-livereload-plugin": "3.0.2",
"mini-css-extract-plugin": "1.6.2",
"buffer": "^6.0.3"
"webpack-livereload-plugin": "3.0.2"
}
}