# AGV 数字孪生 GLB 导出规范 > **文档版本**:1.1 > **适用对象**:负责 AGV 三维建模与 GLB 导出的同事 > **对接系统**:Web 查看器(Three.js)、PanguCanvas 桌面播放器 > **交付范围**:仅需交付 GLB 模型文件;JSON 配置由程序同事在收到 GLB 后生成与维护 --- ## 1. 背景与目标 我们使用 **GLB 模型** 驱动 AGV 数字孪生(轮子旋转/转向、举升、灯光、动作切换等);配套的 JSON 配置由程序侧根据 GLB 自动生成,**无需建模同事参与**。 当前部分模型在导出时未统一层级与坐标,导致程序在运行时不得不: - 猜测轮子旋转轴与轴心位置 - 动态插入临时空节点 - 做复杂的世界坐标 ↔ 本地坐标换算 - 兼容混乱的节点命名(中文、`.001` 后缀、空格等) **本规范的目标**:把几何与运动语义在 Blender 导出阶段写进 GLB,程序侧只做「查节点 + 改 transform / 材质」,降低联调成本、减少 bug。 --- ## 2. 交付物清单 每款 AGV **只需交付一个文件**: | 文件 | 说明 | |------|------| | `{车型名}.glb` | 按本规范导出的模型 | 可选(联调时有助于排查问题):Blender 源文件(`.blend`)、各可动件行程与轴方向的简要说明。 导出前请自检(见第 10 节)。收到 GLB 后,程序同事会负责生成配置、绑定动作并完成验证。 --- ## 3. 场景层级(必须遵守) 请在 Blender 中按以下结构组织,**导出前建好空物体(Empty)层级** ``` agv_root ← 唯一根节点(程序侧 root 固定为 "agv_root") ├── body/ ← 静态车体 │ └── chassis ├── wheels/ │ ├── wheel_fl/ ← 左前舵轮(命名按实际车型调整) │ │ ├── steer ← 转向节点:绕本地 Y 轴旋转 │ │ │ └── spin ← 滚转节点:绕本地 X 轴旋转 │ │ │ └── mesh ← 轮子网格 │ ├── wheel_fr/ │ └── ... ├── actuators/ │ └── lift_fork/ ← 举升机构:沿本地 Y 轴平移 │ └── mesh ├── lights/ ← 可选分组,非必须 │ ├── light_status_l/ │ └── light_status_r/ └── sensors/ └── lidar_top/ ``` ### 3.1 根节点 - **名称固定为 `agv_root`**(不要用 `lux_root`、`Scene`、`StealthAGV` 等) - 原点建议:车辆地面接触面几何中心,或后轴中心;**Y = 0 贴地** - 车头朝向建议统一为 **+Z**(见第 4 节) ### 3.2 轮子层级(最重要) 每个可动轮子必须包含三层空物体: | 节点 | 作用 | 程序操作 | |------|------|----------| | `wheel_xxx` | 轮子总成,固定在父级 | 程序按节点名绑定 | | `steer` | 转向 | `rotation.y`(或约定的转向轴) | | `spin` | 滚转 | `rotation.x`(所有轮子统一) | | `mesh` | 视觉网格 | 不直接改 transform | **所有轮子的滚转轴统一为 spin 节点的本地 X 轴,转向轴统一为 steer 节点的本地 Y 轴。** 麦轮、舵轮等特殊情况也用独立命名的 wheel 节点表达,不要在不同轮子上使用不同旋转轴约定。 ### 3.3 举升 / 执行机构 - 举升件放在 `actuators/` 下 - **收回位置 = 本地 Y = 0**(相对 actuators 父节点或 lift 节点自身约定) - **完全伸出位置 = 本地 Y = 行程米数**(如 0.15 m = 15 cm) - 行程以 **米** 为单位,与 Blender 中 1 单位 = 1 米 保持一致(程序侧会据此配置) ### 3.4 灯光 - 每个需独立控制的指示灯单独 **命名节点**(如 `light_status_l`),程序按节点名绑定 - 节点下可有 mesh,材质 **可与其他部件共用**;程序运行时会 clone,无需刻意拆材质 - 材质使用 PBR,支持 **Emission** 即可(亮灭由程序改 emissive 控制) - 不必强制放在 `lights/` 分组下,但名称建议带 `light_` 前缀便于识别 ### 3.5 静态件 - 不参与动作的零件合并进 `body/chassis`,减少零散节点 - 仅保留需要单独隐藏、透明或换色的零件为独立节点 --- ## 4. 坐标系与单位 | 项目 | 要求 | |------|------| | 坐标系 | **Y 轴向上**(glTF 标准),**右手系** | | 单位 | **1 Blender 单位 = 1 米** | | 朝向 | 车头 **+Z**,左右 **±X**,上下 **Y**(全项目统一) | | Transform | 导出前对每个可动节点 **Apply All Transforms**(Ctrl+A),scale 应为 `(1, 1, 1)` | | 全局旋转 | **不要在模型根节点上留 ±90° 的「纠正旋转」**;朝向在 Blender 里摆好再导出 | > 说明:若导出时未 Apply Transform 或 scale ≠ 1,程序侧举升、轮子会出现位移异常或「部件飞出视野」。 --- ## 5. 命名规范 ### 5.1 必须 - 仅使用 **ASCII 英文字母、数字、下划线** - 使用 **snake_case**:`wheel_fl`、`lift_fork`、`light_status_l` - 按角色加前缀: | 前缀 | 用途 | 示例 | |------|------|------| | `body_` / 放在 body/ 下 | 静态车体 | `body/chassis` | | `wheel_` | 轮子 | `wheel_fl`, `wheel_rl` | | `lift_` / 放在 actuators/ 下 | 举升 | `lift_fork` | | `light_` | 指示灯 | `light_status_l` | | `sensor_` | 传感器 | `sensor_lidar_top` | ### 5.2 禁止 - 中文节点名(如 `前座`、`雷达`、`柱体`) - Blender 自动后缀(如 `主体.001`、`平面.003`) - 空格、全角字符、不可见字符(含 NBSP) - 无语义的编号(如仅有 `light_1`、`light_2` 而不说明用途) - 多个不相关含义的节点重名 ### 5.3 推荐命名示例(舵轮 AGV) ``` agv_root body/chassis wheels/wheel_fl/steer/spin/mesh wheels/wheel_fr/steer/spin/mesh wheels/wheel_rl/spin/mesh ← 从动轮可无 steer 层,spin 下挂 mesh actuators/lift_fork/mesh lights/light_status_l lights/light_status_r sensors/lidar_top ``` --- ## 6. 材质要求 | 项目 | 要求 | |------|------| | 材质类型 | **PBR Principled BSDF** → 导出为 glTF Standard Material | | 车体 | 正常 albedo / roughness / metalness,贴图嵌入 GLB | | 指示灯 | PBR 材质,支持 Emission;可与车体共用材质 | | 材质实例 | 无特殊要求;程序侧会对需动画的部件 clone 材质 | | 法线 | 导出时包含 Normals;有贴图时包含 Tangents | --- ## 7. Blender 导出设置 **File → Export → glTF 2.0 (.glb/.gltf)** | 选项 | 设置 | |------|------| | Format | **glTF Binary (.glb)** | | Include | Selected Objects **关闭**(导出整场景) | | Transform | **+Y Up** | | Geometry | 勾选 Apply Modifiers、UVs、Normals;有 normal map 时勾选 Tangents | | Material | Export 开启 | | Compression | 开发联调阶段 **关闭 Draco**(上线可按体积需求再开) | | 层级 | **保持层级**,不要勾选 Flatten / 合并为单 mesh | 导出后请确认文件大小合理,并用 glTF 查看器预览,确认模型显示正常。 --- ## 8. 节点命名与程序侧映射(供参考,无需建模同事配置) 程序会根据 GLB 节点名自动绑定逻辑组件。**请按第 5 节规范命名**,便于程序识别;以下类型说明仅供理解命名意图,JSON 配置由程序同事完成。 ### 8.1 组件类型(程序侧配置) | type | 用途 | motion.role | |------|------|-------------| | `static` / `body` | 静态件 | 无 | | `wheel` | 轮子 | `wheel` | | `actuator` | 举升等 | `lift` | | `light` | 指示灯 | `light` | | `sensor` | 传感器(可选动画) | `lidar` / `camera` 等 | ### 8.2 命名与用途对照 | 节点示例 | 程序侧用途 | 建模侧要求 | |----------|------------|------------| | `wheel_fl` | 轮子旋转/转向 | 含 `steer` → `spin` → `mesh` 层级 | | `lift_fork` | 举升平移 | 收回 Y=0,伸出 Y=行程(米) | | `light_status_l` | 指示灯 emissive | 单独命名节点,材质支持 Emission | | `body/chassis` | 静态车体 | 不参与 transform 动画 | --- ## 9. 常见问题对照(旧模型 vs 规范) 以现有「英招」模型为例,以下做法请避免: | 现状问题 | 规范做法 | |----------|----------| | 根节点名 `lux_root` | 改为 `agv_root` | | 节点 `柱体.003`、`主体.001` | 语义命名如 `wheel_rl` | | 同车型轮子 axis 有的 y、有的 z | 统一预置 spin/steer,axis 统一 x/y | | 6 个 light 节点对应 3 盏灯 | 合并为 3 个 `light_*` 节点 | | 19 个零散 static 组件 | 合并 body,仅保留可动件独立节点 | | 举升行程不清晰或为负值 | 在 Blender 摆好 0 ~ 行程(米),并附简要说明 | --- ## 10. 导出前自检清单 请在交付前逐项确认: - [ ] 根节点名为 `agv_root`,Y=0 贴地,车头朝 +Z - [ ] 所有可动节点已 **Apply All Transforms**,scale = (1,1,1) - [ ] 每个舵轮含 `steer` → `spin` → `mesh` 层级 - [ ] 所有轮子滚转轴为 spin 的 **本地 X**,转向轴为 steer 的 **本地 Y** - [ ] 举升行程在 Blender 中以米制摆好(如收回 0 m、伸出 0.15 m) - [ ] 节点名全部为 ASCII snake_case,无中文、无 `.001` 后缀 - [ ] 需独立控制的指示灯有单独命名节点(`light_*`) - [ ] 静态件已合并到 body,无多余零散 mesh - [ ] glTF 导出:+Y Up、保留层级、Apply Modifiers - [ ] 用任意 glTF 查看器预览 GLB,确认无错位、无缩放异常 --- ## 11. 联调流程 **建模同事:** 1. 按本规范完成 Blender 场景 2. 导出 `{车型名}.glb` 并交付给程序同事 3. (建议)一并提供 `.blend` 源文件及可动件行程说明 **程序同事(建模同事无需参与):** 1. 将 GLB 放入项目 `agv/` 目录 2. 生成 JSON 配置、绑定动作并在查看器 / PanguCanvas 中验证 如有疑问,请提供:**Blender 源文件 + GLB + 各可动件行程与轴方向说明**,便于对照排查。 --- ## 12. 附录:层级示意图 ``` agv_root (原点贴地, 车头 +Z) │ ┌─────────────────┼─────────────────┐ │ │ │ body/ wheels/ actuators/ │ │ │ chassis wheel_fl lift_fork │ │ steer ── spin mesh │ │ spin mesh │ mesh ``` --- *文档维护:数字孪生开发组 · 如有规范变更请同步更新本文档版本号*