优化代码

This commit is contained in:
yinsx
2025-12-20 13:02:42 +08:00
parent d9abc57b0b
commit 16ae511f21
8 changed files with 30 additions and 482 deletions

BIN
cuba.glb

Binary file not shown.

296
cuba.stp
View File

@ -1,296 +0,0 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('STEP AP214'),'1');
FILE_NAME('cuba.stp','2025-12-20T11:13:44',(' '),(' '),'Spatial InterOp 3D',' ',' ');
FILE_SCHEMA(('automotive_design'));
ENDSEC;
DATA;
#1=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION(' ',(#148,#183,#218,#253,#288,#323),#6);
#2=PRODUCT_DEFINITION_CONTEXT('',#7,'design');
#3=APPLICATION_PROTOCOL_DEFINITION('INTERNATIONAL STANDARD','automotive_design',1994,#7);
#4=PRODUCT_CATEGORY_RELATIONSHIP('NONE','NONE',#8,#9);
#5=SHAPE_DEFINITION_REPRESENTATION(#10,#11);
#6= (GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#12))GLOBAL_UNIT_ASSIGNED_CONTEXT((#13,#14,#15))REPRESENTATION_CONTEXT('NONE','WORKSPACE'));
#7=APPLICATION_CONTEXT(' ');
#8=PRODUCT_CATEGORY('part','NONE');
#9=PRODUCT_RELATED_PRODUCT_CATEGORY('detail',' ',(#17));
#10=PRODUCT_DEFINITION_SHAPE('NONE','NONE',#18);
#11=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('Root',(#16,#19),#6);
#12=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0E-006),#13,'','');
#13=(CONVERSION_BASED_UNIT('METRE',#20)LENGTH_UNIT()NAMED_UNIT(#21));
#14=(NAMED_UNIT(#22)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.));
#15=(NAMED_UNIT(#22)SOLID_ANGLE_UNIT()SI_UNIT($,.STERADIAN.));
#16=SHELL_BASED_SURFACE_MODEL('Root',(#29));
#17=PRODUCT('Root','Root','Root',(#23));
#18=PRODUCT_DEFINITION('NONE','NONE',#24,#2);
#19=AXIS2_PLACEMENT_3D('',#25,#26,#27);
#20=LENGTH_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0),#28);
#21=DIMENSIONAL_EXPONENTS(1.0,0.0,0.0,0.0,0.0,0.0,0.0);
#22=DIMENSIONAL_EXPONENTS(0.0,0.0,0.0,0.0,0.0,0.0,0.0);
#23=PRODUCT_CONTEXT('',#7,'mechanical');
#24=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE(' ','NONE',#17,.NOT_KNOWN.);
#25=CARTESIAN_POINT('',(0.0,0.0,0.0));
#26=DIRECTION('',(0.0,0.0,1.0));
#27=DIRECTION('',(1.0,0.0,0.0));
#28= (NAMED_UNIT(#21)LENGTH_UNIT()SI_UNIT(.MILLI.,.METRE.));
#29=CLOSED_SHELL('',(#156,#191,#226,#261,#296,#331));
#100=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259));
#101=VERTEX_POINT('',#100);
#102=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741));
#103=VERTEX_POINT('',#102);
#104=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259));
#105=VERTEX_POINT('',#104);
#106=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741));
#107=VERTEX_POINT('',#106);
#108=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741));
#109=VERTEX_POINT('',#108);
#110=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259));
#111=VERTEX_POINT('',#110);
#112=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259));
#113=VERTEX_POINT('',#112);
#114=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741));
#115=VERTEX_POINT('',#114);
#116=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741));
#117=VERTEX_POINT('',#116);
#118=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259));
#119=VERTEX_POINT('',#118);
#120=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741));
#121=VERTEX_POINT('',#120);
#122=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259));
#123=VERTEX_POINT('',#122);
#124=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259));
#125=VERTEX_POINT('',#124);
#126=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741));
#127=VERTEX_POINT('',#126);
#128=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741));
#129=VERTEX_POINT('',#128);
#130=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259));
#131=VERTEX_POINT('',#130);
#132=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741));
#133=VERTEX_POINT('',#132);
#134=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741));
#135=VERTEX_POINT('',#134);
#136=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259));
#137=VERTEX_POINT('',#136);
#138=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259));
#139=VERTEX_POINT('',#138);
#140=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259));
#141=VERTEX_POINT('',#140);
#142=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259));
#143=VERTEX_POINT('',#142);
#144=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741));
#145=VERTEX_POINT('',#144);
#146=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741));
#147=VERTEX_POINT('',#146);
#148=STYLED_ITEM('',(#149),#156);
#149=PRESENTATION_STYLE_ASSIGNMENT((#150));
#150=SURFACE_STYLE_USAGE(.BOTH.,#151);
#151=SURFACE_SIDE_STYLE('',(#152));
#152=SURFACE_STYLE_FILL_AREA(#153);
#153=FILL_AREA_STYLE('',(#154));
#154=FILL_AREA_STYLE_COLOUR('',#155);
#155=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#156=FACE_SURFACE('',(#161),#157,.T.);
#157=PLANE('',#158);
#158=AXIS2_PLACEMENT_3D('',#100,#159,#160);
#159=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#160=DIRECTION('',(0.000000000,1.000000000,0.000000000));
#161=FACE_BOUND('',#162,.T.);
#162=EDGE_LOOP('',(#163,#164,#165,#166));
#163=ORIENTED_EDGE('',*,*,#167,.T.);
#164=ORIENTED_EDGE('',*,*,#168,.T.);
#165=ORIENTED_EDGE('',*,*,#169,.T.);
#166=ORIENTED_EDGE('',*,*,#170,.T.);
#167=EDGE_CURVE('',#101,#103,#171,.F.);
#168=EDGE_CURVE('',#103,#105,#172,.T.);
#169=EDGE_CURVE('',#105,#107,#173,.T.);
#170=EDGE_CURVE('',#107,#101,#174,.T.);
#171=LINE('',#100,#175);
#172=LINE('',#102,#176);
#173=LINE('',#104,#177);
#174=LINE('',#106,#178);
#175=VECTOR('',#179,1.0);
#176=VECTOR('',#180,1.0);
#177=VECTOR('',#181,1.0);
#178=VECTOR('',#182,1.0);
#179=DIRECTION('',(0.000000000,0.000000000,1.000000000));
#180=DIRECTION('',(0.000000000,1.000000000,0.000000000));
#181=DIRECTION('',(0.000000000,0.000000000,-1.000000000));
#182=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#183=STYLED_ITEM('',(#184),#191);
#184=PRESENTATION_STYLE_ASSIGNMENT((#185));
#185=SURFACE_STYLE_USAGE(.BOTH.,#186);
#186=SURFACE_SIDE_STYLE('',(#187));
#187=SURFACE_STYLE_FILL_AREA(#188);
#188=FILL_AREA_STYLE('',(#189));
#189=FILL_AREA_STYLE_COLOUR('',#190);
#190=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#191=FACE_SURFACE('',(#196),#192,.T.);
#192=PLANE('',#193);
#193=AXIS2_PLACEMENT_3D('',#108,#194,#195);
#194=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#195=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#196=FACE_BOUND('',#197,.T.);
#197=EDGE_LOOP('',(#198,#199,#200,#201));
#198=ORIENTED_EDGE('',*,*,#202,.T.);
#199=ORIENTED_EDGE('',*,*,#203,.T.);
#200=ORIENTED_EDGE('',*,*,#204,.T.);
#201=ORIENTED_EDGE('',*,*,#205,.T.);
#202=EDGE_CURVE('',#109,#111,#206,.F.);
#203=EDGE_CURVE('',#111,#113,#207,.T.);
#204=EDGE_CURVE('',#113,#115,#208,.T.);
#205=EDGE_CURVE('',#115,#109,#209,.T.);
#206=LINE('',#108,#210);
#207=LINE('',#110,#211);
#208=LINE('',#112,#212);
#209=LINE('',#114,#213);
#210=VECTOR('',#214,1.0);
#211=VECTOR('',#215,1.0);
#212=VECTOR('',#216,1.0);
#213=VECTOR('',#217,1.0);
#214=DIRECTION('',(0.000000000,0.000000000,1.000000000));
#215=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#216=DIRECTION('',(0.000000000,0.000000000,-1.000000000));
#217=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#218=STYLED_ITEM('',(#219),#226);
#219=PRESENTATION_STYLE_ASSIGNMENT((#220));
#220=SURFACE_STYLE_USAGE(.BOTH.,#221);
#221=SURFACE_SIDE_STYLE('',(#222));
#222=SURFACE_STYLE_FILL_AREA(#223);
#223=FILL_AREA_STYLE('',(#224));
#224=FILL_AREA_STYLE_COLOUR('',#225);
#225=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#226=FACE_SURFACE('',(#231),#227,.T.);
#227=PLANE('',#228);
#228=AXIS2_PLACEMENT_3D('',#116,#229,#230);
#229=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#230=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#231=FACE_BOUND('',#232,.T.);
#232=EDGE_LOOP('',(#233,#234,#235,#236));
#233=ORIENTED_EDGE('',*,*,#237,.T.);
#234=ORIENTED_EDGE('',*,*,#238,.T.);
#235=ORIENTED_EDGE('',*,*,#239,.T.);
#236=ORIENTED_EDGE('',*,*,#240,.T.);
#237=EDGE_CURVE('',#117,#119,#241,.F.);
#238=EDGE_CURVE('',#119,#121,#242,.T.);
#239=EDGE_CURVE('',#121,#123,#243,.T.);
#240=EDGE_CURVE('',#123,#117,#244,.T.);
#241=LINE('',#116,#245);
#242=LINE('',#118,#246);
#243=LINE('',#120,#247);
#244=LINE('',#122,#248);
#245=VECTOR('',#249,1.0);
#246=VECTOR('',#250,1.0);
#247=VECTOR('',#251,1.0);
#248=VECTOR('',#252,1.0);
#249=DIRECTION('',(0.000000000,0.000000000,1.000000000));
#250=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#251=DIRECTION('',(0.000000000,0.000000000,-1.000000000));
#252=DIRECTION('',(0.000000000,1.000000000,0.000000000));
#253=STYLED_ITEM('',(#254),#261);
#254=PRESENTATION_STYLE_ASSIGNMENT((#255));
#255=SURFACE_STYLE_USAGE(.BOTH.,#256);
#256=SURFACE_SIDE_STYLE('',(#257));
#257=SURFACE_STYLE_FILL_AREA(#258);
#258=FILL_AREA_STYLE('',(#259));
#259=FILL_AREA_STYLE_COLOUR('',#260);
#260=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#261=FACE_SURFACE('',(#266),#262,.T.);
#262=PLANE('',#263);
#263=AXIS2_PLACEMENT_3D('',#124,#264,#265);
#264=DIRECTION('',(0.000000000,1.000000000,-0.000000000));
#265=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#266=FACE_BOUND('',#267,.T.);
#267=EDGE_LOOP('',(#268,#269,#270,#271));
#268=ORIENTED_EDGE('',*,*,#272,.T.);
#269=ORIENTED_EDGE('',*,*,#273,.T.);
#270=ORIENTED_EDGE('',*,*,#274,.T.);
#271=ORIENTED_EDGE('',*,*,#275,.T.);
#272=EDGE_CURVE('',#125,#127,#276,.F.);
#273=EDGE_CURVE('',#127,#129,#277,.T.);
#274=EDGE_CURVE('',#129,#131,#278,.T.);
#275=EDGE_CURVE('',#131,#125,#279,.T.);
#276=LINE('',#124,#280);
#277=LINE('',#126,#281);
#278=LINE('',#128,#282);
#279=LINE('',#130,#283);
#280=VECTOR('',#284,1.0);
#281=VECTOR('',#285,1.0);
#282=VECTOR('',#286,1.0);
#283=VECTOR('',#287,1.0);
#284=DIRECTION('',(0.000000000,0.000000000,1.000000000));
#285=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#286=DIRECTION('',(0.000000000,0.000000000,-1.000000000));
#287=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#288=STYLED_ITEM('',(#289),#296);
#289=PRESENTATION_STYLE_ASSIGNMENT((#290));
#290=SURFACE_STYLE_USAGE(.BOTH.,#291);
#291=SURFACE_SIDE_STYLE('',(#292));
#292=SURFACE_STYLE_FILL_AREA(#293);
#293=FILL_AREA_STYLE('',(#294));
#294=FILL_AREA_STYLE_COLOUR('',#295);
#295=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#296=FACE_SURFACE('',(#301),#297,.T.);
#297=PLANE('',#298);
#298=AXIS2_PLACEMENT_3D('',#132,#299,#300);
#299=DIRECTION('',(-0.000000000,0.000000000,1.000000000));
#300=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#301=FACE_BOUND('',#302,.T.);
#302=EDGE_LOOP('',(#303,#304,#305,#306));
#303=ORIENTED_EDGE('',*,*,#307,.T.);
#304=ORIENTED_EDGE('',*,*,#308,.T.);
#305=ORIENTED_EDGE('',*,*,#309,.T.);
#306=ORIENTED_EDGE('',*,*,#310,.T.);
#307=EDGE_CURVE('',#133,#135,#311,.F.);
#308=EDGE_CURVE('',#135,#137,#312,.T.);
#309=EDGE_CURVE('',#137,#139,#313,.T.);
#310=EDGE_CURVE('',#139,#133,#314,.T.);
#311=LINE('',#132,#315);
#312=LINE('',#134,#316);
#313=LINE('',#136,#317);
#314=LINE('',#138,#318);
#315=VECTOR('',#319,1.0);
#316=VECTOR('',#320,1.0);
#317=VECTOR('',#321,1.0);
#318=VECTOR('',#322,1.0);
#319=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#320=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#321=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#322=DIRECTION('',(0.000000000,1.000000000,0.000000000));
#323=STYLED_ITEM('',(#324),#331);
#324=PRESENTATION_STYLE_ASSIGNMENT((#325));
#325=SURFACE_STYLE_USAGE(.BOTH.,#326);
#326=SURFACE_SIDE_STYLE('',(#327));
#327=SURFACE_STYLE_FILL_AREA(#328);
#328=FILL_AREA_STYLE('',(#329));
#329=FILL_AREA_STYLE_COLOUR('',#330);
#330=COLOUR_RGB('',0.800000012,0.800000012,0.800000012);
#331=FACE_SURFACE('',(#336),#332,.T.);
#332=PLANE('',#333);
#333=AXIS2_PLACEMENT_3D('',#140,#334,#335);
#334=DIRECTION('',(-0.000000000,-0.000000000,-1.000000000));
#335=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#336=FACE_BOUND('',#337,.T.);
#337=EDGE_LOOP('',(#338,#339,#340,#341));
#338=ORIENTED_EDGE('',*,*,#342,.T.);
#339=ORIENTED_EDGE('',*,*,#343,.T.);
#340=ORIENTED_EDGE('',*,*,#344,.T.);
#341=ORIENTED_EDGE('',*,*,#345,.T.);
#342=EDGE_CURVE('',#141,#143,#346,.F.);
#343=EDGE_CURVE('',#143,#145,#347,.T.);
#344=EDGE_CURVE('',#145,#147,#348,.T.);
#345=EDGE_CURVE('',#147,#141,#349,.T.);
#346=LINE('',#140,#350);
#347=LINE('',#142,#351);
#348=LINE('',#144,#352);
#349=LINE('',#146,#353);
#350=VECTOR('',#354,1.0);
#351=VECTOR('',#355,1.0);
#352=VECTOR('',#356,1.0);
#353=VECTOR('',#357,1.0);
#354=DIRECTION('',(-1.000000000,0.000000000,0.000000000));
#355=DIRECTION('',(0.000000000,-1.000000000,0.000000000));
#356=DIRECTION('',(1.000000000,0.000000000,0.000000000));
#357=DIRECTION('',(0.000000000,1.000000000,0.000000000));
ENDSEC;
END-ISO-10303-21;

