This commit is contained in:
124
src/babylonjs/AppRay.ts
Normal file
124
src/babylonjs/AppRay.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import {
|
||||
type IPointerEvent,
|
||||
PickingInfo,
|
||||
PointerEventTypes,
|
||||
Vector3,
|
||||
AbstractMesh,
|
||||
Color3,
|
||||
PBRMaterial,
|
||||
StandardMaterial,
|
||||
HighlightLayer,
|
||||
PointerInfo,
|
||||
} from '@babylonjs/core'
|
||||
import { MainApp } from './MainApp'
|
||||
import { Monobehiver } from '../base/Monobehiver';
|
||||
import { EventBridge } from '../event/bridge';
|
||||
|
||||
class AppRay extends Monobehiver {
|
||||
oldPoint: Vector3 = Vector3.Zero()
|
||||
newPoint: Vector3 = Vector3.Zero()
|
||||
private highlightLayer: HighlightLayer | null = null
|
||||
private originalMaterial: any = null
|
||||
private highlightedMesh: AbstractMesh | null = null
|
||||
|
||||
constructor(mainApp: MainApp) {
|
||||
super(mainApp)
|
||||
}
|
||||
|
||||
Awake() {
|
||||
this.setupHighlightLayer()
|
||||
this.setupUnifiedEventHandling()
|
||||
}
|
||||
|
||||
// 设置高亮层
|
||||
setupHighlightLayer() {
|
||||
// 高亮层创建已禁用
|
||||
return
|
||||
}
|
||||
|
||||
// 设置统一的事件处理
|
||||
setupUnifiedEventHandling() {
|
||||
// 使用观察者模式而不是直接覆盖事件处理器
|
||||
this.mainApp.appScene.object.onPointerObservable.add((pointerInfo: PointerInfo) => {
|
||||
const { type, event, pickInfo } = pointerInfo;
|
||||
|
||||
// 检查事件类型并转换
|
||||
const pointerEvent = event as IPointerEvent;
|
||||
|
||||
// 只处理鼠标和触摸事件
|
||||
if (pointerEvent.pointerType !== "mouse" && pointerEvent.pointerType !== "touch") {
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理非主要触摸点
|
||||
if (pointerEvent.pointerType === "touch" && (pointerEvent as any).isPrimary === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === PointerEventTypes.POINTERDOWN) {
|
||||
this.oldPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY);
|
||||
} else if (type === PointerEventTypes.POINTERUP) {
|
||||
this.newPoint.set(pointerEvent.clientX, 0, pointerEvent.clientY);
|
||||
const distance = Vector3.Distance(this.oldPoint, this.newPoint);
|
||||
|
||||
// 只有在没有移动的情况下才处理单击
|
||||
if (distance < 5) { // 增加一些容差
|
||||
this.handleSingleClick(pointerEvent, pickInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 处理单击
|
||||
handleSingleClick(evt: IPointerEvent, pickInfo: PickingInfo | null) {
|
||||
if (pickInfo && pickInfo.pickedMesh) {
|
||||
EventBridge.modelClick({
|
||||
meshName: pickInfo.pickedMesh.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 高亮显示网格 - 已禁用
|
||||
highlightMesh(mesh: AbstractMesh) {
|
||||
// 高亮功能已禁用
|
||||
return
|
||||
}
|
||||
|
||||
// 使用材质方式高亮 - 已禁用
|
||||
highlightWithMaterial(mesh: AbstractMesh) {
|
||||
// 材质高亮功能已禁用
|
||||
return
|
||||
}
|
||||
|
||||
// 清除高亮
|
||||
clearHighlight() {
|
||||
try {
|
||||
// 清除高亮层
|
||||
if (this.highlightLayer && this.highlightedMesh) {
|
||||
try {
|
||||
this.highlightLayer.removeMesh(this.highlightedMesh as any)
|
||||
} catch (error) {
|
||||
console.warn('高亮层移除失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复原始材质
|
||||
if (this.highlightedMesh && this.originalMaterial) {
|
||||
const material = this.highlightedMesh.material as PBRMaterial
|
||||
if (material && this.originalMaterial.albedoColor) {
|
||||
material.albedoColor = this.originalMaterial.albedoColor
|
||||
material.emissiveColor = this.originalMaterial.emissiveColor
|
||||
}
|
||||
}
|
||||
|
||||
this.highlightedMesh = null
|
||||
this.originalMaterial = null
|
||||
} catch (error) {
|
||||
console.error('清除高亮失败:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { AppRay }
|
||||
Reference in New Issue
Block a user