feat: integrate Draco compression for 3D models in backoffice
- Added support for uploading and compressing GLB models using Draco in the backoffice. - Implemented commands for importing and re-compressing 3D models. - Updated model resource to handle 3D model uploads and validations. - Introduced a new script for compressing GLB files with Draco. - Modified Vite configuration to remove GLB files from the build output. - Updated package dependencies to include GLTF-transform libraries for handling 3D models. - Added tests to ensure proper functionality of 3D model handling and compression.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env node
|
||||
// Comprime con Draco un modello GLB: node scripts/comprimi-glb.mjs <sorgente.glb> <destinazione.glb>
|
||||
//
|
||||
// Usato dal backoffice al caricamento di un modello 3D (App\Support\Configuratore\CompressoreGlb):
|
||||
// l'originale resta salvato non compresso, nel configuratore va solo questa copia. Nel browser la
|
||||
// decomprime il DRACOLoader di three.js (vedi src/js/starter.js).
|
||||
//
|
||||
// In caso di successo stampa su stdout una riga JSON con le dimensioni prima/dopo.
|
||||
import fs from 'node:fs/promises';
|
||||
import { NodeIO } from '@gltf-transform/core';
|
||||
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
|
||||
import { draco, weld } from '@gltf-transform/functions';
|
||||
import draco3d from 'draco3dgltf';
|
||||
|
||||
// Bit di quantizzazione: valori più alti = più fedeltà e file più grandi.
|
||||
// Le posizioni a 14 bit sono sotto il decimo di millimetro sulle dimensioni di un infisso.
|
||||
export const DRACO_OPTIONS = {
|
||||
method: 'edgebreaker',
|
||||
encodeSpeed: 5,
|
||||
decodeSpeed: 5,
|
||||
quantizePosition: 14,
|
||||
quantizeNormal: 10,
|
||||
quantizeTexcoord: 12,
|
||||
quantizeColor: 8,
|
||||
quantizeGeneric: 12,
|
||||
};
|
||||
|
||||
const [src, dest] = process.argv.slice(2);
|
||||
if (!src || !dest) {
|
||||
console.error('Uso: comprimi-glb.mjs <sorgente.glb> <destinazione.glb>');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
try {
|
||||
const io = new NodeIO().registerExtensions(ALL_EXTENSIONS).registerDependencies({
|
||||
'draco3d.encoder': await draco3d.createEncoderModule(),
|
||||
'draco3d.decoder': await draco3d.createDecoderModule(),
|
||||
});
|
||||
|
||||
const input = await fs.readFile(src);
|
||||
const doc = await io.readBinary(new Uint8Array(input));
|
||||
if (!doc.getRoot().listMeshes().length) throw new Error('Il file non contiene geometrie.');
|
||||
|
||||
// Draco lavora su primitive indicizzate: weld unisce solo i vertici identici in tutti gli
|
||||
// attributi (posizione, normale, uv...), quindi non cambia l'aspetto del modello.
|
||||
await doc.transform(weld(), draco(DRACO_OPTIONS));
|
||||
const output = await io.writeBinary(doc);
|
||||
await fs.writeFile(dest, output);
|
||||
|
||||
console.log(JSON.stringify({ originale: input.length, compresso: output.length }));
|
||||
} catch (err) {
|
||||
console.error(err?.message ?? String(err));
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user