View File

@ -1,115 +0,0 @@
import fs from "fs";
import path from "path";
import { spawn } from "child_process";
import color from "picocolors";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const toktx = path.join(__dirname, "..", "bin", "toktx.exe");
// 检查 toktx 是否存在
export function checkToktx() {
if (!fs.existsSync(toktx)) {
console.error("❌ 找不到 toktx.exe");
process.exit(1);
}
}
// 扫描图片文件
export function scanImages(exts) {
console.log("🔍 扫描目标文件中...");
const cwd = process.cwd();
const images = fs.readdirSync(cwd).filter(f =>
exts.some(ext => f.toLowerCase().endsWith("." + ext))
);
return { images, cwd };
}
// 构建压缩参数
export function buildArgs(input, output, config) {
const args = ["--t2"];
if (config.encoding === "uastc") {
args.push("--encode", "uastc");
const zcmpLevel = { none: "0", standard: "10", high: "18", extreme: "22" };
args.push("--zcmp", zcmpLevel[config.quality] || "10");
} else if (config.encoding === "etc1s") {
args.push("--encode", "etc1s");
} else if (config.encoding === "astc") {
args.push("--encode", "astc");
const blkSize = { none: "8x8", standard: "6x6", high: "5x5", extreme: "4x4" };
args.push("--astc_blk_d", blkSize[config.quality] || "6x6");
}
if (config.mipmap === "auto") {
args.push("--genmipmap");
}
args.push(output, input);
return args;
}
// 压缩单个文件
export function compressFile(img, config, cwd, progress) {
const baseName = img.replace(/\.[^.]+$/, "");
const out = baseName + ".ktx2";
// 点动画
let dots = 0;
const dotAnim = setInterval(() => {
const dotStr = ".".repeat(dots);
process.stdout.write(`\r${progress} ${img} 正在转换中${dotStr} `);
dots = dots >= 3 ? 0 : dots + 1;
}, 300);
process.stdout.write(`${progress} ${img} 正在转换中.`);
const args = buildArgs(img, out, config);
return new Promise((resolve) => {
const proc = spawn(toktx, args, { cwd });
let stderr = "";
proc.stderr?.on("data", data => {
stderr += data.toString();
});
proc.on("close", code => {
clearInterval(dotAnim);
if (code === 0) {
console.log(`\r${progress} ${color.green("✓")} ${out} `);
resolve({ success: true });
} else {
console.log(`\r${progress} ${color.red("✗")} ${img} 失败 `);
if (stderr) {
console.log(color.dim(` 错误: ${stderr.trim()}`));
}
resolve({ success: false, error: stderr });
}
});
proc.on("error", err => {
clearInterval(dotAnim);
console.log(`\r${progress} ${color.red("✗")} ${img} 失败 `);
console.log(color.dim(` 错误: ${err.message}`));
resolve({ success: false, error: err.message });
});
});
}
// 批量压缩
export async function compressAll(images, config, cwd) {
const total = images.length;
let finished = 0;
let failed = 0;
for (const img of images) {
finished++;
const progress = `(${finished}/${total})`;
const result = await compressFile(img, config, cwd, progress);
if (!result.success) failed++;
}
return { total, failed };
}

