Files
bim_engine/src/components/engine/index.ts

208 lines
6.6 KiB
TypeScript
Raw Normal View History

2025-12-04 18:41:11 +08:00
import type { ThemeConfig } from '../../themes/types';
import { IBimComponent } from '../../types/component';
import { themeManager } from '../../services/theme';
import type { EngineOptions, ModelLoadOptions } from './types';
// 导入第三方 SDK 的 createEngine 函数
import { createEngine as createEngineSDK } from '../../bim-engine-sdk.es.js';
// 重新导出类型,方便外部引用
export type { EngineOptions, ModelLoadOptions };
2025-12-22 15:39:58 +08:00
/**
* Engine
* import { createEngine }
*/
export const createEngine = (options: EngineOptions) => {
return new Engine(options);
};
2025-12-04 18:41:11 +08:00
/**
* 3D
* 3D
*/
export class Engine implements IBimComponent {
/** 第三方 3D 引擎实例 */
private engine: any = null;
/** 引擎挂载的容器元素 */
private container: HTMLElement;
/** 引擎容器 ID用于传递给 createEngine */
private containerId: string;
/** 引擎配置选项(不包含 container */
private options: Omit<EngineOptions, 'container'>;
/** 是否已初始化 */
private _isInitialized = false;
/** 是否已销毁 */
private _isDestroyed = false;
/** 主题订阅取消函数 */
private unsubscribeTheme: (() => void) | null = null;
/**
*
* @param options 3D
*/
constructor(options: EngineOptions) {
// 解析容器元素
this.container = options.container;
// 如果容器没有 id生成一个唯一的 id
if (!this.container.id) {
this.containerId = `engine-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
this.container.id = this.containerId;
} else {
this.containerId = this.container.id;
}
// 保存配置选项(设置默认值)
this.options = {
backgroundColor: options.backgroundColor ?? 0x1a1a1a, // 默认深色背景
version: options.version ?? 'v1', // 默认使用 v1 版本
showStats: options.showStats ?? false, // 默认不显示统计
showViewCube: options.showViewCube ?? true, // 默认显示视图立方体
};
}
/**
* ()
* div
*/
public init(): void {
if (this._isInitialized) {
console.warn('[Engine] Engine already initialized.');
return;
}
if (this._isDestroyed) {
console.error('[Engine] Cannot initialize destroyed engine.');
return;
}
try {
// 创建引擎配置对象
const engineConfig = {
containerId: this.containerId,
backgroundColor: this.options.backgroundColor,
version: this.options.version,
showStats: this.options.showStats,
showViewCube: this.options.showViewCube,
};
// 调用引擎创建函数创建引擎实例
// 将 options 中的配置复制给 createEngine
this.engine = createEngineSDK(engineConfig);
if (!this.engine) {
throw new Error('Failed to create engine instance');
}
// 标记为已初始化
this._isInitialized = true;
// 订阅主题变化
this.unsubscribeTheme = themeManager.subscribe((theme) => {
this.setTheme(theme);
});
// 应用当前主题
this.setTheme(themeManager.getTheme());
} catch (error) {
console.error('[Engine] Failed to initialize engine:', error);
this._isInitialized = false;
throw error;
}
}
/**
* ()
* 3D
* @param theme
*/
public setTheme(theme: ThemeConfig): void {
if (!this._isInitialized || !this.engine) {
return;
}
// 根据主题调整背景色
// dark 主题使用深色背景light 主题使用浅色背景
let backgroundColor: number;
if (theme.name === 'dark') {
backgroundColor = 0x1a1a1a; // 深色背景
} else if (theme.name === 'light') {
backgroundColor = 0xf5f5f5; // 浅色背景
} else {
// 自定义主题,尝试从主题配置中获取背景色
// 如果主题配置中有 backgroundColor使用它否则使用默认值
backgroundColor = this.options.backgroundColor ?? 0x1a1a1a;
}
// 如果引擎支持设置背景色,则更新
if (this.engine && typeof this.engine.setBackgroundColor === 'function') {
this.engine.setBackgroundColor(backgroundColor);
} else if (this.engine && this.engine.scene) {
// 如果引擎有 scene 对象,尝试设置背景色
if (this.engine.scene.background) {
this.engine.scene.background.setHex(backgroundColor);
}
}
}
/**
* ()
*/
public setLocales(): void {
// 3D 引擎组件暂时不需要本地化
}
/**
*
*/
public isInitialized(): boolean {
return this._isInitialized;
}
/**
* 3D
* @param url URL
* @param options
*/
public loadModel(url: string, options?: ModelLoadOptions): void {
if (!this._isInitialized || !this.engine) {
console.error('[Engine] Engine not initialized. Please call init() first.');
return;
}
if (!url) {
console.error('[Engine] Model URL is required.');
return;
}
this.engine.loader.loadModel(url, options);
}
/**
* 3D
*/
public getEngine(): any {
return this.engine;
}
/**
* ()
*
*/
public destroy(): void {
if (this._isDestroyed) {
return;
}
// 取消主题订阅
if (this.unsubscribeTheme) {
this.unsubscribeTheme();
this.unsubscribeTheme = null;
}
// 清理容器(可选,根据需求决定是否清空容器)
this.container.innerHTML = '';
// 更新状态
this._isDestroyed = true;
this._isInitialized = false;
}
}