Anatomy Three.js — 交互式 3D 技术图形
使用 Three.js + GLSL 构建交互式等轴测 3D 技术插图。每个图形都将技术概念解释为可放置在桌面上的物理台式仪器或剖切测试装置:厚重的倒角底板、转制的支脚、符合领域逻辑的外壳和连杆、核心的内部转子或运动主体、可直接拖拽的 3D 控件和专门为该机器构建的仪器,以及严格限制在机器内部物理介质(火焰、等离子体、流体、下洗流、光束)中的自定义 GLSL 着色器。
无需编写 1500 行的单一 HTML 文件并在脑海中猜测 3D 坐标,而是首先与用户对齐装置和交互方式(第 0 阶段),然后在 figures/<slug>/ 目录下,在不可变的 kit/ 引擎支持下,通过六个独立阶段构建每个图形,并在每一步通过双层3D 空间 + 正交视觉验证平台进行验证。
目录结构
anatomy-threejs/
├── SKILL.md # 第 0 阶段简报 + 6 阶段工作流 & 代理入口
├── kit/ # 不可变引擎 — 从此处导入;切勿为每个图形编辑
│ ├── shaders.mjs # 5 种主题、4 色调 + 顶盖 cel 着色器、倒置外壳、折痕
│ ├── primitives.mjs # 轴感知的板、圆柱体、齿轮、螺丝、滚花、刻度
│ ├── registry.mjs # Recorder3D: .group(), .part(), .anchor(), .tube(), .interactable(), .tag()
│ ├── audit3d.mjs # 无头 Node 3D 空间审计(碰撞、漂浮、孔洞、管道)
│ ├── runtime.mjs # 正交相机系统、射线投射 3D 拖拽、自定义控件、弹簧、__ANATOMY_DEBUG__
│ ├── bundle.mjs # 将图形模块编译成单个自包含的 HTML 文件
│ └── shell.html # 响应式卡片框架、5 种主题 CSS 变量、功能感知控件
├── scripts/
│ ├── inspect.mjs # 无头 Chrome (CDP) 2x2 正交蓝图 & 关节叠加
│ ├── drive.mjs # 交互式联系表 + 主角静态图 + 移动端 390px 验证
│ └── chrome-port.mjs # 零依赖 WebSocket + PNG 拼接器,用于无头 Chrome
├── references/
│ ├── craft-3d.md # 3D 坐标系、色调层次、特制控件、反模式
│ ├── kit-3d.md # Recorder3D、图元、着色器和运行时的 API 参考
│ └── verify-3d.md # 如何解释和修复 [COLLISION]、[FLOATING]、[TUBE KINK] 和正交视图
└── figures/
└── <slug>/ # 你的图形工作区(例如 figures/wankel-engine/)
├── model.mjs # 第 1 阶段:纯数学、尺寸、SPEC.features、SPEC.controls、锚点
├── base.mjs # 第 2 阶段:底板、支脚、光环、标尺、黄铜铭牌
├── structure.mjs # 第 3 阶段:底座、框架/外壳、端口、紧固件
├── subject.mjs # 第 4 阶段:运动核心组件(转子、叶片、密封件、齿轮)
├── mechanism.mjs # 第 5 阶段:特制控件、仪器、3D 可交互对象、管道、updateKinematics()
├── shader.mjs # 第 6 阶段:局限于活动物理介质的自定义 GLSL 着色器
├── build.mjs # CLI 入口:--test-model、--audit 和完整 HTML 打包
└── dist/
└── <slug>.html # 编译后的自包含交互式图形
规则 1 — 切勿重写
kit/:Three.js 相机、cel 着色器、射线拖拽处理程序、弹簧求解器、DOM 框架和调试工具都位于kit/中。你的图形文件仅定义领域数学、3D 零件、运动学、可交互对象和自定义介质着色器。规则 2 — 在编写几何体之前阅读参考文档:
- 在第 0/1 阶段之前阅读
references/craft-3d.md,以设计物理装置、特制控件、功能标志、色调层次和 3D 坐标框架。- 在第 2 阶段之前阅读
references/kit-3d.md,了解Recorder3D和kit/primitives.mjs的精确签名。- 当
--audit、inspect.mjs或drive.mjs报告问题时,阅读references/verify-3d.md。
第 0 阶段 — 装置与交互简报(构建前对齐)
在创建文件或编写第 1 阶段代码之前,向用户提出一个简明的装置与交互简报,并就机器的作用以及读者如何与其交互达成一致(仅当用户明确指示立即构建而不提问时,才可跳过等待):
- 台式装置与主角主题:命名物理机制以及承载
lit强调色的单一组件。 - 直接 3D 操控(
reg.interactable):确定读者可以在视口中抓取并直接拖拽的 3D 组件或控件(例如,拖拽斜盘以使其倾斜/升降并观察旋翼叶片变距,滑动游标滑架,拉动连杆杠杆),包括在旋转/模拟暂停时。 - 领域真实控件与遥测(
SPEC.controls):选择属于此机器的台面硬件和控件条滑块(例如,2 轴循环操纵杆、总距杆象限仪、量角器弧、千分尺鼓轮、游标尺、压力计管)。切勿复制其他图形的旋转旋钮、波尔登管压力计或液压箱,除非主题确实使用该精确仪器。 - 视图模式(
SPEC.features):明确决定哪些可选模式值得包含:explode:仅对具有堆叠轴向层的封闭同心机器(例如,发动机、变速箱、泵)启用(true)。对于开放式机械连杆、斜盘、光学平台或分离零件会破坏连杆几何体并增加杂乱的外露装置,设置explode: false。cutaway:当外壳隐藏内部运动部件时启用(true);对于开放式框架机构设置为false。shader:当受限的物理介质(燃烧气体、转子尾流、光束、流体流动)能阐明机制时启用(true)。
第 0 阶段关口:用户确认或完善简报(或明确指示立即进行非交互式构建)。
六阶段工作流
依序执行这些阶段。每个阶段以验证关口结束 — 运行命令,修复任何错误,并在进入下一阶段前使用文件阅读工具目视检查渲染的 PNG。
第 1 阶段 — 模型与运动学(model.mjs + build.mjs)
在接触 Three.js 之前,将商定的简报转化为纯物理数学模块:
- 在
figures/<slug>/model.mjs中编码物理隐喻:SPEC.features:{ explode: boolean, cutaway: boolean, shader: boolean, crank: boolean }匹配第 0 阶段。SPEC.interactionHint:显示在左下角的简短提示,告知用户他们可以直接拖拽哪些 3D 零件(例如,"拖拽斜盘、操纵杆或总距杆")。SPEC.controls:特定领域滑块控件的数组({ id, label, min, max, step, initial, title })。runtime.mjs将这些渲染在控件栏中,用弹簧进行平滑处理,并传递给updateKinematics和formatReadout。SPEC.auditPoses和SPEC.drivePoses:领域代表性姿态(极端控制角度、暂停操控、剖切/主题检查),由--audit和scripts/drive.mjs使用。当features.explode === false时,省略分解姿态。SPEC:所有关键尺寸(BASE_W、BASE_D、BASE_H、BASE_Y、topSurfaceY、isoElevDeg: 30、isoAzimDeg: -36、initialZoom、initialPanY、minVertSpan、minHorizSpan)。ANCHORS:底板上的命名[x, y, z]安装坐标(plaqueCenter、rulerCenter,以及你图形的特制控件/仪器锚点)。记住,在标准等轴测视图(30° 仰角, -36° 方位角)中,+Z边是前面板,-X, +Z/+X, +Z是未遮挡的前角。- 纯状态和运动学函数(零 Three.js 导入),由
theta和来自SPEC.controls的实时params驱动。 formatReadout({ theta, effectiveRpm, params })返回用于遥测栏的{ readout, phase }字符串。
- 搭建
figures/<slug>/build.mjs(参考figures/wankel-engine/build.mjs或figures/helicopter-swashplate/build.mjs)并调整标题、副标题、初始读数和图例。
第 1 阶段关口:
node figures/<slug>/build.mjs --test-model
通过标准:退出码为 0,所有锚点均为有限值,且在完整的 $0 \dots 6\pi$ 周期内验证了读数和状态。
第 2 阶段 — 基底(base.mjs)
构建接地整个仪器的重型基准底板:
- 创建
base.group(stage: "base")。 - 在
BASE_Y - 0.24处添加软地面阴影(makeHaloMesh)。 - 使用
buildSlabGeometry(BASE_W, BASE_D, BASE_H, { radius: 0.26, bevel: true, bevelSize: 0.025, bevelThickness: 0.025 })添加base.plate,参数为ramp: "lo"、mountOn: "ground"。注意,topSurfaceY = BASE_Y + BASE_H + 0.025考虑了顶部倒角厚度,因此安装在topSurfaceY的零件能平放在顶面上而不下沉。 - 通过
reg.anchor(id, x, y, z, baseGroup)注册所有底板安装锚点,以便第 3 和第 5 阶段直接卡入base.plate。 - 添加嵌入式周边凹槽(
makePlanOutline)、4 个转制角腿(base.foot.collar.i+base.foot.pad.i)并带顶部沉头螺钉(makeScrewDetail)、一个刻度标尺(base.ruler+makeRulerTicks),以及在可见前面板(+Z)上添加一个铆接的brass规格铭牌(base.plaque),并带有一个雕刻标签(reg.tag("tag-plate", ...))。
第 2 阶段关口:
node figures/<slug>/build.mjs --audit
node scripts/inspect.mjs figures/<slug>/dist/<slug>.html --isolate base --ortho --out figures/<slug>/dist/inspect-base.png
阅读 inspect-base.png,验证支脚干净地位于底板下方,且黄铜铭牌和标尺在前面板上未被遮挡。
第 3 阶段 — 结构(structure.mjs)
构建静止的承重支架、主框架或剖切外壳、端口/歧管和紧固件:
- 在
base.plate上安装支撑底座或变速箱,带法兰底座、螺栓细节、锥形柱和轴承鞍座。 - 构建主外壳或框架(
ramp: "mid"、outline: "hi")。保持前部(+Z)开放或安装剖切盖(cutawayHide: true),以便在启用features.cutaway时,内部机构从标准等轴测相机角度保持完全可见。 - 添加领域真实的端口、执行器外壳或指向外部的静止支架。在每个局部子组内,使用其局部向外端口法线注册 3D 端口/端子锚点(
reg.anchor("plug.leading.tip", 0, 0.68, 0, spGroup, { dir: [0, 1, 0] })),以便第 5 阶段的管道卡入其精确的世界位置并同轴地进入/退出。 - 仅在
SPEC.features.explode为true且装置具有旨在沿轴向分离的封闭同心层时,在可移除子组上设置explode: [ex, ey, ez]向量。
第 3 阶段关口:
node figures/<slug>/build.mjs --audit
node scripts/inspect.mjs figures/<slug>/dist/<slug>.html --isolate base,structure --ortho --out figures/<slug>/dist/inspect-structure.png
阅读 inspect-structure.png(俯视图、前视图、右视图、标准等轴测视图):验证端口指向外部,底座同时接触底板和外壳且无裁剪,并且没有漂浮物。
第 4 阶段 — 主体(subject.mjs)
构建主导视觉焦点的主角内部组件:
- 为主要运动体(例如,转子体、桨毂轭架)分配
ramp: "hi",为活动工作元件(rotor.apexSeal.i、blade.airfoil.*)分配ramp: "lit",为精密齿轮和枢轴分配ramp: "brass"。 - 创建嵌套运动学组(
orbit -> spin,或azimuth -> flap -> pitch),以便层次运动干净地合成,而不会出现欧拉万向节锁。 - 在孔内运动的零件上传递
insideBoreOf和boreClearanceFn,以便audit3d.mjs在每个审计姿态下数学验证零壁穿透。 - 添加机械加工的凹槽、面槽、翼梁接缝或螺栓图案,使运动一目了然。
第 4 阶段关口:
node figures/<slug>/build.mjs --audit
node scripts/inspect.mjs figures/<slug>/dist/<slug>.html --isolate subject --ortho --out figures/<slug>/dist/inspect-subject.png
阅读 inspect-subject.png,确认主体的轮廓、倒角和接头从每个角度都清晰可辨。
第 5 阶段 — 机构、特制控件与直接 3D 交互(mechanism.mjs)
将主体连接到领域真实的操作员控件、遥测仪器、直接 3D 拖拽交互和管线:
- 在第 0/1 阶段的
ANCHORS处构建领域真实的控件(例如,2 轴万向节循环操纵杆、带槽口的总距杆象限仪、游标丝杠或滚花油门鼓)。切勿在机器需要自己的控制硬件时复制其他图形的滚花旋钮或歧管块。 - 构建领域真实的遥测设备(例如,弯曲的叶片变距量角器弧、线性行程标尺、压力计柱或表盘式指示器),放置于
+Z方向的前方,或位于标准等轴测视图主体轮廓之外的空旷处。 - 使用
reg.interactable(targetId, { cursor, hint, onDrag })在主机构和/或物理杠杆上注册直接 3D 操控,以便用户即使在旋转暂停时(RPM = 0或PAUSED)也能通过setParam(...)在视口中直接拖拽 3D 零件。 - 使用
reg.tube(id, fromAnchorId, waypoints, toAnchorId, opts)布线所有管道和电缆:- 查询
reg.getAnchorWorldPos(anchorId)和reg.getAnchorWorldDir(anchorId)以构建平滑的 3D 拱形航点(length / chord >= 1.12),使其远离相邻零件并沿每个端口的向外法线同轴进入。
- 查询
- 构建传动系和铰接连杆。在隐藏内部机构的正面外壳或护罩上传递
cutawayHide: true
…
[为翻译而截断]