You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
7.9 KiB
271 lines
7.9 KiB
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(); |
|
} |
|
|
|
} |