Skip to content

viewer.camera — CameraManager

设计意图

viewer.camera 是相机与导航域,它把「把什么放进视野」抽象成语义操作:fitView 按「显式包围盒 → 指定节点 → 当前选中集 → 整个模型」依次回落解析取景目标,集成方几乎不需要手算相机位姿;setStandardView 提供 7 个工程标准视图(Z-up / CATIA 约定)。鼠标 / 触控交互(旋转 / 平移 / 缩放)由引擎内置接管,API 层只补「程序化导航」与开关(setInteractionEnabled / setNavMode)。

另一个关键抽象是可序列化的位姿快照:getState() 返回 { position, target, up, fov } 纯数据,setState() 部分更新写回——视角书签、跨会话恢复、多视口同步都建立在这一对方法上。相机位姿的一切变化(交互或 API)统一经 camera-changed 事件对外广播。

何时用它:UI 上的「适配 / 标准视图 / 恢复视角」按钮、选中后聚焦、视角持久化与同步。取景目标的「范围」来自模型与选中集,本域只负责「怎么看过去」。

典型用法

工具条「聚焦」按钮(fitView 无参时自动回落:有选中框选中,无选中框整模型):

ts
focusBtn.onclick = () => viewer.camera.fitView();
// 批量出图前跳过动画
viewer.camera.fitView(undefined, { animate: false });

视角书签(快照可序列化,跨会话恢复):

ts
const bookmark = viewer.camera.getState(); // { position, target, up, fov }
localStorage.setItem("view-a", JSON.stringify(bookmark));
// 之后恢复:setState 只写传入字段,立即生效
viewer.camera.setState(JSON.parse(localStorage.getItem("view-a")!));

主从视口同步(camera-changed 驱动):

ts
main.on("camera-changed", (e) => {
  follower.camera.setState({ position: e.position, target: e.target, up: e.up });
});

注意事项

  • fitView 解析不出取景范围时静默返回(无模型且无显式 box),不抛错;取景保持当前视线方向,只调整距离与注视点。
  • setStandardView 在模型尚未取过景时是 no-op:它以最近一次取景范围为中心定距,加载后先 fitView() 一次再切标准视图。
  • camera-changed 交互期间约 30Hz 节流,payload 含 position / target / up(不含 fov);程序化 setState 也会触发。
  • setState 会取消进行中的相机动画(如 fitView 的取景过渡):程序化设位姿与用户交互同权,写入的位姿不会被下一帧动画覆盖。
  • setInteractionEnabled(false) 只关指针交互,API 控制(setState / fitView)不受影响。

完整签名与延伸