中化加油站项目
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.
 
 
 
 
 
 

323 lines
9.8 KiB

import { Color3, MeshBuilder, Quaternion, Space, Vector3 } from "@babylonjs/core";
import { PointerEventTypes, PointerInfo } from "@babylonjs/core/Events/pointerEvents";
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh";
import { Mesh } from "@babylonjs/core/Meshes/mesh";
import { EventState, Observer } from "@babylonjs/core/Misc/observable";
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_multiArrow } from "../../../data/mark/other/mark-data-multi-arrow";
import { ModelInfo_mark } from "../model-info-mark";
/**
* 多点的箭头
*/
export class ModelInfo_mark_multiArrow extends ModelInfo_mark {
arrowData: MarkData_multiArrow;
onPointObserver: Observer<PointerInfo>;
arrowInfo: ArrowInfo[] = [];
mat: StandardMaterial;
onCreate(isNew: boolean) {
let instance = this;
instance.arrowData = this.markData as MarkData_multiArrow;
this.mat = new StandardMaterial("mat_multiArrow", SceneManager.Instance.scene);
if (this.arrowData.color == null) {
this.mat.emissiveColor = Color3.Green();
}
else {
this.mat.emissiveColor = Color3.FromHexString(this.arrowData.color);
}
this.mat.disableLighting = true;
if (isNew) {
instance.arrowData.pointData = [];
instance.addPoint(this.modelBox.absolutePosition.clone());
setTimeout(() => {
instance.onPointObserver = SceneManager.Instance.scene.onPointerObservable.add((eventData: PointerInfo, eventState: EventState) => {
instance.onPointerObservable(eventData, eventState);
}
);
}, 300);
}
else {
instance.arrowData.pointData = plainToClass(Vector3, instance.arrowData.pointData);
instance.updateRender();
}
}
/**
* 更新显示
*/
updateRender() {
if (this.arrowData.pointData != null && this.arrowData.pointData.length > 1) {
// this.lineMesh = MeshBuilder.CreateTube("tube", { path: this.lineData.pointData, radius: this.lineData.radius, sideOrientation: Mesh.DOUBLESIDE, updatable: true }, SceneManager.Instance.scene);
// this.lineMesh.setParent(this.modelBox);
// this.lineMesh.position = Vector3.Zero();
// this.lineMesh.material = this.mat;
for (let i = 1; i < this.arrowData.pointData.length; i++) {
// let newBox = MeshBuilder.CreateBox("box", { size: 1 });
// newBox.setParent(this.modelBox);
// newBox.position = this.arrowData.pointData[i];
let lastPoint = this.arrowData.pointData[i - 1];
let point = this.arrowData.pointData[i];
let newArrow = new ArrowInfo(lastPoint, point, this.mat, this.modelBox as Mesh);
this.arrowInfo.push(newArrow);
}
}
}
/**
* 添加节点
* @param point
*/
addPoint(point: Vector3) {
let localPos = point.subtract(this.modelBox.absolutePosition);
localPos.y = localPos.y / this.modelBox.scaling.y;
console.log(point, localPos, this.modelBox.absolutePosition);
let startBox = MeshBuilder.CreateBox("start", { size: 1 });
startBox.setParent(this.modelBox);
startBox.position = localPos;
this.arrowData.pointData.push(localPos);
//更新表现
if (this.arrowData.pointData.length > 1) {
// this.updateRender();
let lastPoint = this.arrowData.pointData[this.arrowData.pointData.length - 2];
let newArrow = new ArrowInfo(lastPoint, localPos, this.mat, this.modelBox as Mesh);
this.arrowInfo.push(newArrow);
}
}
/**
* 移除事件
*/
removeEvent() {
if (this.onPointObserver != null) {
SceneManager.Instance.scene.onPointerObservable.remove(this.onPointObserver);
this.onPointObserver = null;
}
}
/**
* 取消创建
*/
cancelCreate() {
if (this.arrowData.pointData.length < 2) {
MarkWindow.instance.deleteMarkInfo(this);
}
if (this.arrowData.type == MarkType.JGLX) {
MarkWindow.instance.mulArrowIsBreak_JG = -1;
}
else if (this.arrowData.type == MarkType.CT) {
MarkWindow.instance.mulArrowIsBreak_CT = -1;
}
}
onPointerObservable(eventData: PointerInfo, eventState: EventState) {
let instance = this;
if (this.arrowData.type == MarkType.JGLX && MarkWindow.instance.mulArrowIsBreak_JG < 0) {
instance.cancelCreate();
instance.removeEvent();
return;
}
else if (this.arrowData.type == MarkType.CT && MarkWindow.instance.mulArrowIsBreak_CT < 0) {
instance.cancelCreate();
instance.removeEvent();
return;
}
switch (eventData.type) {
case PointerEventTypes.POINTERUP:
if (eventData.event.button == 0) { //左键正常
if (eventData.pickInfo.hit && !SceneManager.s_isPointerDrag) {
instance.addPoint(eventData.pickInfo.pickedPoint);
}
}
else if (eventData.event.button == 2) { //右键取消
instance.cancelCreate();
instance.removeEvent();
}
break;
}
}
onSelect(select: boolean) {
super.onSelect(select);
if (select = false) {
this.cancelCreate();
}
}
/**
* 克隆
*/
clone(markData?: MarkData, isNew: boolean = true): ModelInfo_mark {
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_multiArrow(l_markData, childMeshes, modelBox, null, isNew);
this.cloneAnimTo(info);
return info;
}
dispose() {
if (this.mat != null) {
this.mat.dispose();
}
this.removeEvent();
super.dispose();
}
}
/**
* 箭头信息
* 仅用作创建mesh,所以没有释放(mesh会跟随父节点释放)
*/
class ArrowInfo {
static s_step = 3;//箭头间隔(从头到下一个的头)
lastArrowInfo: ArrowInfo;//上一个箭头
parent: Mesh;
mesh: Mesh[] = [];
point: Vector3[];
start: Vector3;
end: Vector3;
forward: Vector3;
endlocalY: number; //局部的Y做坐标,末尾
mat: StandardMaterial;
constructor(start: Vector3, end: Vector3, mat: StandardMaterial, parent: Mesh) {
this.start = start;
this.end = end;
this.forward = end.subtract(start).normalize();
this.mat = mat;
this.parent = parent;
this.createMesh();
}
createMesh() {
//let distance = Vector3.Distance(this.start, this.end);
//console.log(distance);
let distance = Vector3.Distance(new Vector3(this.start.x, 0, this.start.z), new Vector3(this.end.x, 0, this.end.z));
let yStep = (this.start.y - this.end.y) / (distance / ArrowInfo.s_step);
let index = 0;
while (distance > ArrowInfo.s_step) {
let offset = index * ArrowInfo.s_step;
let forwardDistance = this.forward.multiplyByFloats(1, 0, 1).normalize().multiplyByFloats(offset, offset, offset);
let meshStart: Vector3 = this.start.add(forwardDistance);
let posArray = [];
posArray.push(new Vector3(0, 0, 2));
posArray.push(new Vector3(-1, 0, 1));
posArray.push(new Vector3(-0.5, 0, 1));
posArray.push(new Vector3(-0.5, 0, 0));
posArray.push(new Vector3(0.5, 0, 0));
posArray.push(new Vector3(0.5, 0, 1));
posArray.push(new Vector3(1, 0, 1));
let l_mesh = MeshBuilder.ExtrudePolygon("arrow", { shape: posArray, depth: 1, updatable: false }, SceneManager.Instance.scene);
l_mesh.material = this.mat;
l_mesh.setParent(this.parent);
this.endlocalY = (0.5) / this.parent.scaling.y - index * yStep;//0.5 - index * yStep
//l_mesh.position = new Vector3(0, (0.5 - index * yStep) / this.parent.scaling.y, 0).add(meshStart);
l_mesh.position = new Vector3(0, this.endlocalY, 0).add(meshStart);
// l_mesh.setParent(null)
// setTimeout(() => {
l_mesh.lookAt(this.end.add(this.parent.absolutePosition), undefined, undefined, undefined, Space.WORLD);
l_mesh.rotation.x = 0;
l_mesh.rotation.z = 0;
// }, (50));
// l_mesh.rotation.x = 0;
// l_mesh.rotation.z = 0;
// l_mesh.setParent(this.parent);
//l_mesh.rotationQuaternion = Quaternion.FromEulerVector(Vector3.Zero());
// let angle = Vector3.GetAngleBetweenVectors(l_mesh.forward, this.forward, Vector3.Up());
// l_mesh.rotation.y = 180 / Math.PI * angle;
this.mesh.push(l_mesh);
distance -= ArrowInfo.s_step;
index++;
}
}
}