mcpField
M
machine

machine

github.com/airsuphq创意与媒体435208 次安装2 周前更新
代码仓库

关于 machine

machine 是用于制作机器交互式 3D 展示和影片的技能,面向希望呈现真实结构与运行原理的创作者。它以单行描述为起点,要求使用真实尺寸、实体部件和计算得出的物理数据,并输出独立 HTML 页面及影片。

主要功能

  1. 01生成自包含的 three.js 页面
  2. 02按真实尺寸构建实体部件
  3. 03呈现剖切、爆炸与透视模式
  4. 04用方程计算显示数据与运动
  5. 05制作标准时长的机器影片

适用场景

  1. 01制作涡扇发动机的交互式展示
  2. 02展示机器内部结构和部件装配
  3. 03演示滑块输入对运行状态的影响
  4. 04呈现故障及其计算结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/airsuphq/machine-skill --skill machine

安装后在 Claude Code 中输入/machine确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
LICENSE
CHANGELOG.md
.gitignore
CONTRIBUTING.md
LAUNCH.md
V2-IDEAS.md
package.json
.github/
REPO.md
evals/
evals.json
examples/
compressor.html
rocket-engine.html
turbofan.html
refinery-pump.html
film/
README.md
reply.html
launch.html
kit/
template.html
lab-kit.js
references/
solvers.md
scripts/
inline.mjs
shot.mjs
record.mjs
pinkscan.mjs
scripts/lib/
browser.mjs
guard.mjs
serve.mjs
png.mjs

详细介绍

机器技能

像产品工作室拍摄机器、工程师讲解机器那样,打造一台机器:以真实尺寸、真实材料呈现真实设备,置于整洁的摄影棚布景中,并由真实方程驱动。输入一行命令,输出一个 HTML 文件,并通过一条命令制作影片。

输出始终包括:

  1. <name>.html:一个独立页面(使用 jsDelivr 上的 three.js 0.170,工具包内嵌其中)。它可直接从磁盘打开,也可通过任意静态主机或在 iframe 中打开。
  2. 一部影片:node scripts/record.mjs <name>.html out/<name>.mp4 --music freepd:<Category>/<Name>。

先打开 examples/。每个示例都是根据页面顶部那一行内容制作的。examples/turbofan.html 是参考范例:动手写之前,先从头到尾读一遍。

标准

开始之前,先想象观众三秒后看到的画面。它一开始就必须像真实机器的摄影棚产品照:轮廓和比例正确,金属看起来像金属,纸面地板上有柔和的阴影,没有悬浮、穿插或占位内容。随后机器开始运动,屏幕上的每个数值都由计算得出。

只要存在以下任一问题,结果就还没有完成:

  • 缺少技师理应看到的部件(燃烧室里没有燃油喷嘴、手表里没有擒纵机构、发动机里没有气门)
  • 有部件悬浮、相交,或接缝处有明显的缝线或间隙
  • 材料看起来像塑料而非金属,或所有部件都是同一种灰色
  • 屏幕上的数值是手动输入的,而不是由求解器计算得出
  • 剖切视图显示的是中空壳体,而非实心剖面
  • 影片的第一帧不够美观

工作流程

1. 研究真实机器(5 分钟,不写代码)

在机器脚本顶部的注释块中,根据已有知识(如有条件,也可查阅网络)写下:

  • 真实尺寸:以米为单位,列出 5 到 10 个决定机器轮廓的部件(以涡扇发动机为例:风扇直径 2.85 m、长度 4.9 m、短舱最大直径 3.44 m)。
  • 部件清单:按装配顺序列出,并标注每个部件的材料。目标是列出 15 到 40 个有名称的部件;重复部件(叶片、齿、螺栓、线圈)分别计数。
  • 物理原理:用 3 到 6 个你会实际计算的方程,说明机器如何工作,并给出真实常数和运行工况(以涡扇发动机为例:布雷顿循环、起飞时 N1 100 %、OPR 42、T4 1,750 K、推力约 330 kN)。
  • 一个关键数值:观众最关心的数值,例如推力、扭矩、每小时振次、流量或功率。用醒目的大号衬线字体显示,并配一条细长进度条。
  • 输入项:观众希望调整的一个滑块,例如油门、风速、转速、泵速或研磨粒度。
  • 故障情形:工程师担心的故障及求解器给出的后果,例如风扇叶片脱落及其不平衡载荷、气门在红线转速以上发生浮阀、泵失速或超压。后果必须是计算得出的,不能只是动画效果。
