Files
Mujoco_WASM/plans/map-v3-design.md
T
chenlin a9b07e0abf
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
feat(web-platform): release V0.8.1 常规地图优化
2026-09-03 13:18:35 +08:00

8.3 KiB
Raw Blame History

MuJoCo Web 地图导入与编辑设计

状态:V1/V2 与 V3 地图编辑能力已实现。当前阶段只聚焦地图导入、可视化、受约束编辑、事务应用和地图包导出。

1. 目标

平台在不修改 @mujoco/mujoco WASM 内核的前提下,支持:

  1. 内置 MJCF 物理地图:平地、坡道、楼梯和随机障碍物。
  2. 工程地图包:map.json、简化 MJCF 碰撞层、可选自包含 GLB 视觉层和出生点。
  3. Schema V2 创作层:通过 map.scene.json 编辑受支持的静态原语。
  4. 将完全可识别的只读静态 MJCF 显式转换为可编辑副本。
  5. 在浏览器中事务式重新编译,并导出独立地图 ZIP。

当前阶段不扩展机器人运动控制或其他地图上层应用。

2. 坐标与分层

所有地图统一使用:

  • 米制;
  • Z-up
  • 右手坐标系;
  • +X 前方;
  • 物理层、视觉层、创作层和出生点共享世界原点。

地图拆分为三类资产:

  • physics/world.xmlMuJoCo 使用的简化静态碰撞层;
  • visuals/scene.glb:Three.js 使用的高精度视觉层;
  • authoring/map.scene.json:编辑器的规范源。

高面数视觉模型不得直接作为大型地图碰撞网格。

3. 地图包结构

