# 漫游功能 API 对接工作计划 ## Context ### Original Request 继续漫游功能的接口对接,将 SDK UI 组件的回调对接到底层 3D 引擎 API。 ### 前置工作(已完成) - 剖切盒 (Section Box) 接口对接 ✅ - Toolbar 按钮调用链文档创建 ✅ ### 底层 API 分析 #### controlModule 方法 > 文件位置: `bim_engine_base/src/core/v2/modules/controlModule.ts` | 方法 | 签名 | 说明 | |------|------|------| | `switchFirstPersonMode()` | `public switchFirstPersonMode(): void` | 切换到第一人称漫游模式,禁用轨道控制器 | | `switchDefaultMode()` | `public switchDefaultMode(): void` | 切换回默认轨道控制模式 | #### firstPersonControls 属性 > 文件位置: `bim_engine_base/src/core/v2/controls/firstPersonCameraControl.js` | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `applyGravity` | `boolean` | `false` | 重力开关 | | `applyCollision` | `boolean` | `true` | 碰撞检测开关 | | `moveSpeed` | `number` | `0.02` | 移动速度 | | `lookSpeed` | `number` | `0.008` | 视角转动速度 | | `playerHeight` | `number` | `1.4` | 玩家身高 | | `maxRotateX` | `number` | `0.8` | 相机翻转最大限度 | | `g` | `number` | `9.8` | 重力加速度 | | `positionEasing` | `boolean` | `true` | 位置缓动 | | `gravityMinHeight` | `boolean` | `true` | 重力最低点限制 | --- ### UI 回调对接分析 #### V2 底层能力说明 > **重要**: V2 版本的 `controlModule.ts` 使用简化版 `firstPersonCameraControl.js`, > 而非旧版 `FirstPersonControls_.js`(包含人物模型、小地图等完整功能)。 > > **因此 V2 仅支持第一人称漫游的基本功能,不支持第三人称漫游、人物模型等高级功能。** #### 本次对接范围 | UI 回调 | 对应功能 | 底层 API | 对接状态 | |---------|---------|---------|----------| | `onWalkModeToggle` | **第一人称漫游** | ✅ `switchFirstPersonMode()` | ✅ **本次对接** | | `onSpeedChange` | **移动速度** | ✅ `moveSpeed` | ✅ **本次对接** | | `onGravityToggle` | **重力** | ✅ `applyGravity` | ✅ **本次对接** | | `onCollisionToggle` | **碰撞** | ✅ `applyCollision` | ✅ **本次对接** | #### 暂不接入 (保持现状) | UI 回调 | 对应功能 | 原因 | |---------|---------|------| | `onPlanViewToggle` | 地图 | 底层无 API,保持现有 UI 控制 | | `onPathModeToggle` | 路径漫游 | 底层无 API,保持现有 UI 控制 | | `onWalkModeChange` | 行走/跑步模式 | 第三人称功能,暂不接入 | | `onCharacterModelChange` | 人物模型 | 第三人称功能,暂不接入 | | `onExit` | 退出 | 已实现,无需修改 | #### 本次对接的 4 个功能调用链 > 标注说明: `[SDK]` = SDK 层代码, `[底层]` = bim_engine_base 底层引擎 **1. 第一人称漫游模式开关 (`onWalkModeToggle`)** ``` 用户点击「漫游」按钮 → [SDK] WalkControlPanel.onWalkModeToggle(isActive) → [SDK] WalkControlManager.onWalkModeToggle → [SDK] EngineManager.activateFirstPersonMode() / deactivateFirstPersonMode() → [SDK] Engine.activateFirstPersonMode() / deactivateFirstPersonMode() → [底层] engine.controlModule.switchFirstPersonMode() / switchDefaultMode() ``` **2. 速度调节 (`onSpeedChange`)** ``` 用户点击「+/-」速度按钮 (UI: 1-10) → [SDK] WalkControlPanel.onSpeedChange(speed) → [SDK] WalkControlManager.onSpeedChange → [SDK] EngineManager.setWalkSpeed(speed * 0.01) // 值转换: UI 1-10 → 引擎 0.01-0.1 → [SDK] Engine.setWalkSpeed(speed) → [底层] engine.controlModule.firstPersonControls.moveSpeed = speed ``` **3. 重力开关 (`onGravityToggle`)** ``` 用户点击「重力」复选框 → [SDK] WalkControlPanel.onGravityToggle(enabled) → [SDK] WalkControlManager.onGravityToggle → [SDK] EngineManager.setWalkGravity(enabled) → [SDK] Engine.setWalkGravity(enabled) → [底层] engine.controlModule.firstPersonControls.applyGravity = enabled ``` **4. 碰撞检测开关 (`onCollisionToggle`)** ``` 用户点击「碰撞」复选框 → [SDK] WalkControlPanel.onCollisionToggle(enabled) → [SDK] WalkControlManager.onCollisionToggle → [SDK] EngineManager.setWalkCollision(enabled) → [SDK] Engine.setWalkCollision(enabled) → [底层] engine.controlModule.firstPersonControls.applyCollision = enabled ``` --- #### 暂不接入的功能 (保持现状) | 功能 | 说明 | |------|------| | 地图/平面图 | 底层无 API,保持现有 SDK 层 UI 控制 | | 路径漫游 | 底层无 API,保持现有 SDK 层 UI 控制 | | 行走/跑步模式 | 第三人称功能,暂不接入 | | 角色模型切换 | 第三人称功能,暂不接入 | --- ## Work Objectives ### Core Objective 将漫游控制面板的 UI 回调对接到底层 3D 引擎的第一人称控制器 API。 ### Concrete Deliverables - `engine/src/components/engine/index.ts` - 新增 5 个漫游相关方法 - `engine/src/managers/engine-manager.ts` - 暴露漫游方法到管理器 - `engine/src/managers/walk-control-manager.ts` - 修改回调对接实际 API - `.sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md` - 更新漫游部分文档 ### Definition of Done - [x] `bun run build` 构建成功 - [x] 第一人称漫游模式开关可正常切换 - [x] 速度调节可正常控制 - [x] 重力开关可正常控制 - [x] 碰撞开关可正常控制 - [x] 调用链文档已更新 ### Must Have - 第一人称漫游模式开关(switchFirstPersonMode / switchDefaultMode) - 移动速度调节(moveSpeed) - 重力开关(applyGravity) - 碰撞检测开关(applyCollision) - 所有注释使用中文 ### Must NOT Have (Guardrails) - 不要实现第三人称漫游相关功能(角色模型、行走/跑步模式) - 不要修改底层引擎代码(只修改 SDK 层) - 不要添加新的 npm 依赖 - 不要修改 onPlanViewToggle/onPathModeToggle/onWalkModeChange/onCharacterModelChange --- ## Verification Strategy ### Test Decision - **Infrastructure exists**: NO(无自动化测试) - **User wants tests**: Manual-only - **Framework**: none ### Manual QA 每个 TODO 完成后,需要手动验证: 1. 运行 `bun run build` 确保无编译错误 2. 在 playground 中测试功能 --- ## Task Flow ``` Task 1 (Engine 新增方法) ↓ Task 2 (EngineManager 暴露方法) ↓ Task 3 (WalkControlManager 对接回调) ↓ Task 4 (更新文档) ↓ Task 5 (构建验证) ``` ## Parallelization | Task | Depends On | Reason | |------|------------|--------| | 2 | 1 | EngineManager 需要调用 Engine 的方法 | | 3 | 2 | WalkControlManager 需要调用 EngineManager 的方法 | | 4 | 3 | 文档需要反映最终实现 | | 5 | 1,2,3 | 构建验证需要所有代码完成 | --- ## TODOs - [x] 1. 在 Engine 组件中新增漫游相关方法 **What to do**: 在 `engine/src/components/engine/index.ts` 中的剖切盒功能区块后添加: ```typescript // ==================== 漫游功能 ==================== /** 漫游模式是否激活 */ private isWalkModeActive: boolean = false; /** * 激活第一人称漫游模式 * @remarks 切换到第一人称控制器,禁用轨道控制器 */ public activateFirstPersonMode(): void { if (!this._isInitialized || !this.engine) { console.error('[Engine] Cannot activate first person mode: engine not initialized.'); return; } if (!this.engine.controlModule) { console.error('[Engine] Control module not available.'); return; } if (this.isWalkModeActive) { console.log('[Engine] First person mode already active, skipping.'); return; } console.log('[Engine] Activating first person mode'); this.engine.controlModule.switchFirstPersonMode(); this.isWalkModeActive = true; } /** * 停用第一人称漫游模式 * @remarks 切换回轨道控制器 */ public deactivateFirstPersonMode(): void { if (!this._isInitialized || !this.engine?.controlModule) { return; } if (!this.isWalkModeActive) { return; } console.log('[Engine] Deactivating first person mode'); this.engine.controlModule.switchDefaultMode(); this.isWalkModeActive = false; } /** * 设置漫游移动速度 * @param speed 移动速度(默认 0.02) */ public setWalkSpeed(speed: number): void { if (!this._isInitialized || !this.engine?.controlModule?.firstPersonControls) { console.error('[Engine] Cannot set walk speed: engine not initialized.'); return; } console.log('[Engine] Setting walk speed:', speed); this.engine.controlModule.firstPersonControls.moveSpeed = speed; } /** * 设置漫游重力开关 * @param enabled 是否启用重力 */ public setWalkGravity(enabled: boolean): void { if (!this._isInitialized || !this.engine?.controlModule?.firstPersonControls) { console.error('[Engine] Cannot set walk gravity: engine not initialized.'); return; } console.log('[Engine] Setting walk gravity:', enabled); this.engine.controlModule.firstPersonControls.applyGravity = enabled; } /** * 设置漫游碰撞检测开关 * @param enabled 是否启用碰撞检测 */ public setWalkCollision(enabled: boolean): void { if (!this._isInitialized || !this.engine?.controlModule?.firstPersonControls) { console.error('[Engine] Cannot set walk collision: engine not initialized.'); return; } console.log('[Engine] Setting walk collision:', enabled); this.engine.controlModule.firstPersonControls.applyCollision = enabled; } /** * 获取漫游模式是否激活 * @returns 是否处于漫游模式 */ public isFirstPersonModeActive(): boolean { return this.isWalkModeActive; } // ==================== 结束:漫游功能 ==================== ``` **Must NOT do**: - 不要修改其他功能区块的代码 - 不要添加角色模型相关的方法 **Parallelizable**: NO (其他任务依赖此任务) **References**: - `engine/src/components/engine/index.ts:508-583` - 剖切盒功能区块(作为插入位置参考) - `bim_engine_base/src/core/v2/modules/controlModule.ts:62-84` - 底层 switchFirstPersonMode/switchDefaultMode 方法 - `bim_engine_base/src/core/v2/controls/firstPersonCameraControl.js:24-30` - 底层 firstPersonControls 属性 **Acceptance Criteria**: - [x] 新增 `isWalkModeActive` 私有属性 - [x] 新增 `activateFirstPersonMode()` 方法 - [x] 新增 `deactivateFirstPersonMode()` 方法 - [x] 新增 `setWalkSpeed(speed: number)` 方法 - [x] 新增 `setWalkGravity(enabled: boolean)` 方法 - [x] 新增 `setWalkCollision(enabled: boolean)` 方法 - [x] 新增 `isFirstPersonModeActive()` 方法 - [x] 所有方法注释使用中文 **Commit**: YES - Message: `feat(engine): 新增漫游功能方法` - Files: `src/components/engine/index.ts` --- - [x] 2. 在 EngineManager 中暴露漫游方法 **What to do**: 在 `engine/src/managers/engine-manager.ts` 中的 `activateZoomBox` 方法后添加: ```typescript // ==================== 漫游功能 ==================== /** 激活第一人称漫游模式 */ public activateFirstPersonMode(): void { if (!this.engineInstance) { console.warn('[EngineManager] 3D Engine not initialized.'); return; } this.engineInstance.activateFirstPersonMode(); } /** 停用第一人称漫游模式 */ public deactivateFirstPersonMode(): void { if (!this.engineInstance) { return; } this.engineInstance.deactivateFirstPersonMode(); } /** * 设置漫游移动速度 * @param speed 移动速度 */ public setWalkSpeed(speed: number): void { if (!this.engineInstance) { console.warn('[EngineManager] 3D Engine not initialized.'); return; } this.engineInstance.setWalkSpeed(speed); } /** * 设置漫游重力开关 * @param enabled 是否启用重力 */ public setWalkGravity(enabled: boolean): void { if (!this.engineInstance) { console.warn('[EngineManager] 3D Engine not initialized.'); return; } this.engineInstance.setWalkGravity(enabled); } /** * 设置漫游碰撞检测开关 * @param enabled 是否启用碰撞检测 */ public setWalkCollision(enabled: boolean): void { if (!this.engineInstance) { console.warn('[EngineManager] 3D Engine not initialized.'); return; } this.engineInstance.setWalkCollision(enabled); } /** * 获取漫游模式是否激活 * @returns 是否处于漫游模式 */ public isFirstPersonModeActive(): boolean { if (!this.engineInstance) { return false; } return this.engineInstance.isFirstPersonModeActive(); } // ==================== 结束:漫游功能 ==================== ``` **Must NOT do**: - 不要修改其他管理器方法 **Parallelizable**: NO (依赖 Task 1) **References**: - `engine/src/managers/engine-manager.ts:242-249` - activateZoomBox 方法(作为插入位置参考) - `engine/src/components/engine/index.ts` - Task 1 新增的方法 **Acceptance Criteria**: - [x] 新增 `activateFirstPersonMode()` 方法 - [x] 新增 `deactivateFirstPersonMode()` 方法 - [x] 新增 `setWalkSpeed(speed: number)` 方法 - [x] 新增 `setWalkGravity(enabled: boolean)` 方法 - [x] 新增 `setWalkCollision(enabled: boolean)` 方法 - [x] 新增 `isFirstPersonModeActive()` 方法 **Commit**: YES - Message: `feat(engine-manager): 暴露漫游功能方法` - Files: `src/managers/engine-manager.ts` --- - [x] 3. 修改 WalkControlManager 回调对接实际 API **What to do**: 修改 `engine/src/managers/walk-control-manager.ts` 中的 4 个回调函数,对接到 EngineManager: ```typescript // ============ 本次需要修改的 4 个回调 ============ // 1. onWalkModeToggle - 对接底层第一人称漫游 API onWalkModeToggle: (isActive) => { console.log('[WalkControl] 第一人称漫游:', isActive); if (isActive) { this.pathManager?.hide(); this.registry.engine3d?.activateFirstPersonMode(); } else { this.registry.engine3d?.deactivateFirstPersonMode(); } this.emit('walk:walk-mode-toggle', { isActive }); }, // 2. onSpeedChange - 对接底层 moveSpeed onSpeedChange: (speed) => { console.log('[WalkControl] 速度变化:', speed); // 将 UI 速度值转换为引擎速度值(UI: 1-10, 引擎: 0.01-0.1) const engineSpeed = speed * 0.01; this.registry.engine3d?.setWalkSpeed(engineSpeed); this.emit('walk:speed-change', { speed }); }, // 3. onGravityToggle - 对接底层 applyGravity onGravityToggle: (enabled) => { console.log('[WalkControl] 重力:', enabled); this.registry.engine3d?.setWalkGravity(enabled); this.emit('walk:gravity-toggle', { enabled }); }, // 4. onCollisionToggle - 对接底层 applyCollision onCollisionToggle: (enabled) => { console.log('[WalkControl] 碰撞:', enabled); this.registry.engine3d?.setWalkCollision(enabled); this.emit('walk:collision-toggle', { enabled }); }, // ============ 以下回调保持现状,不修改 ============ // onPlanViewToggle - 保持现有 UI 控制 // onPathModeToggle - 保持现有 UI 控制 // onWalkModeChange - 第三人称功能,暂不接入 // onCharacterModelChange - 第三人称功能,暂不接入 // onExit - 已实现 ``` **Must NOT do**: - 不要修改 onPlanViewToggle(已正确对接到 MapDialogManager,底层无 API) - 不要修改 onPathModeToggle(已正确对接到 WalkPathDialogManager,底层无 API) - 不要尝试实现角色模型的实际切换(底层不支持) **Parallelizable**: NO (依赖 Task 2) **References**: - `engine/src/managers/walk-control-manager.ts:57-81` - 当前的回调实现 - `engine/src/managers/engine-manager.ts` - Task 2 新增的方法 - `engine/src/components/walk-control-panel/types.ts` - 回调类型定义 **Acceptance Criteria**: - [x] `onWalkModeToggle` 调用 `activateFirstPersonMode()` / `deactivateFirstPersonMode()` - [x] `onSpeedChange` 调用 `setWalkSpeed()` 并进行值转换 (UI 1-10 → 引擎 0.01-0.1) - [x] `onGravityToggle` 调用 `setWalkGravity()` - [x] `onCollisionToggle` 调用 `setWalkCollision()` - [x] 其他回调保持现状不修改 **Commit**: YES - Message: `feat(walk-control): 对接漫游功能到底层 API` - Files: `src/managers/walk-control-manager.ts` --- - [x] 4. 更新 Toolbar 调用链文档 **What to do**: 更新 `.sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md` 中的漫游部分,补充完整的调用链: ```markdown ## 5. 漫游 (Walk) - 第一人称漫游 > 标注说明: `[SDK]` = SDK 层代码, `[底层]` = bim_engine_base 底层引擎 ### 5.1 第一人称漫游模式开关 ``` UI 点击漫游按钮 → [SDK] WalkControlPanel.onWalkModeToggle(isActive) → [SDK] WalkControlManager.onWalkModeToggle → [SDK] EngineManager.activateFirstPersonMode() / deactivateFirstPersonMode() → [SDK] Engine.activateFirstPersonMode() / deactivateFirstPersonMode() → [底层] engine.controlModule.switchFirstPersonMode() / switchDefaultMode() ``` ### 5.2 速度调节 ``` UI 速度按钮 (1-10) → [SDK] WalkControlPanel.onSpeedChange(speed) → [SDK] WalkControlManager.onSpeedChange → [SDK] EngineManager.setWalkSpeed(speed * 0.01) // 值转换: UI 1-10 → 引擎 0.01-0.1 → [SDK] Engine.setWalkSpeed(speed) → [底层] engine.controlModule.firstPersonControls.moveSpeed = speed ``` ### 5.3 重力开关 ``` UI 重力复选框 → [SDK] WalkControlPanel.onGravityToggle(enabled) → [SDK] WalkControlManager.onGravityToggle → [SDK] EngineManager.setWalkGravity(enabled) → [SDK] Engine.setWalkGravity(enabled) → [底层] engine.controlModule.firstPersonControls.applyGravity = enabled ``` ### 5.4 碰撞检测开关 ``` UI 碰撞复选框 → [SDK] WalkControlPanel.onCollisionToggle(enabled) → [SDK] WalkControlManager.onCollisionToggle → [SDK] EngineManager.setWalkCollision(enabled) → [SDK] Engine.setWalkCollision(enabled) → [底层] engine.controlModule.firstPersonControls.applyCollision = enabled ``` ``` **Must NOT do**: - 不要修改其他功能的文档 **Parallelizable**: NO (依赖 Task 3) **References**: - `.sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md` - 现有调用链文档 **Acceptance Criteria**: - [x] 第一人称漫游模式开关调用链已更新 - [x] 速度调节调用链已更新 - [x] 重力开关调用链已更新 - [x] 碰撞检测开关调用链已更新 **Commit**: YES - Message: `docs: 更新漫游功能调用链文档` - Files: `.sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md` --- - [x] 5. 构建验证 **What to do**: 运行构建命令验证代码无误: ```bash bun run build ``` **Must NOT do**: - 不要跳过构建验证 **Parallelizable**: NO (依赖 Task 1, 2, 3) **References**: - `package.json` - 构建脚本配置 **Acceptance Criteria**: - [x] `bun run build` 执行成功,无错误 - [x] 无 TypeScript 类型错误 - [x] dist 目录生成正常 **Commit**: NO (无代码变更) --- ## Commit Strategy | After Task | Message | Files | Verification | |------------|---------|-------|--------------| | 1 | `feat(engine): 新增漫游功能方法` | src/components/engine/index.ts | bun run build | | 2 | `feat(engine-manager): 暴露漫游功能方法` | src/managers/engine-manager.ts | bun run build | | 3 | `feat(walk-control): 对接漫游功能到底层 API` | src/managers/walk-control-manager.ts | bun run build | | 4 | `docs: 更新漫游功能调用链文档` | .sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md | N/A | --- ## Success Criteria ### Verification Commands ```bash bun run build # Expected: BUILD SUCCESS ``` ### Final Checklist - [x] Engine 组件新增 6 个漫游方法(第一人称漫游 + 速度 + 重力 + 碰撞) - [x] EngineManager 暴露 6 个漫游方法 - [x] WalkControlManager 4 个回调对接完成(onWalkModeToggle/onSpeedChange/onGravityToggle/onCollisionToggle) - [x] 调用链文档已更新 - [x] 构建成功