View File

@ -1,62 +0,0 @@
// 步骤配置
export const steps = [
{
name: "文件格式",
type: "multiselect",
message: "请选择要压缩的图片类型",
options: [
{ value: "png", label: "PNG (.png)(无损格式,适合图标和透明图)" },
{ value: "jpg", label: "JPG (.jpg)(有损格式,适合照片和复杂图像)" },
{ value: "jpeg", label: "JPEG (.jpeg)同JPG仅扩展名不同" },
{ value: "webp", label: "WebP (.webp)(新一代格式,体积更小)" },
{ value: "tga", label: "TGA (.tga)(游戏纹理常用格式)" }
],
default: ["png", "jpg"]
},
{
name: "压缩程度",
type: "select",
message: "请选择压缩级别",
options: [
{ value: "none", label: "无压缩(原始质量)", hint: "保持原始文件大小,图片和内容无损" },
{ value: "standard", label: "标准压缩(推荐)", hint: "平衡文件大小与质量压缩率约40%" },
{ value: "high", label: "高度压缩(最小体积)", hint: "最大程度减小文件体积,可能轻微影响清晰度" },
{ value: "extreme", label: "极限压缩(极致压缩)", hint: "牺牲部分质量换取最小体积,适合网络传输" }
],
default: "standard"
},
{
name: "编码格式",
type: "select",
message: "请选择编码格式",
options: [
{ value: "uastc", label: "UASTC通用超压缩纹理", hint: "高质量GPU纹理解码快适合实时渲染" },
{ value: "etc1s", label: "ETC1S基础压缩纹理", hint: "文件体积最小,兼容性好,适合移动端" },
{ value: "astc", label: "ASTC自适应纹理压缩", hint: "灵活块大小,质量与体积可调,适合高端设备" }
],
default: "uastc"
},
{
name: "Mipmap",
type: "select",
message: "请选择Mipmap生成方式",
options: [
{ value: "auto", label: "自动生成(推荐)", hint: "根据图片尺寸自动生成多级纹理,优化远距离渲染" },
{ value: "none", label: "不生成Mipmap", hint: "仅保留原始尺寸,文件更小但可能出现锯齿" },
{ value: "custom", label: "自定义层级", hint: "手动指定Mipmap层数精细控制纹理细节" }
],
default: "auto"
},
{
name: "输出选项",
type: "multiselect",
message: "请选择输出选项",
options: [
{ value: "overwrite", label: "覆盖已存在文件(自动替换同名文件)" },
{ value: "keepOriginal", label: "保留原文件(压缩后不删除源文件)" },
{ value: "report", label: "生成压缩报告(输出详细的压缩统计信息)" },
{ value: "silent", label: "静默模式(减少控制台输出信息)" }
],
default: ["overwrite", "keepOriginal"]
}
];

