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

628 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 漫游功能 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] 构建成功