From d179e456fcaeca7d6f9aab38d2b6871a6dab9968 Mon Sep 17 00:00:00 2001 From: zguiy <1415466602@qq.com> Date: Sat, 6 Jun 2026 02:37:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=8Cbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/babylonjs/AppDropZone.ts | 45 +++++++++++++++++++++++++++++++++++- src/babylonjs/AppRay.ts | 8 +++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/babylonjs/AppDropZone.ts b/src/babylonjs/AppDropZone.ts index 0fb4ab5..a544e29 100644 --- a/src/babylonjs/AppDropZone.ts +++ b/src/babylonjs/AppDropZone.ts @@ -35,6 +35,9 @@ export class AppDropZone { // 存储原始墙面配置(用于 updateDivisions 时恢复完整墙面列表) private originalWalls: WallConfig[] = []; + // 备份数据,用于点击空白处时回退 + private backupConfig: DropZoneConfig | null = null; + constructor(scene: Scene) { this.scene = scene; this.placementWall = new AppPlacementWall(scene); @@ -100,6 +103,16 @@ export class AppDropZone { return []; } + // 每次 updateDivisions 都备份当前配置(深拷贝,保留 Vector3 对象) + this.backupConfig = { + ...this.dropZoneConfig, + walls: this.dropZoneConfig.walls.map(wall => ({ + ...wall, + startPoint: wall.startPoint.clone(), + endPoint: wall.endPoint.clone() + })) + }; + // 将数组转换为对象映射 const divisionsMap: Record = {}; divisions.forEach(item => { @@ -227,6 +240,8 @@ export class AppDropZone { // 记录新模型 this.zoneModelMap.set(zoneKey, modelId); + // 成功放置模型,确认当前配置(清除备份) + this.confirmConfig(); // 检查该墙面是否已满,如果满了则自动排列 this.checkAndAutoArrange(wallName); @@ -484,13 +499,41 @@ export class AppDropZone { /** * 隐藏所有放置区域 + * @param shouldRollback 是否回退到备份配置(点击空白处时为true) */ - hide(): void { + hide(shouldRollback: boolean = false): void { + // 如果需要回退且有备份数据,则恢复配置 + if (shouldRollback && this.backupConfig) { + this.dropZoneConfig = this.backupConfig; + this.backupConfig = null; + + // 同步 wallDivisionsMap + if (this.dropZoneConfig) { + this.dropZoneConfig.walls.forEach(wall => { + this.wallDivisionsMap.set(wall.name, wall.divisions); + }); + } + + // 重新生成放置区域,使 placementZones 与回退后的配置一致 + this.placementWall.generatePlacementAreas({ + ...this.dropZoneConfig, + walls: this.dropZoneConfig.walls + }); + } + this.placementWall.hide(); // 恢复所有已放置模型的拾取 this.setModelsPickable(true); } + /** + * 确认当前配置(清除备份) + * 当成功放置配件后调用,表示接受当前的配置修改 + */ + confirmConfig(): void { + this.backupConfig = null; + } + /** * 设置所有已放置模型的可拾取状态 * @param pickable 是否可拾取 diff --git a/src/babylonjs/AppRay.ts b/src/babylonjs/AppRay.ts index 32051ed..abe9e81 100644 --- a/src/babylonjs/AppRay.ts +++ b/src/babylonjs/AppRay.ts @@ -88,10 +88,10 @@ class AppRay extends Monobehiver { this.newPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY); const distance = Vector3.Distance(this.oldPoint, this.newPoint); - // 如果是长按后松手,隐藏分割区域 + // 如果是长按后松手,隐藏分割区域,并回退配置 if (this.isLongPress) { console.log('[长按] 松手,隐藏分割区域'); - this.mainApp.appDropZone.hide(); + this.mainApp.appDropZone.hide(true); } // 只有在没有移动且不是长按的情况下才处理单击 @@ -249,8 +249,8 @@ class AppRay extends Monobehiver { this.mainApp.appPositionGizmo.detach(); this.mainApp.appDomTo3D.hideAll(); - // 隐藏放置区域 - this.mainApp.appDropZone?.hide(); + // 隐藏放置区域,并回退到备份配置 + this.mainApp.appDropZone?.hide(true); } }