2. 根据模板构建页面

将 kit/template.html 复制为 <name>.html。模板包含导入映射(固定使用 [email protected])、字体、用于放置工具包的标记区块,以及需要填写的四个部分:

const { THREE, Lab, MAT, GEO, heatGlow, clamp, lerp, approach, fmt } = window.LabKit
const lab = new Lab({ prompt, no, title, sub, size, view, cut })   // 1. the lab
// 2. the parts      lab.mesh(GEO..., MAT..., { name, pos, explode, xray, count })
// 3. the solver     lab.hero(...); lab.slider(...); lab.onTick((dt, lab) => { ... lab.setHero(...) })
// 4. break, explain, film      lab.breakIt(...); lab.how(...); lab.autoFilm(...); lab.start()

复制后立即运行 node <skill dir>/scripts/inline.mjs <name>.html:它会将工具包粘贴到标记区块中,让页面成为一个独立文件,无论文件存放在哪里都能使用(模板中的 src="../kit/lab-kit.js" 只有在此仓库中才能解析)。然后在第二个脚本区块中编写机器。

3. 几何体:真实尺寸的实体

以机器自身坐标系中的米为单位建模,Y 轴朝上,除非设置 ground,否则地面位于 y = 0。将 size 设为最长的实际尺寸;工具包会缩放显示效果,让布景中的每台机器大小一致,比例尺则显示实际尺寸。

  • 圆形部件(轴、圆盘、外壳、喷嘴、圆锥、旋转件、活塞、装饰圈):使用带闭合轮廓的 GEO.lathe([[r, y], ...])。壁面:GEO.shell(profile, thickness);管件:GEO.tube(rOut, rIn, h);倒角圆盘:GEO.disc(r, h)。转角保持锐利,曲面会自动平滑着色。
  • 叶片和导叶:GEO.rotor({ count, axis, r0, r1, chord, thick, camber, twist, pitch, sweep }) 可构建带弯度和扭转的真实翼型(NACA 厚度),并将其制成闭合实体和环形排列。弦长、厚度和弯度使用 [root, tip] 数组。
  • 齿轮:GEO.gear({ teeth, module, width, bore, helix, spokes, rim })。两齿轮的中心距设为 (z1 + z2) * module / 2,并按齿数比的倒数转动,错开半个齿距。
  • 管道、软管、电线:GEO.pipe(points, r)(闭合、带端盖)。沿结构从一个接口布设至另一个接口,切勿穿过部件。
  • 紧固件:每个法兰上都加 GEO.bolts(n, R, size, h)。弹簧:GEO.spring(R, wire, turns, len)。箱体:GEO.rbox(w, h, d, r)(始终为圆角,不要做成尖角)。带孔板件:GEO.extrude(shape, depth)。
  • 质量和惯量根据几何体计算:GEO.volume(geo) 可得体积和质心,再乘以实际密度。

保持模型整洁的规则:

  • 每个部件都是闭合实体(闭合的车削轮廓、带厚度的壳体、带端盖的管道)。这样剖切时才能绘制实体剖面。剖切时,开放曲面会显示为中空。
  • **部件之间不可有明显交叠或悬空。**每个部件都必须接触支撑它的结构(法兰贴合端面、轴穿过轴承、支柱延伸至地面)。请在特写中检查连接处。
  • 在视觉焦点处添加细节:法兰上的螺栓孔圈、倒角、凸缘、铭牌、燃油管路、线束。大片平面区域应添加接缝、面板线或纹理饰面。
  • 为机器添加底座:支架、托架、基座、工作台或带落地支脚的底座。现实中的机器很少悬浮。
  • 预算:最多约 70 万个三角形和 200 个网格。使用 GEO.merge / GEO.ring 合并重复的静态部件;移动部件组则保持独立。
