重构成功
This commit is contained in:
107
lib/plugins/model/service.js
Normal file
107
lib/plugins/model/service.js
Normal 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 };
|
||||
};
|
||||
Reference in New Issue
Block a user