Files
bim_engine/src/managers/engine-manager.ts

465 lines
14 KiB
TypeScript
Raw Normal View History

/**
* 3D
* 3D
*/
2025-12-04 18:41:11 +08:00
import { Engine, type EngineOptions, type ModelLoadOptions } from '../components/engine';
import { BaseManager } from '../core/base-manager';
import { RightKeyManager } from './right-key-manager';
import type { MeasureMode } from '../types/measure';
import type { SectionBoxRange } from '../components/section-box-panel/types';
import type { MenuItemConfig } from '../components/menu/item';
import { ManagerRegistry } from '../core/manager-registry';
2025-12-04 18:41:11 +08:00
/**
* 3D
* 3D
2025-12-04 18:41:11 +08:00
*/
export class EngineManager extends BaseManager {
/** 容器元素 */
2025-12-04 18:41:11 +08:00
private container: HTMLElement;
/** 引擎实例 */
2025-12-08 10:02:24 +08:00
private engineInstance: Engine | null = null;
/** 右键菜单管理器 */
public rightKey: RightKeyManager | null = null;
2025-12-04 18:41:11 +08:00
constructor(container: HTMLElement) {
super();
2025-12-04 18:41:11 +08:00
this.container = container;
}
/**
* 3D
* @param options
2025-12-04 18:41:11 +08:00
* @returns
*/
public initialize(options?: Omit<EngineOptions, 'container'>): boolean {
2025-12-08 10:02:24 +08:00
if (this.engineInstance && this.engineInstance.isInitialized()) {
2025-12-04 18:41:11 +08:00
console.warn('[EngineManager] 3D Engine already initialized. Destroying old instance...');
2025-12-08 10:02:24 +08:00
this.engineInstance.destroy();
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
}
try {
2025-12-08 10:02:24 +08:00
this.engineInstance = new Engine({
2025-12-04 18:41:11 +08:00
container: this.container,
...options,
2025-12-04 18:41:11 +08:00
});
2025-12-08 10:02:24 +08:00
this.engineInstance.init();
2025-12-04 18:41:11 +08:00
this.rightKey = new RightKeyManager(this.container);
this.rightKey.registerHandler((_e) => {
const selected = this.getSelectedComponent();
const items: MenuItemConfig[] = [];
if (selected) {
// 1. 构件详情
items.push({
id: 'componentDetail',
label: 'menu.componentDetail',
group: 'component',
order: 1,
divider: true,
onClick: () => {
const registry = ManagerRegistry.getInstance();
registry.componentDetail?.show();
this.rightKey?.hide();
}
});
// 2. 隐藏选中构件
items.push({
id: 'hideSelected',
label: 'menu.hideSelected',
group: 'component',
order: 2,
onClick: () => {
console.log('[Menu] 隐藏选中构件 - 暂未实现');
this.rightKey?.hide();
}
});
// 3. 半透明选中构件
items.push({
id: 'transparentSelected',
label: 'menu.transparentSelected',
group: 'component',
order: 3,
onClick: () => {
console.log('[Menu] 半透明选中构件 - 暂未实现');
this.rightKey?.hide();
}
});
// 4. 隔离选中构件(带子菜单)
items.push({
id: 'isolateSelected',
label: 'menu.isolateSelected',
group: 'component',
order: 4,
divider: true,
children: [
{
id: 'hideOthers',
label: 'menu.hideOthers',
onClick: () => {
console.log('[Menu] 隔离 - 其他构件隐藏 - 暂未实现');
this.rightKey?.hide();
}
},
{
id: 'transparentOthers',
label: 'menu.transparentOthers',
onClick: () => {
console.log('[Menu] 隔离 - 其他构件半透明 - 暂未实现');
this.rightKey?.hide();
}
}
]
});
// 5. 剖切盒适应
items.push({
id: 'fitSectionBox',
label: 'menu.fitSectionBox',
group: 'component',
order: 5,
onClick: () => {
console.log('[Menu] 剖切盒适应 - 暂未实现');
this.rightKey?.hide();
}
});
}
// 6. 显示全部(始终显示)
items.push({
id: 'showAll',
label: 'menu.showAll',
group: 'component',
order: 6,
onClick: () => {
console.log('[Menu] 显示全部 - 暂未实现');
this.rightKey?.hide();
}
});
return items;
});
2025-12-08 10:02:24 +08:00
return this.engineInstance.isInitialized();
2025-12-04 18:41:11 +08:00
} catch (error) {
console.error('[EngineManager] Failed to initialize 3D engine:', error);
2025-12-08 10:02:24 +08:00
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
return false;
}
}
2025-12-04 18:41:11 +08:00
/**
*
* @returns
2025-12-04 18:41:11 +08:00
*/
public isInitialized(): boolean {
2025-12-08 10:02:24 +08:00
return this.engineInstance !== null && this.engineInstance.isInitialized();
2025-12-04 18:41:11 +08:00
}
2025-12-04 18:41:11 +08:00
/**
*
* @param url URL
* @param options
2025-12-04 18:41:11 +08:00
*/
public loadModel(url: string, options?: ModelLoadOptions): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
2025-12-04 18:41:11 +08:00
return;
}
2025-12-08 10:02:24 +08:00
this.engineInstance.loadModel(url, options);
2025-12-04 18:41:11 +08:00
}
/**
*
* @returns
2025-12-04 18:41:11 +08:00
*/
public getEngine(): any {
2025-12-08 10:02:24 +08:00
if (!this.engineInstance) {
2025-12-04 18:41:11 +08:00
console.warn('[EngineManager] 3D Engine not initialized.');
return null;
}
2025-12-08 10:02:24 +08:00
return this.engineInstance.getEngine();
2025-12-04 18:41:11 +08:00
}
/** 相机回到初始位置 */
public CameraGoHome(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.CameraGoHome();
}
/** 暂停渲染 */
public pauseRendering(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.pauseRendering();
}
/** 恢复渲染 */
public resumeRendering(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.resumeRendering();
}
/**
*
* @param mode
*/
public activateMeasure(mode: MeasureMode): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.activateMeasure(mode);
}
/** 停用测量模式 */
public deactivateMeasure(): void {
if (!this.engineInstance) {
return;
}
this.engineInstance.deactivateMeasure();
}
/**
*
* @returns
*/
public getCurrentMeasureType(): MeasureMode | null {
if (!this.engineInstance) {
return null;
}
return this.engineInstance.getCurrentMeasureType();
}
/** 清除所有测量标注 */
public clearAllMeasures(): void {
if (!this.engineInstance) {
return;
}
this.engineInstance.clearAllMeasures();
}
/**
*
* @param axis ('x' | 'y' | 'z')
*/
public activateSectionAxis(axis: 'x' | 'y' | 'z'): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.activateSectionAxis(axis);
}
/**
*
*/
public deactivateSectionAxis(): void {
if (!this.engineInstance) {
return;
}
this.engineInstance.deactivateSectionAxis();
}
/**
*
* @returns
*/
public getCurrentSectionAxis(): 'x' | 'y' | 'z' | null {
if (!this.engineInstance) {
return null;
}
return this.engineInstance.getCurrentSectionAxis();
}
/** 激活剖切盒 */
public activateSectionBox(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.activateSectionBox();
}
/** 停用剖切盒 */
public deactivateSectionBox(): void {
if (!this.engineInstance) {
return;
}
this.engineInstance.deactivateSectionBox();
}
/** 设置剖切盒范围(百分比 0-100 */
public setSectionBoxRange(range: SectionBoxRange): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.setSectionBoxRange(range);
}
/** 适应剖切盒到模型 */
public fitSectionBoxToModel(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.fitSectionBoxToModel();
}
/** 重置剖切盒 */
public resetSectionBox(): void {
if (!this.engineInstance) {
return;
}
this.engineInstance.resetSectionBox();
}
/** 激活框选放大功能 */
public activateZoomBox(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.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();
}
// ==================== 结束:漫游功能 ====================
// ==================== 构件选中 ====================
/**
*
* @returns URL ID null
*/
public getSelectedComponent(): { url: string; id: string } | null {
return this.engineInstance?.getSelectedComponent() ?? null;
}
/**
*
* @param url URL
* @param id ID
* @param callback
*/
public getComponentProperties(
url: string,
id: string,
callback: (data: any) => void
): void {
this.engineInstance?.getComponentProperties(url, id, callback);
}
// ==================== 结束:构件选中 ====================
// ==================== 模型树 ====================
public getTypeTreeData(): any[] {
return this.engineInstance?.getTypeTreeData() ?? [];
}
public getLevelTreeData(): any[] {
return this.engineInstance?.getLevelTreeData() ?? [];
}
public getMajorTreeData(): any[] {
return this.engineInstance?.getMajorTreeData() ?? [];
}
// ==================== 结束:模型树 ====================
/** 销毁引擎管理器 */
2025-12-04 18:41:11 +08:00
public destroy(): void {
2025-12-08 10:02:24 +08:00
if (this.engineInstance) {
this.engineInstance.destroy();
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
}
if (this.rightKey) {
this.rightKey.destroy();
this.rightKey = null;
}
super.destroy();
2025-12-04 18:41:11 +08:00
}
}