4. 材质:不能只有一种灰色

使用 MAT.* 预设;这些预设采用实测反射率,让钢、钛、铝、黄铜和铜并排时呈现出不同质感。每个预设都支持覆盖参数(color、roughness、clearcoat 以及任何 MeshPhysicalMaterial 字段)和 finish(微观粗糙度纹理:车削部件上的 turned 环纹、brushed 刷痕、cast 铸造斑点、smudge 污痕、knurl 滚花)。

用途预设
轴、圆盘、机加工部件MAT.steel、MAT.stainless、MAT.chrome
外壳、铸件MAT.aluminium、MAT.castIron、MAT.steelDark
叶片、航空航天部件MAT.titanium、MAT.inconel(加上 heatGlow)
接头、布线MAT.brass、MAT.copper、MAT.gold
喷漆机身MAT.paint({ color })、MAT.satin、MAT.anodised({ color })
聚合物MAT.plastic、MAT.rubber、MAT.carbon
窗口、晶体MAT.glass、MAT.sapphire、MAT.ruby、MAT.enamel
光、火焰、高温气体MAT.glow、heatGlow(material, kelvin)

像工业设计师一样选择配色:以金属色为主,搭配一两种喷漆颜色,最多使用一种强调色。热部件根据求解器给出的温度发光(material.userData.heat.value = T)。

5. 求解器:只用真实数值

编写一个简单的纯函数,根据输入和状态计算你展示的每个数值,并使用真实单位和真实常数。用 approach(一阶滞后:加速、热惯性)或 rk4(弹簧、擒纵机构、摆)积分动力学。然后用它驱动运动:求解器算出的 rpm 带动轴旋转,算出的流量推动粒子,算出的温度加热金属。

  • 一个主指标:每个刻度调用 lab.hero({ label, unit, max }),然后调用 lab.setHero(value, { state, sub, bad })。state 用两三个词描述(加速中、起飞、阻塞流)。sub 用一行显示另外 2 或 3 个数值。
  • 一个滑块:lab.slider({ id, label, min, max, value, unit, ends })。只有机器确实需要时才添加第二个。
  • 在剖切平面的点位,将标签固定在静止部件上:lab.label(obj, 'HP turbine', { at: [x, y, z], value: () => '12,979 rpm' })。
  • lab.how(words, equations) 填写“计算方式”:用通俗文字说明模型,并写出代码中的方程。说明做了哪些简化。
  • 如果某个运动快到看不清(例如转速为 2,700 rpm 的风扇),就放慢显示速度,并在 how 中说明(“显示转速为原来的 1:60”)。绝不要放慢数值。
  • 根据第 1 步记录的公开数据检查工作点。如果偏差超过约 20%,就修正模型,而不是修改数据。
6. 流动、热量和效果
  • lab.flow({ paths, count, length, color, parent }):沿着根据真实流路构建的路径生成流线(空气穿过风道、血液流经泵、水流过冰球)。根据求解器设置 .speed,根据 lab.state.cut 设置 .opacity,让流线显示在剖切视图中。根据计算出的量(温度、压力)设置颜色。
  • lab.plume({ radius, length, dir, color: 'rocket' | 'jet', shocks }):生成带马赫菱形的排气流;根据求解器设置 .power。
  • 出现断裂时,使用 lab.sparks.emit(worldPos, n, speed) 和 lab.shed(mesh, v, w):火花受重力下落并弹跳;脱落的部件会变成刚体并落到地面。
