Files
bim_engine/docs/components/engine.md
2025-12-22 18:48:38 +08:00

613 lines
15 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.

# Engine 组件详细文档
> 本文档详细描述 Engine 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
---
## 1. 组件概述
### 1.1 基本信息
- **组件名称**: `Engine`
- **文件路径**: `src/components/engine/index.ts`
- **类型定义**: `src/components/engine/types.ts`
- **实现接口**: `IBimComponent`
- **用途**: 封装第三方 3D 引擎 SDK提供统一的 3D 引擎管理接口
### 1.2 在 SDK 中的位置
- Engine 组件是独立的 3D 引擎组件
- 必须通过 `EngineManager` 使用,不允许直接使用
- `EngineManager` 位于 `src/managers/engine-manager.ts`
- 采用延迟初始化模式,需要用户主动调用 `init()` 方法
### 1.3 第三方 SDK 依赖
- 依赖 `src/bim-engine-sdk.es.js` 中的 `createEngine` 函数
- 通过依赖注入方式使用,不直接导入
---
## 2. 组件类 API 文档
### 2.1 构造函数
```typescript
constructor(options: EngineOptions)
```
**参数**:
- `options`: `EngineOptions` - 3D 引擎配置选项
**默认配置**:
```typescript
{
backgroundColor: 0x1a1a1a, // 默认深色背景
version: 'v1', // 默认使用 v1 版本
showStats: false, // 默认不显示统计
showViewCube: true // 默认显示视图立方体
}
```
**行为**:
- 解析容器元素
- 如果容器没有 id生成一个唯一的 id
- 保存配置选项(设置默认值)
### 2.2 公共方法
#### `init(): void`
初始化组件(实现 `IBimComponent` 接口)
**功能**:
- 检查是否已初始化或已销毁
- 创建引擎配置对象
- 调用 `createEngineSDK()` 创建引擎实例
- 标记为已初始化
- 订阅主题变化
- 应用当前主题
**错误处理**:
- 如果创建失败,抛出错误并标记为未初始化
#### `setTheme(theme: ThemeConfig): void`
设置主题(实现 `IBimComponent` 接口)
**参数**:
- `theme`: `ThemeConfig` - 全局主题配置
**功能**:
- 根据主题名称选择背景色:
- `dark`: 使用深色背景 `0x1a1a1a`
- `light`: 使用浅色背景 `0xf5f5f5`
- `custom`: 使用配置中的 `backgroundColor` 或默认值
- 尝试更新引擎背景色:
- 如果引擎有 `setBackgroundColor()` 方法,调用它
- 否则,如果引擎有 `scene.background`,设置其颜色
#### `setLocales(): void`
设置语言(实现 `IBimComponent` 接口)
**功能**:
- 3D 引擎组件暂时不需要本地化
- 方法为空实现
#### `isInitialized(): boolean`
检查是否已初始化
**返回**: `boolean` - 是否已初始化
#### `loadModel(url: string, options?: ModelLoadOptions): void`
加载 3D 模型
**参数**:
- `url`: `string` - 模型文件 URL必需
- `options`: `ModelLoadOptions` (可选) - 加载选项
**功能**:
- 检查引擎是否已初始化
- 检查 URL 是否提供
- 调用引擎的 `loader.loadModel()` 方法加载模型
**加载选项**:
- `position`: `[number, number, number]` - 模型位置 [x, y, z]
- `rotation`: `[number, number, number]` - 模型旋转(弧度)[x, y, z]
- `scale`: `[number, number, number]` - 模型缩放 [x, y, z]
- `id`: `string` - 模型 ID可选
#### `getEngine(): any`
获取原始 3D 引擎实例
**返回**: 第三方 3D 引擎实例或 `null`
**功能**:
- 返回底层 3D 引擎实例
- 用于直接调用第三方引擎的其他 API
#### `destroy(): void`
销毁组件(实现 `IBimComponent` 接口)
**功能**:
- 取消主题订阅
- 清空容器内容
- 标记为已销毁和未初始化
**注意**: 不销毁引擎实例本身(由第三方 SDK 管理)
---
## 3. 分化组件说明
**Engine 组件没有分化组件**
---
## 4. Manager API 文档
### 4.1 EngineManager 类
**文件路径**: `src/managers/engine-manager.ts`
**继承关系**: `EngineManager extends BimComponent`
### 4.2 构造函数
```typescript
constructor(engine: BimEngine, container: HTMLElement)
```
**参数**:
- `engine`: `BimEngine` - 引擎实例
- `container`: `HTMLElement` - 3D 引擎挂载的目标容器
**行为**:
- 保存容器引用
- **不自动初始化引擎**(延迟初始化模式)
### 4.3 公共方法
#### `initialize(options?: Omit<EngineOptions, 'container'>): boolean`
初始化 3D 引擎
**参数**:
- `options`: `Omit<EngineOptions, 'container'>` (可选) - 引擎配置选项
**返回**: `boolean` - 是否初始化成功
**功能**:
- 如果已经初始化,先销毁旧的实例
- 创建 `Engine` 组件实例
- 调用组件的 `init()` 方法初始化引擎
- 返回初始化结果
**错误处理**:
- 如果初始化失败,返回 `false` 并输出错误信息
#### `isInitialized(): boolean`
检查 3D 引擎是否已初始化
**返回**: `boolean` - 是否已初始化
#### `loadModel(url: string, options?: ModelLoadOptions): void`
加载 3D 模型
**参数**:
- `url`: `string` - 模型文件 URL
- `options`: `ModelLoadOptions` (可选) - 加载选项
**功能**:
- 检查引擎是否已初始化
- 如果未初始化,输出错误信息
- 调用引擎组件的 `loadModel()` 方法
#### `getEngine(): any`
获取原始 3D 引擎实例
**返回**: 第三方 3D 引擎实例或 `null`
**功能**:
- 用于直接调用第三方引擎的其他 API
- 如果引擎未初始化,返回 `null` 并输出警告
#### `destroy(): void`
销毁 3D 引擎实例
**功能**:
- 调用引擎组件的 `destroy()` 方法
- 清空引擎实例引用
---
## 5. UI 详细描述
### 5.1 DOM 结构
**Engine 组件不直接创建 UI 元素**,而是:
1. **使用容器元素**:
- 容器元素由外部提供(通过 `EngineOptions.container`
- 如果容器没有 id组件会生成一个唯一的 id
2. **第三方 SDK 创建 UI**:
- 第三方 SDK 的 `createEngine()` 函数会在容器内创建 3D 场景
- 可能包括:
- Canvas 元素WebGL 渲染)
- 统计面板(如果 `showStats: true`
- 视图立方体(如果 `showViewCube: true`
### 5.2 容器 ID 生成
**算法**:
```typescript
containerId = `engine-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
```
**格式**: `engine-container-[时间戳]-[随机字符串]`
**示例**: `engine-container-1704067200000-k3j9x2m1p`
### 5.3 第三方 SDK 配置
**传递给 `createEngine()` 的配置对象**:
```typescript
{
containerId: string, // 容器 ID
backgroundColor: number, // 背景色(十六进制数字)
version: 'v1' | 'v2', // WebGL 版本
showStats: boolean, // 是否显示统计
showViewCube: boolean // 是否显示视图立方体
}
```
---
## 6. 逻辑流程详细描述
### 6.1 初始化流程
1. **构造函数调用**:
- 解析容器元素
- 生成或使用容器 ID
- 保存配置选项(设置默认值)
2. **init() 方法执行**(用户主动调用):
- 检查是否已初始化,如果是则返回
- 检查是否已销毁,如果是则报错
- 创建引擎配置对象
- 调用 `createEngineSDK()` 创建引擎实例
- 检查引擎实例是否创建成功
- 标记为已初始化
- 订阅主题变化:`themeManager.subscribe()`
- 应用当前主题
### 6.2 生命周期
#### 创建阶段
- 构造函数 → 保存配置
#### 初始化阶段(延迟)
- 用户调用 `init()` → 创建引擎实例 → 订阅主题
#### 运行阶段
- 响应主题变更:`setTheme()` 被调用
- 加载模型:`loadModel()` 被调用
- 用户交互3D 场景交互(由第三方 SDK 处理)
#### 销毁阶段
- `destroy()` 被调用
- 取消主题订阅
- 清空容器
- 更新状态
### 6.3 主题变更流程
1. 主题变更 → `themeManager` 通知订阅者
2. `setTheme()` 方法被调用
3. 根据主题名称选择背景色:
- `dark``0x1a1a1a`
- `light``0xf5f5f5`
- `custom` → 使用配置值或默认值
4. 尝试更新引擎背景色:
- 方法 1: 调用 `engine.setBackgroundColor(backgroundColor)`
- 方法 2: 设置 `engine.scene.background.setHex(backgroundColor)`
### 6.4 模型加载流程
1. 用户调用 `loadModel(url, options)`
2. 检查引擎是否已初始化
3. 检查 URL 是否提供
4. 调用 `engine.loader.loadModel(url, options)`
5. 第三方 SDK 处理模型加载
### 6.5 状态管理
#### 内部状态
- `_isInitialized`: 是否已初始化
- `_isDestroyed`: 是否已销毁
- `engine`: 第三方 3D 引擎实例
- `containerId`: 容器 ID
- `options`: 引擎配置选项
#### 订阅管理
- `unsubscribeTheme`: 主题订阅取消函数
### 6.6 与其他组件的交互
- **与 EngineManager**: 通过 Manager 创建和管理
- **与 ThemeManager**: 订阅主题变更
- **与第三方 SDK**: 通过 `createEngine()` 函数创建引擎实例
---
## 7. 国际化支持
### 7.1 使用的翻译键
**Engine 组件不使用翻译键**3D 引擎不需要国际化)。
### 7.2 语言变更处理
- `setLocales()` 方法为空实现
- 不订阅语言变更
---
## 8. 主题支持
### 8.1 使用的主题变量
- 根据主题名称选择背景色:
- `dark` 主题 → `0x1a1a1a`(深色背景)
- `light` 主题 → `0xf5f5f5`(浅色背景)
- `custom` 主题 → 使用配置值或默认值
### 8.2 主题变更处理
- 组件订阅 `themeManager.subscribe()`
- 主题变更时,`setTheme()` 方法被调用
- 根据主题名称选择背景色
- 尝试更新引擎背景色(通过引擎 API
### 8.3 实现细节
```typescript
public setTheme(theme: ThemeConfig): void {
let backgroundColor: number;
if (theme.name === 'dark') {
backgroundColor = 0x1a1a1a;
} else if (theme.name === 'light') {
backgroundColor = 0xf5f5f5;
} else {
backgroundColor = this.options.backgroundColor ?? 0x1a1a1a;
}
// 尝试更新引擎背景色
if (this.engine && typeof this.engine.setBackgroundColor === 'function') {
this.engine.setBackgroundColor(backgroundColor);
} else if (this.engine && this.engine.scene) {
if (this.engine.scene.background) {
this.engine.scene.background.setHex(backgroundColor);
}
}
}
```
---
## 9. 使用示例
### 9.1 基本使用(通过 EngineManager
```typescript
import { BimEngine } from 'bim-engine-sdk';
const engine = new BimEngine('container');
// 初始化 3D 引擎(延迟初始化)
const success = engine.initEngine({
backgroundColor: 0x333333,
version: 'v1',
showStats: true,
showViewCube: true
});
if (success) {
console.log('3D 引擎初始化成功');
}
// 加载模型
engine.engine.loadModel('/model/building.glb', {
position: [0, 0, 0],
rotation: [0, 0, 0],
scale: [1, 1, 1]
});
```
### 9.2 高级使用
```typescript
// 检查引擎是否已初始化
if (engine.engine.isInitialized()) {
// 加载模型
engine.engine.loadModel('/model/model.glb');
}
// 获取原始引擎实例,调用第三方 API
const rawEngine = engine.engine.getEngine();
if (rawEngine) {
// 调用第三方 SDK 的其他方法
rawEngine.someOtherMethod();
}
```
### 9.3 主题切换
```typescript
// 切换主题会自动更新 3D 场景背景色
engine.setTheme('dark'); // 深色背景
engine.setTheme('light'); // 浅色背景
```
---
## 10. 实现细节(供 AI 重现)
### 10.1 关键算法
#### 容器 ID 生成算法
```typescript
function generateContainerId(): string {
const timestamp = Date.now();
const random = Math.random().toString(36).substr(2, 9);
return `engine-container-${timestamp}-${random}`;
}
```
#### 主题背景色选择算法
```typescript
function selectBackgroundColor(theme: ThemeConfig, defaultColor: number): number {
if (theme.name === 'dark') {
return 0x1a1a1a; // 深色背景
} else if (theme.name === 'light') {
return 0xf5f5f5; // 浅色背景
} else {
return defaultColor; // 自定义主题,使用配置值
}
}
```
#### 引擎背景色更新算法
```typescript
function updateEngineBackground(engine: any, color: number): void {
// 方法 1: 如果引擎有 setBackgroundColor 方法
if (engine && typeof engine.setBackgroundColor === 'function') {
engine.setBackgroundColor(color);
return;
}
// 方法 2: 如果引擎有 scene.background
if (engine && engine.scene && engine.scene.background) {
engine.scene.background.setHex(color);
return;
}
// 方法 3: 无法更新(引擎可能不支持)
}
```
### 10.2 性能优化点
1. **延迟初始化**:
- 引擎不自动初始化,由用户主动调用
- 减少不必要的资源消耗
2. **状态检查**:
- 初始化前检查状态,避免重复初始化
- 销毁后禁止初始化,避免错误
3. **错误处理**:
- 所有操作都有错误检查
- 提供有意义的错误信息
### 10.3 注意事项和边界情况
1. **容器 ID 唯一性**:
- 容器 ID 必须唯一
- 如果容器已有 id使用现有 id
- 如果容器没有 id生成唯一 id
2. **延迟初始化**:
- 引擎不会自动初始化
- 用户必须主动调用 `init()``initialize()`
- 初始化前调用其他方法会报错
3. **引擎实例管理**:
- 引擎实例由第三方 SDK 创建
- 组件不负责销毁引擎实例本身
- 只负责清理订阅和容器
4. **主题更新兼容性**:
- 不同第三方 SDK 的 API 可能不同
- 需要尝试多种方式更新背景色
- 如果都不支持,静默失败
5. **模型加载**:
- 模型 URL 必须是可访问的
- 模型格式由第三方 SDK 支持
- 加载选项由第三方 SDK 处理
6. **错误处理**:
- 初始化失败时,标记为未初始化
- 提供有意义的错误信息
- 不抛出未捕获的异常
7. **第三方 SDK 依赖**:
- 依赖 `bim-engine-sdk.es.js` 文件
- 通过动态导入或全局变量访问
- 需要确保 SDK 文件已加载
---
## 11. 类型定义
### 11.1 EngineOptions
```typescript
interface EngineOptions {
container: HTMLElement; // 容器元素(必需)
backgroundColor?: number; // 背景颜色(可选,默认 0x1a1a1a
version?: 'v1' | 'v2'; // WebGL 版本(可选,默认 'v1'
showStats?: boolean; // 是否显示性能统计(可选,默认 false
showViewCube?: boolean; // 是否显示视图立方体(可选,默认 true
}
```
### 11.2 ModelLoadOptions
```typescript
interface ModelLoadOptions {
position?: [number, number, number]; // 模型位置 [x, y, z](可选)
rotation?: [number, number, number]; // 模型旋转(弧度)[x, y, z](可选)
scale?: [number, number, number]; // 模型缩放 [x, y, z](可选)
id?: string; // 模型 ID可选
}
```
---
## 12. 文件清单
### 12.1 相关文件
- `src/components/engine/index.ts` - 主组件类
- `src/components/engine/types.ts` - 类型定义
- `src/managers/engine-manager.ts` - 管理器类
- `src/bim-engine-sdk.es.js` - 第三方 SDK依赖
### 12.2 依赖文件
- `src/types/component.ts` - IBimComponent 接口
- `src/themes/types.ts` - ThemeConfig 类型
- `src/services/theme.ts` - ThemeManager
---
## 13. 更新记录
| 日期 | 修改内容 | 修改人 |
|------|---------|--------|
| 2024-XX-XX | 初始创建 | AI Assistant |
---
**重要提醒**: 本文档必须与组件代码保持同步。任何组件修改都必须更新本文档!