重构成功

This commit is contained in:
yinsx
2025-12-22 15:01:10 +08:00
parent 1df41ac4ab
commit 1de2ac8491
25 changed files with 349 additions and 377 deletions

View File

@ -0,0 +1,107 @@
import fs from "fs";
import path from "path";
import { NodeIO } from "@gltf-transform/core";
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
import { dedup, prune, resample, weld, quantize } from "@gltf-transform/functions";
import { BACKUP_SUFFIX, needsConversion } from "../../utils/gltf.js";
import { convert } from "../convert/service.js";
const io = new NodeIO().registerExtensions(ALL_EXTENSIONS);
const QUANTIZE_PRESETS = {
high: { position: 16, normal: 12, texcoord: 14, color: 10, generic: 12 },
balanced: { position: 14, normal: 10, texcoord: 12, color: 8, generic: 12 },
aggressive: { position: 12, normal: 8, texcoord: 10, color: 8, generic: 10 },
light: { position: 10, normal: 8, texcoord: 10, color: 8, generic: 10 }
};
export const buildTransforms = (config) => {
const transforms = [];
const selected = new Set(config.commands);
if (selected.has("dedup")) transforms.push(dedup());
if (selected.has("prune")) transforms.push(prune());
if (selected.has("resample")) transforms.push(resample());
if (selected.has("weld")) transforms.push(weld());
if (selected.has("quantize")) {
const preset = QUANTIZE_PRESETS[config.quantizePreset] || QUANTIZE_PRESETS.balanced;
transforms.push(quantize({
quantizePosition: preset.position,
quantizeNormal: preset.normal,
quantizeTexcoord: preset.texcoord,
quantizeColor: preset.color,
quantizeGeneric: preset.generic
}));
}
return transforms;
};
const resolveOutput = (file, config) => {
const cwd = process.cwd();
const originalExt = path.extname(file).toLowerCase() || ".gltf";
const baseName = originalExt ? file.slice(0, -originalExt.length) : file;
const isConvertible = needsConversion(file);
const targetExt = config.outputFormat === "gltf" ? ".gltf"
: (config.outputFormat === "glb" || isConvertible) ? ".glb"
: originalExt;
const wantsCopy = config.outputOptions.includes("copy");
const wantsOverwrite = config.outputOptions.includes("overwrite");
const mode = wantsCopy ? "copy" : (wantsOverwrite ? "overwrite" : "copy");
const backup = config.outputOptions.includes("backup") && mode === "overwrite";
const targetName = mode === "copy"
? `${baseName}_compressed${targetExt}`
: `${baseName}${targetExt}`;
return {
cwd,
mode,
backup,
sourcePath: path.join(cwd, file),
sourceExt: originalExt,
targetExt,
targetPath: path.join(cwd, targetName),
baseName,
needsConversion: isConvertible
};
};
export const processFile = async (file, config, transforms) => {
const output = resolveOutput(file, config);
if (!fs.existsSync(output.sourcePath)) {
return { ok: false, file, reason: "missing" };
}
if (!transforms.length) {
return { ok: false, file, reason: "no-transform" };
}
if (output.backup) {
const backupName = `${output.baseName}${BACKUP_SUFFIX}${output.sourceExt}`;
const backupPath = path.join(output.cwd, backupName);
fs.copyFileSync(output.sourcePath, backupPath);
}
let inputPath = output.sourcePath;
if (output.needsConversion) {
const tempPath = path.join(output.cwd, `${output.baseName}_temp.glb`);
await convert(output.sourcePath, tempPath, { binary: true });
inputPath = tempPath;
}
const document = io.read(inputPath);
await document.transform(...transforms);
io.write(output.targetPath, document);
if (output.needsConversion) {
fs.rmSync(inputPath, { force: true });
}
if (output.mode === "overwrite" && output.targetPath !== output.sourcePath) {
fs.rmSync(output.sourcePath, { force: true });
}
return { ok: true, file, output: output.targetPath };
};