7. 模式(工具包会处理;你负责设置)
  • 爆炸视图:每个 lab.add/lab.mesh 都可以在父级坐标系中使用 explode: [dx, dy, dz](单位:米)。沿装配轴移动部件;外壳移动最远,并让核心保持原位。部件在移出时不得相互穿过。
  • 剖切视图:在 Lab 上设置 cut: { a, b, center, reach }。a 和 b 表示被移除区域的方向:a = [0,0,1], b = [0,1,0] 会移除朝向观察者且位于上方的四分之一部分(最适合带轴的物体);b = a 会移除一半。系统会自动为每个封闭实体绘制剖切面,并加上浅色剖面线。
  • X 光视图:在外壳上设置 xray: 'shell',使其呈现玻璃质感并带有精细边缘,让运行中的核心显现出来。
  • 慢动作、标签、暂停开箱即用(按键 S、L、Space)。交互方式包括鼠标旋转视角、滑块和按钮。
  • 使其故障:使用 lab.breakIt({ label, run(lab), reset(lab) })。run 会改变求解器状态(叶片脱落、阀门卡住、密封失效),由求解器计算后果。通过主指标(bad: true)以及火花、碎片或震动来展示故障。
8. 像评论家一样审视作品(必做)

渲染并仔细查看你制作的每张图片。使用以下脚本:

node scripts/shot.mjs <name>.html out/review.png                               # the first look
node scripts/shot.mjs <name>.html out/cut.png --js "lab.toggle('cut', true); lab.toggle('labels', true)"
node scripts/shot.mjs <name>.html out/near.png --js "lab.setView({ az: 70, el: 8, dist: 0.8, target: [x, y, z] })"
node scripts/shot.mjs <name>.html out/film --film 1,4,8,12,17,22,26                 # film stills

至少进行四轮审查。每轮都要查看整体视图、带标签的剖切视图、爆炸视图、两张关节特写以及影片静帧。对照你记忆中的真实产品照片,检查比例、部件数量、材质和光线效果。列出所有问题,修复后再次渲染。只有问题清单为空时才能停止。截图脚本会输出 fps、部件数和三角形数;交互帧率必须高于 30。

9. 影片

lab.autoFilm({ runBeat, runSub, breakBeat, breakSub, sliderTo }) 会在你的机器上生成标准的 28 秒故事片,分为编号镜头,并配有以下编辑说明:

  1. 一句话就是全部任务说明(提示词栏会自动输入)。
  2. Claude 构建机器(部件按组装顺序飞入,同时计数器递增:“84 of 3,597 parts”)。
  3. 机器运行(光标拖动滑块;主数值根据求解器结果递增)。
  4. 剖开机器(剖切端盖、带实时数值的标签)。
  5. 拆解机器(爆炸视图)。
  6. 让机器故障(光标点击故障按钮;求解器决定故障点)。

影片会循环播放:最后一个摄像机关键帧会回到第一个关键帧。要制作自定义影片,请使用 lab.film('name', { len, assemble, shots, events }):镜头为摄像机关键帧 { t, az, el, dist, target, fov },事件为 { t, beat: ['07', 'Bold sentence.', 'Grey sentence.'], set: { cut: 1 }, slider: { id, to, dur }, cursor: { to: 'slider:id:0.8' | 'button:break' | [x, y], click: true }, do(lab) {} }。

录制(需要 Node 18+、带 Chromium 的 Playwright、ffmpeg):

node scripts/record.mjs <name>.html out/<name>.mp4 --music freepd:Classical/Easy_Lemon
node scripts/record.mjs <name>.html out/<name>-portrait.mp4 --w 1080 --h 1350

页面以影片模式运行(?film=1):只有录制器推进时钟,页面才会向前运行,因此每一帧都是完整的,每次录制的影片也完全相同。录制器会检查每张截图,防止停滞的无头 GPU 返回洋红色画面,并扫描成片;如果任何一帧呈粉色,程序就会以非零状态退出。配乐来自 FreePD,采用 CC0 许可;仍请注明曲目来源。

屏幕文案

页面是编辑呈现,不是仪表盘:提示词栏、衬线字体标题和斜体副标题、一个醒目的大数字(带斜体单位和细条)、一行辅助数字、一个滑块。文案要像出色的说明文字:简短、具体、不夸张,使用真实单位,单位前留空格(338 kN、1,750 K、4.2 L/min),千位之间加分隔符。镜头说明由一句粗体句子和一句灰色句子组成。

交付时要说明的内容

提供 HTML 文件的路径、影片命令、求解器达到的工作点与公开数据的对比,以及你做过的简化。并提出下一台机器。

评论

支持 Markdown