import { AbstractMesh, Color3, Material, Mesh, MeshBuilder, PointerDragBehavior, PolygonMeshBuilder, Vector2, Vector3 } from "@babylonjs/core"; import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; import { classToClass, plainToClass } from "class-transformer"; import { SceneManager } from "src/app/babylon/controller/scene-manager"; import { BabylonTool } from "src/app/babylon/tool/babylon-tool"; import { MarkWindow } from "src/app/babylon/view/mark-window/mark-window"; import { MarkData, MarkType } from "../../../data/mark/mark-data"; import { MarkData_Area } from "../../../data/mark/other/mark-data-area"; import { ModelInfo_mark } from "../model-info-mark"; /** * 区域类的标绘物 */ export class ModelInfo_mark_area extends ModelInfo_mark { areaSize = 5;//区域尺寸 material: StandardMaterial;//mesh材质 pointMat: StandardMaterial; //顶点材质 areaPoint: AreaPoint[]; areaMesh: Mesh; areaDragEvent: PointerDragBehavior;//区域mesh 拖拽行为 onCreate(isNew: boolean) { super.onCreate(isNew); this.modelBox.position.y = this.modelBox.position.y + 1; let data = this.markData as MarkData_Area; this.pointMat = new StandardMaterial("mat_areaPoint", SceneManager.Instance.scene); this.pointMat.emissiveColor = Color3.FromHexString("#A9FF00"); this.pointMat.disableLighting = true; this.pointMat.alpha = 0.87; let instance = this; this.areaDragEvent = new PointerDragBehavior({ dragPlaneNormal: Vector3.Up() }); //平面内移动 this.areaDragEvent.moveAttached = false; this.areaDragEvent.onDragStartObservable.add((eventData) => { //instance.modelBox.translate(eventData.dragPlaneNormal, eventData.dragDistance); MarkWindow.instance.selectMarkDataFrom3d(instance, true); }) this.initMeshPoint(isNew); this.material = new StandardMaterial("mat_area", SceneManager.Instance.scene); this.material.emissiveColor = Color3.FromHexString((this.markData as MarkData_Area).color); this.material.disableLighting = true; this.material.alpha = 0.87; this.refreshMesh(); } getVector2Point(): Vector2[] { let data = this.markData as MarkData_Area; let point: Vector2[] = []; for (let i = 0; i < data.pointData.length; i++) { let pos = new Vector2(data.pointData[i].x, data.pointData[i].z); point.push(pos); } return point; } /** * 更新mesh */ refreshMesh() { if (this.areaMesh != null) { this.areaMesh.removeBehavior(this.areaDragEvent); this.areaMesh.dispose(); SceneManager.Instance.removeFromHighLight(this.areaMesh); } let poly_tri = new PolygonMeshBuilder("polytri", this.getVector2Point(), SceneManager.Instance.scene); this.areaMesh = poly_tri.build(true, 0); this.areaMesh.setParent(this.modelBox); this.areaMesh.position = new Vector3(0, 1, 0); this.areaMesh.material = this.material; this.areaMesh.addBehavior(this.areaDragEvent); if (this.isSelect) { // console.log("选中状态下更新"); SceneManager.Instance.addToHighLight(this.areaMesh, this.c_highLightColor); } } /** * 更新顶点 * @param index */ initMeshPoint(isNew: boolean) { let data = this.markData as MarkData_Area; if (isNew) { switch (data.type) { case MarkType.JJQ: data.pointData = this.getDefaultPoint_4(); break; case MarkType.QYSDA: data.pointData = this.getDefaultPoint_6(); break; case MarkType.QYSDB: data.pointData = this.getDefaultPoint_8(); } } else { data.pointData = plainToClass(Vector3, data.pointData); } this.areaPoint = []; for (let i = 0; i < data.pointData.length; i++) { let newPoint = new AreaPoint(data.pointData[i], this.pointMat, this); this.areaPoint.push(newPoint); } } /** * 显示顶点 * @param show */ showMeshPoint(show: boolean) { } //清空顶点 clearMeshPoint() { for (let i = 0; i < this.areaPoint.length; i++) { this.areaPoint[i].dispose(); } this.areaPoint = []; } /** * 获取默认位置,4点 * @param center */ getDefaultPoint_4() { let l_xy = this.areaSize; let result = [new Vector3(l_xy, 0, l_xy), new Vector3(l_xy, 0, -l_xy), new Vector3(-l_xy, 0, -l_xy), new Vector3(-l_xy, 0, l_xy)]; return result; } /** * 获取默认位置,6边型 * @param center */ getDefaultPoint_6() { let sin60 = Math.sin(Math.PI / 3) * this.areaSize; let sin30 = 0.5 * this.areaSize; let l_size = this.areaSize; let result = [new Vector3(0, 0, l_size), new Vector3(sin60, 0, sin30), new Vector3(sin60, 0, -sin30), new Vector3(0, 0, -l_size), new Vector3(-sin60, 0, -sin30), new Vector3(-sin60, 0, sin30)]; return result; } /** * 获取默认位置,8边形 * @param center */ getDefaultPoint_8() { let sin45 = Math.sin(Math.PI * 0.25) * this.areaSize; let l_size = this.areaSize; let result = [new Vector3(0, 0, l_size), new Vector3(sin45, 0, sin45), new Vector3(l_size, 0, 0), new Vector3(sin45, 0, -sin45), new Vector3(0, 0, -l_size), new Vector3(-sin45, 0, -sin45), new Vector3(-l_size, 0, 0), new Vector3(-sin45, 0, sin45)]; return result; } /** * 克隆 */ clone(markData?: MarkData, isNew: boolean = true): ModelInfo_mark_area { let l_markData: MarkData = null; if (markData == null) { l_markData = classToClass(this.modelData) as MarkData; } else { l_markData = markData; } let childMeshes = null; let modelBox = null; modelBox = BabylonTool.cloneMesh(this.modelBox as Mesh, null, (childMesh: AbstractMesh[]) => { childMeshes = childMesh; }); let info = new ModelInfo_mark_area(l_markData, childMeshes, modelBox, null, isNew); this.cloneAnimTo(info); return info; } dispose() { this.areaMesh.dispose(); this.material.dispose(); this.pointMat.dispose(); this.clearMeshPoint(); super.dispose(); } } /** * 区域顶点 */ export class AreaPoint { parent: ModelInfo_mark_area; mesh: Mesh; pos: Vector3; pointerDragBehavior: PointerDragBehavior;//拖拽事件 constructor(pos: Vector3, material: Material, parent: ModelInfo_mark_area) { this.pos = pos; this.parent = parent; this.mesh = MeshBuilder.CreateSphere("AreaPoint", { segments: 4, diameter: 3 }); this.mesh.material = material; this.mesh.setParent(parent.modelBox); this.mesh.position = pos; this.initDragEvent(); } initDragEvent() { let instance = this; this.pointerDragBehavior = new PointerDragBehavior({ dragPlaneNormal: Vector3.Up() }); //平面内移动 this.mesh.addBehavior(this.pointerDragBehavior); this.pointerDragBehavior.onDragStartObservable.add(() => { instance.parent.setDragEventEnable(false); }) this.pointerDragBehavior.onDragObservable.add(() => { instance.parent.refreshMesh(); setTimeout(() => { instance.parent.refreshMesh(); }, 100); }); this.pointerDragBehavior.onDragEndObservable.add(() => { instance.parent.setDragEventEnable(true); instance.parent.refreshMesh(); }) } dispose() { this.mesh.removeBehavior(this.pointerDragBehavior); this.pointerDragBehavior = null; this.mesh.dispose(); } }