修复bug

This commit is contained in:
2026-05-25 13:08:56 +08:00
parent c6257883e5
commit 266c0c154e
3 changed files with 161 additions and 21 deletions

View File

@ -21,6 +21,11 @@ class AppRay extends Monobehiver {
private highlightLayer: HighlightLayer | null = null
private originalMaterial: any = null
private highlightedMesh: AbstractMesh | null = null
private pointerDownTime: number = 0
private pointerDownPickInfo: PickingInfo | null = null
private longPressTimer: any = null
private longPressThreshold: number = 500 // 长按阈值(毫秒)
private isLongPress: boolean = false
constructor(mainApp: MainApp) {
super(mainApp)
@ -58,18 +63,91 @@ class AppRay extends Monobehiver {
if (type === PointerEventTypes.POINTERDOWN) {
this.oldPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY);
this.pointerDownTime = Date.now();
this.pointerDownPickInfo = pickInfo;
this.isLongPress = false;
// 清除之前的定时器
if (this.longPressTimer) {
clearTimeout(this.longPressTimer);
}
// 设置长按定时器
this.longPressTimer = setTimeout(() => {
this.isLongPress = true;
this.handleLongPress(pointerEvent, this.pointerDownPickInfo);
}, this.longPressThreshold);
} else if (type === PointerEventTypes.POINTERUP) {
// 清除长按定时器
if (this.longPressTimer) {
clearTimeout(this.longPressTimer);
this.longPressTimer = null;
}
this.newPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY);
const distance = Vector3.Distance(this.oldPoint, this.newPoint);
// 只有在没有移动的情况下才处理单击
if (distance < 5) { // 增加一些容差
// 只有在没有移动且不是长按的情况下才处理单击
if (distance < 5 && !this.isLongPress) {
this.handleSingleClick(pointerEvent, pickInfo);
}
this.isLongPress = false;
} else if (type === PointerEventTypes.POINTERMOVE) {
// 如果移动了,取消长按
this.newPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY);
const distance = Vector3.Distance(this.oldPoint, this.newPoint);
if (distance > 5 && this.longPressTimer) {
clearTimeout(this.longPressTimer);
this.longPressTimer = null;
}
}
});
}
// 处理长按
handleLongPress(evt: IPointerEvent, pickInfo: PickingInfo | null) {
if (pickInfo && pickInfo.hit && pickInfo.pickedMesh) {
// 检查是否长按的是模型(不是放置区域、不是热点)
if (pickInfo.pickedMesh.metadata?.type === 'hotspot') {
return;
}
if (pickInfo.pickedMesh.name.startsWith('placement_')) {
return;
}
// 获取模型名称
const modelName = this.mainApp.appModel.findModelNameByMesh(pickInfo.pickedMesh);
if (modelName) {
// 通过模型找到它所在的墙面
const wallName = this.findModelWallName(modelName);
if (wallName) {
console.log(`[长按] 模型 ${modelName} 位于墙面 ${wallName},显示该墙面的放置区域`);
this.mainApp.appDropZone.showWall(wallName);
}
}
}
}
// 查找模型所在的墙面
private findModelWallName(modelId: string): string | null {
const zoneModelMap = this.mainApp.appDropZone['zoneModelMap'] as Map<string, string>;
if (!zoneModelMap) return null;
for (const [zoneKey, id] of zoneModelMap.entries()) {
if (id === modelId) {
// zoneKey 格式为 "wallName[index]"
const match = zoneKey.match(/^(.+)\[(\d+)\]$/);
if (match) {
return match[1];
}
}
}
return null;
}
// 处理单击
handleSingleClick(evt: IPointerEvent, pickInfo: PickingInfo | null) {
// 先尝试热点mesh 热点 / sprite 热点)
@ -93,7 +171,7 @@ class AppRay extends Monobehiver {
const clickedZone = zones.find(zone => zone.mesh === pickInfo.pickedMesh);
if (clickedZone) {
// 计算该放置区域的目标位置和旋转
const offsetDistance = 0; // 增加偏移距离,让模型更往外
const offsetDistance = 0;
const targetPosition = clickedZone.center.add(clickedZone.normal.scale(offsetDistance));
const targetDirection = clickedZone.normal.scale(-1);
const angle = Math.atan2(targetDirection.x, targetDirection.z);
@ -114,7 +192,7 @@ class AppRay extends Monobehiver {
},
rotation: {
x: 0,
y: angle * 180 / Math.PI, // 转换为角度
y: angle * 180 / Math.PI,
z: 0
},
scale: {
@ -130,6 +208,9 @@ class AppRay extends Monobehiver {
this.mainApp.appDomTo3D.hideAll()
// 隐藏放置区域,避免遮挡配件模型的点击
this.mainApp.appDropZone.hide();
const materialName = pickInfo.pickedMesh.material?.name || '';
const holdingShift = Boolean((evt as any).shiftKey);
const modelMeshes = this.mainApp.appModel.getModelMeshesByMesh(pickInfo.pickedMesh);