From 0e38f5805221c16ab1db0591d91059c1662663ad Mon Sep 17 00:00:00 2001 From: yuding <1023798085@qq.com> Date: Wed, 28 Jan 2026 11:24:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(engine):=20=E6=96=B0=E5=A2=9E=E6=BC=AB?= =?UTF-8?q?=E6=B8=B8=E5=8A=9F=E8=83=BD=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/engine/index.ts | 184 ++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 2 deletions(-) diff --git a/src/components/engine/index.ts b/src/components/engine/index.ts index 3bc4a45..3891059 100644 --- a/src/components/engine/index.ts +++ b/src/components/engine/index.ts @@ -3,9 +3,10 @@ import { IBimComponent } from '../../types/component'; import { themeManager } from '../../services/theme'; import type { EngineOptions, ModelLoadOptions } from './types'; import type { MeasureMode } from '../../types/measure'; +import type { SectionBoxRange } from '../section-box-panel/types'; // 导入第三方 SDK 的 createEngine 函数(从 npm 包引入) -import { createEngine as createEngineSDK } from 'iflow-engine-base'; -// import { createEngine as createEngineSDK } from '../../../../bim_engine_base/dist/bim-engine-sdk.es'; +// import { createEngine as createEngineSDK } from 'iflow-engine-base'; +import { createEngine as createEngineSDK } from '../../../../bim_engine_base/dist/bim-engine-sdk.es'; // 重新导出类型,方便外部引用 @@ -44,6 +45,8 @@ export class Engine implements IBimComponent { private isMeasureActive: boolean = false; /** 当前激活的剖切轴向 */ private currentSectionAxis: 'x' | 'y' | 'z' | null = null; + /** 剖切盒是否激活 */ + private isSectionBoxActive: boolean = false; /** * 构造函数 @@ -502,6 +505,183 @@ export class Engine implements IBimComponent { // ==================== 结束:轴向剖切功能 ==================== + // ==================== 剖切盒功能 ==================== + + /** 激活剖切盒 */ + public activateSectionBox(): void { + if (!this._isInitialized || !this.engine) { + console.error('[Engine] Cannot activate section box: engine not initialized.'); + return; + } + + if (!this.engine.clipping?.sectionBox) { + console.error('[Engine] Section box module not available.'); + return; + } + + if (this.isSectionBoxActive) { + console.log('[Engine] Section box already active, skipping.'); + return; + } + + console.log('[Engine] Activating section box'); + this.engine.clipping.sectionBox.active(); + this.isSectionBoxActive = true; + } + + /** 停用剖切盒 */ + public deactivateSectionBox(): void { + if (!this._isInitialized || !this.engine?.clipping?.sectionBox) { + return; + } + + if (!this.isSectionBoxActive) { + return; + } + + console.log('[Engine] Deactivating section box'); + this.engine.clipping.sectionBox.disActive(); + this.isSectionBoxActive = false; + } + + /** 设置剖切盒范围(百分比 0-100) */ + public setSectionBoxRange(range: SectionBoxRange): void { + if (!this._isInitialized || !this.engine?.clipping?.sectionBox) { + console.error('[Engine] Cannot set section box range: engine not initialized.'); + return; + } + + console.log('[Engine] Setting section box range:', range); + this.engine.clipping.sectionBox.setboxPercent(range); + } + + /** 适应剖切盒到模型(将范围设置为整个模型包围盒) */ + public fitSectionBoxToModel(): void { + if (!this._isInitialized || !this.engine?.clipping?.sectionBox) { + console.error('[Engine] Cannot fit section box: engine not initialized.'); + return; + } + + const box = this.engine.octreeBox?.getBoundingBox(); + if (!box) { + console.error('[Engine] Cannot fit section box: model bounding box not available.'); + return; + } + + console.log('[Engine] Fitting section box to model'); + this.engine.clipping.sectionBox.setBox(box); + } + + /** + * 重置剖切盒 + * @remarks 将剖切盒范围恢复为整个模型的包围盒 + */ + public resetSectionBox(): void { + this.fitSectionBoxToModel(); + } + + // ==================== 结束:剖切盒功能 ==================== + + // ==================== 漫游功能 ==================== + + /** 漫游模式是否激活 */ + 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; + } + + // ==================== 结束:漫游功能 ==================== + /** 激活框选放大功能 */ public activateZoomBox(): void { if (!this._isInitialized || !this.engine) {