Files
zhengte.babylonjs-sdk/src/babylonjs/AppRay.ts
2026-04-21 14:58:22 +08:00

142 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) {
// 先尝试热点mesh 热点 / sprite 热点)
// if (pickInfo && pickInfo.pickedMesh) {
// const isHotspotClick = this.mainApp.appHotspot?.handlePick(pickInfo.pickedMesh);
// if (isHotspotClick) return;
// }
// const isSpriteHotspotClick = this.mainApp.appHotspot?.handleSpritePick();
// if (isSpriteHotspotClick) return;
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)
}
}
/**
* 渲染热点
* @param hotspots 热点数据
*/
renderHotspots(hotspots: any[]): void {
this.mainApp.appHotspot?.render(hotspots);
}
}
export { AppRay }