maps/warehouse/
├── map.json
├── physics/
│   ├── world.xml
│   └── meshes/*.obj
├── visuals/
│   └── scene.glb
└── authoring/
    └── map.scene.json

Schema V1 支持物理层、视觉层和出生点。Schema V2 增加创作层:

{
  "schemaVersion": 2,
  "id": "warehouse",
  "name": "仓库",
  "coordinateSystem": { "units": "m", "up": "Z", "forward": "+X" },
  "physics": { "source": "physics/world.xml" },
  "visual": { "source": "visuals/scene.glb" },
  "authoring": { "source": "authoring/map.scene.json" },
  "spawnPoints": [
    { "id": "main", "name": "主入口", "position": [0, 0, 0.35], "yawDeg": 0 }
  ]
}

声明 authoring.source 时必须同时声明 physics.source

4. 安全导入

所有地图文件必须进入 ProjectManifestMemfsWorkspace,禁止运行时直接读取任意主机路径。

资源引用必须拒绝:

  • HTTP/HTTPS 和其他协议;
  • 绝对路径、UNC、盘符路径;
  • NUL、编码绕过和路径穿越;
  • 不存在的工程资源;
  • 重复路径及超出导入配额的文件。

视觉层仅支持自包含 GLB 2.0。暂不支持外部 glTF 依赖、Draco、KTX2 或视觉层隐藏坐标修正。

5. 物理地图约束

工程物理层只允许静态 worldbody 和必要的基础 asset。拒绝:

  • joint 和动态 body
  • mocap
  • actuator、sensor、tendon、equality
  • include
  • default class
  • 依赖不兼容 compiler 角度语义的姿态;
  • 无法安全重写的资源路径。

地图碰撞 geom 使用 group="2",并通过稳定命名空间 __platform_map_<mapId>_... 与机器人隔离。

6. 创作文档

map.scene.json 是唯一编辑规范源,支持:

  • box
  • cylinder
  • capsule
  • ramp
  • stairs
  • 出生点。

每个对象包含稳定 ID、名称、类型、世界位姿、原语参数、摩擦、颜色和启用状态。对象不超过 2,000 个,出生点不超过 500 个,生成 geom 不超过 10,000 个。

MapDocumentCompiler 根据创作文档确定性生成 physics/world.xml。生成结果只使用 quaternion,不依赖 Euler 角。

7. 编辑交互

地图面板提供统一的“场景 · 资产库”,工程地图源、认证资产和系统程序地形都遵循同一条交互链路:点击或拖放到画布、进入轻量草稿、在场景树选择/删除,最后一次应用。三类卡片共享一种受校验的拖放载荷,画布落点统一按 0.1 m 归一化,任何一种来源的增删都不会隐式触发 MuJoCo 编译。

地图源与场景实例分离。同一工程地图源可创建多个拥有独立 XY/绕 Z 位姿的引用实例;物理层、视觉层和出生点使用同一个实例变换。编辑 authoring 内容属于源编辑,会同步影响引用该 descriptor 的实例,界面必须明确提示这一影响范围,不能伪装成实例级覆盖。

当前没有可编辑地图时,首个认证资产会创建临时 map.json、空物理层和创作层骨架,切换到新场景并作为未应用草稿进入 Three.js 预览;此阶段不调用 MuJoCo。“放弃场景更改”必须同时撤销临时实例、创作草稿和这三份临时工程文件,下一次创建可以复用同一场景 ID。用户点击“应用并重新编译”后才生成并事务提交实际物理层。

React 中的 MapEditSession 是草稿唯一来源。Three.js 预览层只负责:

  • 草稿原语显示;
  • 射线拾取和高亮;
  • 世界坐标平移;
  • 绕世界 Z 轴旋转;
  • 原语尺寸缩放;
  • 出生点预览;
  • 操纵器和临时资源生命周期。

交互规则:

  • W:移动;
  • E:旋转;
  • S:缩放;
  • Delete/Backspace:删除;
  • Escape:取消选择;
  • Ctrl+Z:撤销;
  • Ctrl+YCtrl+Shift+Z:重做。

拖动 TransformControls 操纵轴期间禁用 OrbitControls;在画布空白区域按住鼠标左键仍可旋转相机。连续拖动只在 mouseUp 时提交一次历史记录。缩放必须写回原语参数,不能把 Three.js 节点 scale 作为持久数据。locked 的准确语义是“锁定位姿”:禁止位置、旋转和视口变换,但仍允许编辑名称、尺寸、摩擦和颜色。

“自动落位(重力)”通过统一地图表面查询器沿世界 -Z 求最高承载面。查询器与物理合成共用确定性程序几何,支持有限平地、坡道、楼梯、障碍物、坑/沟壑和高度场,并应用地图实例变换;因此认证资产可正确落到系统程序地形上,而不是始终假设 z=0

8. 只读地图转换

外部 MJCF 默认只读。只有完全可逆的静态原语地图可显式创建可编辑副本。

允许转换:

  • box
  • cylinder
  • capsule
  • 由嵌套静态 body 组成的世界位姿;
  • pos、quat、size、friction、rgba 和出生点。

遇到下列内容必须整体拒绝,禁止静默丢弃:

  • plane、mesh、heightfield
  • asset、材质和碰撞过滤扩展;
  • joint、site、light 或其他未知结构;
  • euler、axisangle、xyaxes、zaxis、fromto
  • 不能确认无损的 compiler 配置。

9. 事务边界

地图实例增删、工程地图实例变换、程序地图参数和认证资产源编辑共享同一个应用基线。普通模型入口切换或 URDF 模式重载只能使用上一次成功应用的地图基线,不能静默提交当前场景草稿。应用编辑草稿或转换地图时,顺序固定为:

  1. 生成候选创作层;
  2. 确定性生成候选物理层;
  3. 创建候选 manifest
  4. 在新的 MEMFS 工作区编译 MuJoCo
  5. Viewer 成功 attach 新会话;
  6. 最后提交 manifest、地图选择和编辑状态;
  7. 推进地图实例与创作文档的统一应用基线;
  8. 释放旧会话和旧工作区。

任一步失败都必须恢复旧仿真和旧工程状态,同时保留完整用户草稿。编译期间禁用所有草稿写入口;提交完成时只清除本次提交的文档版本,不能丢掉晚到修改。系统程序地形会替换无限地面 plane,避免其填平沟壑、深坑和高度场负高度。

10. 导出

浏览器导入文件不保证可写,因此不直接覆盖源目录。地图通过 ZIP 导出,包含:

  • map.json
  • 物理层及其显式 asset
  • 可选视觉层;
  • 可选创作层。

ZIP 内路径保持工程相对结构,并继续执行路径安全校验。

11. 验证重点

  • Schema V1/V2 兼容性;
  • 路径穿越和协议绕过拒绝;
  • 地图物理合成和命名空间隔离;
  • GLB 自包含校验及资源释放;
  • 编辑文档严格校验;
  • 确定性 MJCF 输出;
  • Undo/Redo 和视口变换写回;
  • 只读转换的白名单与整体拒绝;
  • 编译或 Viewer attach 失败后的事务回滚;
  • 地图 ZIP 资产完整性;
  • 三类地图来源的统一拖放、场景树和单次提交边界;
  • 普通模型重载不提交场景草稿,应用失败后草稿仍可放弃或重试;
  • 工程地图实例物理/视觉/出生点变换一致;
  • 首个认证资产临时场景的完整放弃;
  • 认证资产在程序地形上的重力落位,以及坑洞不被无限平面填平。