Communitygithub.com

机器仿真技能

将一句话(如“涡轮风扇发动机”、“机械手表”、“LVAD心脏泵”)转化为一个逼真的、基于物理的交互式3D仿真HTML文件,并附带一段20-30秒的宣传短片。包含真实尺寸、真实材质、工作室灯光、由求解器驱动的运动部件,以及爆炸、剖切、X光透视、慢放、标注和破坏模式。

机器仿真技能 是什么?

该技能旨在根据用户对任意机械、发动机、机构、设备或硬件的一句话描述,自动生成一个完整、可交互的3D仿真HTML文件,并附带可用于社交媒体的宣传短片。其核心是“真实”:几何尺寸基于真实公制,材质采用基于物理的渲染(PBR),运动由内嵌的物理求解器(计算推力、扭矩、转速、流量、压力、效率等实数)驱动,而非预设动画。用户可交互操作:拖拽滑块控制输入(如油门),切换爆炸、剖切、X光、慢放等视图模式,点击“破坏”按钮观察求解器计算的失效后果。输出为单文件HTML(基于 Three.js 0.170),可直接从磁盘或任意静态服务器打开,并可通过命令行录制高精度短片。该技能适用于任何需要构建、模拟、可视化、解释机械工作原理的场景。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/WU7475/skill-backup/tree/main/machine

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

机器仿真技能 是做什么的?

你构建机器的方式,如同产品工作室的摄影师和工程师的讲解:真实尺寸、真实材质、洁净的摄影棚布景,由真实的方程驱动。一句话输入,一个HTML文件输出,一条命令生成短片。

输出始终是:

  1. <name>.html:一个完全自包含的页面(three.js 0.170 来自 jsDelivr,工具包内联)。可直接从磁盘、任意静态主机或 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 米,长度 4.9 米,短舱最大直径 3.44 米)。
  • 零件清单:按装配顺序列出,每个零件附带其材质。目标15到40个命名零件;重复零件(叶片、齿、螺栓、线圈等)单独计数。
  • 物理原理:3到6个你将实际计算的方程,包含真实常数和工作点(例如涡轮风扇:布雷顿循环,起飞时N1 100%,OPR 42,T4 1,750 K,约 330 kN)。
  • 观众关心的一个核心数值:关键指标(推力、扭矩、节拍次数/小时、流量、功率)。它将显示为大号衬线数字和细条形图。
  • 观众想要操控的一个输入:一个滑块(油门、风速、转速、泵速、研磨度)。
  • 故障模式:工程师担心的失效及其对求解器的影响(风扇叶片脱落及不平衡载荷、红线转速以上气门浮动、泵失速、过压)。这必须是计算得出的后果,而非动画。

2. 基于模板构建页面

将 kit/template.html 复制为 <name>.html。它包含 import map(固定 [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. lab
// 2. 零件      lab.mesh(GEO..., MAT..., { name, pos, explode, xray, count })
// 3. 求解器     lab.hero(...); lab.slider(...); lab.onTick((dt, lab) => { ... lab.setHero(...) })
// 4. 破坏、解释、短片      lab.breakIt(...); lab.how(...); lab.autoFilm(...); lab.start()

复制后立即运行 node <skill dir>/scripts/inline.mjs <name>.html:它会将工具包粘贴到标记的块中,使页面成为完全自包含的文件(模板中的 src="../kit/lab-kit.js" 仅在此仓库内有效)。然后在第二个脚本块中编写你的机器。

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

在机器自身框架内以米为单位工作,Y 轴向上,地板位于 y = 0(除非你设置了 ground)。将 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) 返回体积和质心,乘以实际密度。

保持整洁的规则:

  • 每个零件都是闭合实体(lathe 轮廓闭合,shell 带厚度,pipe 加盖)。这是剖切能绘制实心截面的基础。开放表面在剖切时显示为空心。
  • 无可见交叉,无漂浮。 每个零件与支撑它的零件接触(法兰贴合在面上,轴在轴承中运转,立柱接触地面)。近距离检查连接处。
  • 细节集中在视线焦点:法兰上的螺栓孔、倒角、边缘、铭牌、燃油管、线束。大平面区域添加接缝、面板线或纹理饰面。
  • 为机器提供底座:支架、托架、基座、工作台或带脚的安装座,放置在地板上。现实中机器很少悬浮。
  • 预算:最多约 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(弹簧、擒纵机构、钟摆)进行动力学积分。然后根据求解器驱动运动:来自求解器的转速驱动轴旋转,流动驱动粒子移动,温度加热金属。

  • 一个核心数值: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 转/分的风扇),则减慢显示速度并在 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                               # 第一印象
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                 # 电影静帧

至少进行四轮审查。每轮包括:整体视图、带标签的剖切视图、爆炸视图、两个连接处特写以及电影静帧。与记忆中真实机器的产品摄影照片进行比较:比例、零件数量、材质、光线效果。列出所有问题,修复问题,再次渲染。仅在列表为空时停止。shot脚本会输出帧率、零件数量和三角形数;保持交互帧率高于30。

9. 短片

lab.autoFilm({ runBeat, runSub, breakBeat, breakSub, sliderTo }) 根据你的机器编写标准的28秒故事,包含编号镜头和编辑字幕:

  1. 一句话概括整个需求(提示栏自动输入)。
  2. Claude构建机器(零件按装配顺序飞入,计数器攀升:“84/3,597个零件”)。
  3. 机器运转(光标拖动滑块;核心数值根据求解器攀升)。
  4. 剖切(截面、带实时数值的标签)。
  5. 分解(爆炸视图)。
  6. 破坏(光标点击破坏按钮;求解器决定失效方式)。

循环播放:最后一个相机关键帧回到第一个。如需自定义短片,使用 lab.film('name', { len, assemble, shots, events }):shots 是相机关键帧 { t, az, el, dist, target, fov },events 是事件 { t, beat: ['07', '粗体句。', '灰色句。'], 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文件路径、短片命令、求解器达到的工作点(与公开数据对比),以及你简化了哪些部分。提供下一台机器的构建选项。

相关技能