Files
bim_engine/.sisyphus/plans/walk-mode-api-integration.md

20 KiB
Raw Blame History

漫游功能 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

  • bun run build 构建成功
  • 第一人称漫游模式开关可正常切换
  • 速度调节可正常控制
  • 重力开关可正常控制
  • 碰撞开关可正常控制
  • 调用链文档已更新

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

  • 1. 在 Engine 组件中新增漫游相关方法

    What to do: 在 engine/src/components/engine/index.ts 中的剖切盒功能区块后添加:

    // ==================== 漫游功能 ====================
    
    /** 漫游模式是否激活 */
    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:

    • 新增 isWalkModeActive 私有属性
    • 新增 activateFirstPersonMode() 方法
    • 新增 deactivateFirstPersonMode() 方法
    • 新增 setWalkSpeed(speed: number) 方法
    • 新增 setWalkGravity(enabled: boolean) 方法
    • 新增 setWalkCollision(enabled: boolean) 方法
    • 新增 isFirstPersonModeActive() 方法
    • 所有方法注释使用中文

    Commit: YES

    • Message: feat(engine): 新增漫游功能方法
    • Files: src/components/engine/index.ts

  • 2. 在 EngineManager 中暴露漫游方法

    What to do: 在 engine/src/managers/engine-manager.ts 中的 activateZoomBox 方法后添加:

    // ==================== 漫游功能 ====================
    
    /** 激活第一人称漫游模式 */
    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:

    • 新增 activateFirstPersonMode() 方法
    • 新增 deactivateFirstPersonMode() 方法
    • 新增 setWalkSpeed(speed: number) 方法
    • 新增 setWalkGravity(enabled: boolean) 方法
    • 新增 setWalkCollision(enabled: boolean) 方法
    • 新增 isFirstPersonModeActive() 方法

    Commit: YES

    • Message: feat(engine-manager): 暴露漫游功能方法
    • Files: src/managers/engine-manager.ts

  • 3. 修改 WalkControlManager 回调对接实际 API

    What to do: 修改 engine/src/managers/walk-control-manager.ts 中的 4 个回调函数,对接到 EngineManager

    // ============ 本次需要修改的 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:

    • onWalkModeToggle 调用 activateFirstPersonMode() / deactivateFirstPersonMode()
    • onSpeedChange 调用 setWalkSpeed() 并进行值转换 (UI 1-10 → 引擎 0.01-0.1)
    • onGravityToggle 调用 setWalkGravity()
    • onCollisionToggle 调用 setWalkCollision()
    • 其他回调保持现状不修改

    Commit: YES

    • Message: feat(walk-control): 对接漫游功能到底层 API
    • Files: src/managers/walk-control-manager.ts

  • 4. 更新 Toolbar 调用链文档

    What to do: 更新 .sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md 中的漫游部分,补充完整的调用链:

    ## 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:

    • 第一人称漫游模式开关调用链已更新
    • 速度调节调用链已更新
    • 重力开关调用链已更新
    • 碰撞检测开关调用链已更新

    Commit: YES

    • Message: docs: 更新漫游功能调用链文档
    • Files: .sisyphus/drafts/TOOLBAR_API_CALLCHAIN.md

  • 5. 构建验证

    What to do: 运行构建命令验证代码无误:

    bun run build
    

    Must NOT do:

    • 不要跳过构建验证

    Parallelizable: NO (依赖 Task 1, 2, 3)

    References:

    • package.json - 构建脚本配置

    Acceptance Criteria:

    • bun run build 执行成功,无错误
    • 无 TypeScript 类型错误
    • 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

bun run build  # Expected: BUILD SUCCESS

Final Checklist

  • Engine 组件新增 6 个漫游方法(第一人称漫游 + 速度 + 重力 + 碰撞)
  • EngineManager 暴露 6 个漫游方法
  • WalkControlManager 4 个回调对接完成onWalkModeToggle/onSpeedChange/onGravityToggle/onCollisionToggle
  • 调用链文档已更新
  • 构建成功