View File

@ -2,6 +2,8 @@ import fs from "fs";
import { getImportExtensions, getExportFormats } from "./converters.js"; import { getImportExtensions, getExportFormats } from "./converters.js";
import { sortByUsage } from "../stats.js"; import { sortByUsage } from "../stats.js";
const EXCLUDED_FORMATS = ["x", "glb", "gltf"];
export function listConvertibleFiles() { export function listConvertibleFiles() {
const cwd = process.cwd(); const cwd = process.cwd();
const exts = getImportExtensions(); const exts = getImportExtensions();
@ -13,7 +15,7 @@ export function listConvertibleFiles() {
export function getSteps() { export function getSteps() {
const files = listConvertibleFiles(); const files = listConvertibleFiles();
const formats = sortByUsage("convert_format", getExportFormats()); const formats = sortByUsage("convert_format", getExportFormats().filter(f => !EXCLUDED_FORMATS.includes(f)));
return [ return [
{ {

View File

@ -7,9 +7,9 @@ import { stopKeypress, initKeypress, onKey } from "../keyboard.js";
import { record } from "../stats.js"; import { record } from "../stats.js";
const FORMAT_EXT = { const FORMAT_EXT = {
collada: ".dae", x: ".x", stp: ".stp", obj: ".obj", objnomtl: ".obj", collada: ".dae",stp: ".stp", obj: ".obj", objnomtl: ".obj",
stl: ".stl", stlb: ".stl", ply: ".ply", plyb: ".ply", "3ds": ".3ds", stl: ".stl", stlb: ".stl", ply: ".ply", plyb: ".ply", "3ds": ".3ds",
gltf2: ".gltf", glb2: ".glb", gltf: ".gltf", glb: ".glb", gltf2: ".gltf", glb2: ".glb",
assbin: ".assbin", assxml: ".assxml", x3d: ".x3d", assbin: ".assbin", assxml: ".assxml", x3d: ".x3d",
fbx: ".fbx", fbxa: ".fbx", "3mf": ".3mf", pbrt: ".pbrt", assjson: ".json" fbx: ".fbx", fbxa: ".fbx", "3mf": ".3mf", pbrt: ".pbrt", assjson: ".json"
}; };

View File

@ -34,7 +34,24 @@ export function createStepUI(options) {
lines.push(color.dim(step.emptyMessage || "无可用选项")); lines.push(color.dim(step.emptyMessage || "无可用选项"));
return lines.join("\n"); return lines.join("\n");
} }
step.options.forEach((opt, i) => {
// 计算可显示的行数(终端高度 - 标题/导航/提示占用的行数)
const termHeight = process.stdout.rows || 24;
const reservedLines = 8;
const maxVisible = Math.max(5, termHeight - reservedLines);
const total = step.options.length;
// 计算滚动窗口
let start = 0;
if (total > maxVisible) {
start = Math.max(0, Math.min(currentOption - Math.floor(maxVisible / 2), total - maxVisible));
}
const end = Math.min(start + maxVisible, total);
if (start > 0) lines.push(color.dim(" ↑ 更多选项..."));
for (let i = start; i < end; i++) {
const opt = step.options[i];
const isCurrent = i === currentOption; const isCurrent = i === currentOption;
const isSelected = step.type === "multiselect" const isSelected = step.type === "multiselect"
? results[currentStep]?.includes(opt.value) ? results[currentStep]?.includes(opt.value)
@ -46,13 +63,15 @@ export function createStepUI(options) {
const label = isCurrent ? color.cyan(opt.label) : opt.label; const label = isCurrent ? color.cyan(opt.label) : opt.label;
const check = isSelected ? color.green(" ✓") : ""; const check = isSelected ? color.green(" ✓") : "";
lines.push(cursor + prefix + label + check); lines.push(cursor + prefix + label + check);
if (opt.hint) lines.push(" " + color.dim(opt.hint)); }
});
if (end < total) lines.push(color.dim(" ↓ 更多选项..."));
return lines.join("\n"); return lines.join("\n");
} }
function render() { function render() {
console.clear(); process.stdout.write('\x1Bc');
console.log(color.bgCyan(color.black(` ${title} `))); console.log(color.bgCyan(color.black(` ${title} `)));
console.log("\n" + renderNav()); console.log("\n" + renderNav());
console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n")); console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n"));

View File

@ -1,7 +1,7 @@
{ {
"name": "@yinshuangxi/yinx-cli", "name": "@yinshuangxi/yinx-cli",
"version": "1.0.2", "version": "1.0.3",
"description": "游戏资源工具箱 - KTX2纹理压缩、模型压缩等", "description": "子归云工具箱-你想要的都在这",
"main": "dist/index.js", "main": "dist/index.js",
"type": "module", "type": "module",
"scripts": { "scripts": {