feat(engine): 新增漫游功能方法
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user