1 var THREE = require('three');
2
3 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
4 import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
5 import Stats from 'three/examples/jsm/libs/stats.module.js';
6 import Zlib from 'three/examples/jsm/libs/inflate.module.min.js';
7
8 import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
9 import {
10 fjFacti, cdzsqFacti, sxtFacti, lightFacti, qbbfFacti, qbbmFacti, coviFacti, xfsbFacti, hztcqFacti, jjdhFacti, fsfxFacti, kzsFacti, kbxsFacti, cljcqFacti, jlmFacti,
11 hldFacti, dngqFacti, bxFacti, cdzsqFactiNo
12 } from './loadFactites.js'
13 import { getFacs, getHoles, listPartitionByHoleId } from "@/api/mainsys.js"
14 import { showPop } from './pop';
15
16
17 var container, stats, controls;
18 var camera, scene, renderer, light, labelRenderer;
19 var vueObj;
20
21
22 // 创建一个时钟对象Clock
23 //var clock = new THREE.Clock();
24
25 var groupSb = new THREE.Group();//设备模型
26 var fjArray = [];//风机模型数组
27 var fjdirection;//风机旋转方向控制变量
28
29 //var textLoader = new THREE.FontLoader();//文字加载器
30
31
32 var speedRight = null;//可变限速数值文字模型(右洞)
33 var kbxsRightSb = null;//可变限速模型(右洞)
34
35 var speedLeft = null;//可变限速数值文字模型(左洞)
36 var kbxsLeftSb = null;//可变限速模型(左洞)
37
38
39 var textM = null;//可变信息板门架式文字模型
40 var qbbmSb = null;//可变信息板门架式模型
41 var mapM = 0;//循环控制文字显示
42 var textMwidth;//纹理X坐标
43
44 var textF = null;//可变信息板F式文字模型
45 var qbbfSb = null;//可变信息板F式模型
46 var mapF = 0;//循环控制文字显示
47 var intervalF = null;
48
49
50 var ani = null;
51 var ani2 = null;
52
53 const toResize = () => {
54 renderer.setSize(container.offsetWidth, container.offsetHeight);
55 }//窗口自适应函数
56
57 var loader = new FBXLoader();
58
59 export function init(obj) {
60
61 vueObj = null;
62 vueObj = obj;
63 container = document.getElementById('info');
64 console.log('vueObj', vueObj)
65
66 camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2525000);
67
68 // camera.rotation.set( 30,0,0)
69 // 摄像机位置
70 camera.position.set(60000, 7000, 37000);
71 // camera.zoom = -3
72 controls = new OrbitControls(camera, container);
73 // 控制缩放范围
74 controls.maxDistance = 252500;
75 controls.minDistance = 0;
76 // 控制垂直旋转角度
77 controls.maxPolarAngle = 1.5
78 controls.minPolarAngle = 0.1
79
80 // controls.enablePan = false
81 // 旋转中心点
82 //controls.target.set(1000, 0, 1000);
83 controls.update();
84 //场景
85 scene = new THREE.Scene();
86 // scene.background = new THREE.Color( '#62A5F4' );
87 // scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
88
89 light = new THREE.HemisphereLight(0xffffff, 0xffffff, 1);
90 light.position.set(0, 2000, 0);
91 scene.add(light);
92
93
94 // 坐标轴工具类
95 var axesHelper = new THREE.AxesHelper(35000);
96 scene.add(axesHelper);
97
98 light = new THREE.DirectionalLight(0xffffff, 0.7);
99 light.position.set(0, 200, 100);
100 light.castShadow = true;
101 light.shadow.camera.top = 180;
102 light.shadow.camera.bottom = -100;
103 light.shadow.camera.left = -120;
104 light.shadow.camera.right = 120;
105 scene.add(light);
106 // 模拟相机视锥体的辅助对象
107 // scene.add( new THREE.CameraHelper( light.shadow.camera ) );
108
109
110 // var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
111 // grid.material.opacity = 0.2;
112 // grid.material.transparent = true;
113 // scene.add( grid );
114 renderer = new THREE.WebGLRenderer({
115 antialias: true,
116 alpha: true
117 });
118 renderer.setClearAlpha(0.2);
119 renderer.setPixelRatio(window.devicePixelRatio);
120 renderer.setSize(container.offsetWidth, container.offsetHeight);
121 renderer.shadowMap.enabled = true;
122 document.getElementById("info").appendChild(renderer.domElement);
123
124 window.addEventListener('resize', toResize)
125
126 // model
127 // var loader = new FBXLoader();
128 // 地面模型
129 loader.load('../../static/threed/隧道三车道.FBX', function (object) {
130 console.log('loader', loader)
131 object.name = "dm";
132 scene.add(object);
133
134 // console.log(object)
135
136 // object.children.forEach((item,index)=>{
137 // // if(index===7) item.translateY(10000)
138 // // if(index===8) item.translateY(10000)
139 // // if(index===9) item.translateY(10000)
140 // //if(index===15) item.translateY(10000)
141 // //if(index===15) item.translateY(10000)
142 // })
143
144 });
145
146 // function getTextCanvas(text) {
147 // var width = 512, height = 256;
148 // var canvas = document.createElement('canvas');
149 // canvas.width = width;
150 // canvas.height = height;
151 // var ctx = canvas.getContext('2d');
152 // ctx.fillStyle = '#C3C3C3';
153 // ctx.fillRect(0, 0, width, height);
154 // ctx.font = 50 + 'px " bold';
155 // ctx.fillStyle = '#2891FF';
156 // ctx.textAlign = 'center';
157 // ctx.textBaseline = 'middle';
158 // ctx.fillText(text, width / 2, height / 2);
159 // return canvas;
160 // }
161 // var geometry = new THREE.PlaneBufferGeometry(512, 256);
162 // var material = new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(getTextCanvas('我是你爸爸')) });// top
163 // var mesh = new THREE.Mesh(geometry, material);
164 // scene.add(mesh)
165 // mesh.scale.set(10, 10, 10)
166
167
168
169 // 基础设备 包含控制室 车道白线等
170 getBaseSB().then(obj => {
171 getBaseFacl(obj)
172
173 })
174
175 // window.addEventListener( 'resize', onWindowResize, false );
176
177
178 // window.addEventListener( 'mousemove', dragScence, false );
179
180 // 隧道所用设备 风机 情报板等等
181 getSB().then(obj => {
182 getFacl(obj)
183 });
184
185 container.addEventListener('mousedown', onDocumentMouseDown, false);
186 animate()
187
188 }
189
190 function animate() {
191 ani = requestAnimationFrame(animate);
192 fjRotate();
193 fontRun();
194 controls.update();
195 renderer.render(scene, camera);
196 }
197 async function getBaseSB() {
198 let kzs = await kzsFacti();
199 let bx = await bxFacti();
200 let o = { kzs, bx };
201 return o;
202 }
203 async function getSB() {
204
205 let fj = await fjFacti();
206 let cdzsq = await cdzsqFacti();
207 let sxt = await sxtFacti();
208 let light = await lightFacti();
209 let qbbf = await qbbfFacti();
210 let qbbm = await qbbmFacti();
211 let covi = await coviFacti();
212 let xfsb = await xfsbFacti();
213 let hztcq = await hztcqFacti();
214 let jjdh = await jjdhFacti();
215 let fsfx = await fsfxFacti();
216 let kbxs = await kbxsFacti();
217 let hld = await hldFacti();
218 let dngq = await dngqFacti();
219 let cljcq = await cljcqFacti();
220 let jlm = await jlmFacti();
221 let o = { fj, cdzsq, sxt, light, qbbf, qbbm, covi, xfsb, hztcq, jjdh, fsfx, hld, dngq, kbxs, cljcq, jlm };
222 return o;
223 }
224
225 function onDocumentMouseDown(event) {
226
227 event.preventDefault();
228 var mainCanvas = event.path[0];
229
230 if (scene) {
231
232 // 清空当前弹框
233
234 clearLabel();
235 var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2();
236
237
238 mouse.x = ((event.clientX - mainCanvas.getBoundingClientRect().left) / mainCanvas.offsetWidth) * 2 - 1;
239 mouse.y = - ((event.clientY - mainCanvas.getBoundingClientRect().top) / mainCanvas.offsetHeight) * 2 + 1;
240
241
242
243 raycaster.setFromCamera(mouse, camera); // 计算物体和射线的焦点
244 //console.log("mouse--",mouse)
245 var intersects = raycaster.intersectObjects(scene.children, true);
246 //console.log("点击后相交的物体位置", intersects[0].point.x, intersects[0].point.y, intersects[0].point.z)
247
248 // 递归找到点击的是属于该点击处的模型名称
249 var str = [];
250 if (intersects.length > 0) {
251 console.log('3d坐标----------》》》》》》》》》》', intersects[0].point)
252 for (var i = 0; i < intersects.length; i++) {
253
254 // 递归找到点击的是属于该点击处的模型
255 findMesh(intersects[i].object, str);
256
257 }
258
259 //console.log("模型",str)
260 let num = true;
261 for (var item of str) {
262 let name = item.name
263 if (num === false) return;
264 //开启点击弹窗的模型
265 let array = ["fj", "cdzsq", "sxt", "qbbm", "qbbf", "covi", "xfsb", "hztcq", "hld", "dngq", "fsfx", "jjdh", "sxt", "kbxs", "cljcq", "jlm"]
266 if (array.indexOf(name) !== -1) {
267 num = false;
268 console.log("点击得到的数据》》》》》》》", item)
269 showMsg(item, item.userData)
270
271 }
272 }
273 }
274
275 }
276
277
278 }
279
280 // 递归找到点击的模型下所有的材质
281 function findMesh(obj, str) {
282 if (obj.parent != null) {
283 findMesh(obj.parent, str);
284 return str.push(obj.parent)
285 }
286
287 }
288
289 // 加载弹框信息
290 /*
291 加载弹框信息
292 params obj 点击的3d对象,o是该设备信息
293 */
294 function showMsg(obj, o) {
295
296 clearLabel();
297
298 var earthDiv = document.createElement('div');
299
300 //生成不同的弹框
301 showPop(earthDiv, o, function (newState) {
302 clearLabel();
303 if (!newState) return;
304 var oldState = o.defaultCommandStatus;
305 o.defaultCommandStatus = newState;
306 cdzsqChangeState(obj);
307 hldChangeState(obj);
308 jlmChangeState(obj)
309 }, vueObj)
310 // earthDiv.style.marginTop = '-1em';
311 var earthLabel = new CSS2DObject(earthDiv);
312 earthLabel.name = "label";
313 // earthLabel.position.set(0, obj.position.y + 10, 0);
314 obj.add(earthLabel);
315 labelRender();
316
317 }
318 function labelRender() {
319
320 if (labelRenderer) {
321
322 // new CSS2DRenderer().dispatchEvent("removed")
323
324 // 确保3D相关对象已销毁
325 cancelAnimationFrame(ani2) // 可以取消动画
326
327 if (document.getElementsByClassName("label").length > 0) {
328 document.getElementsByClassName("label")[0].parentNode.removeChild(document.getElementsByClassName("label")[0])
329 //console.log("document.getElementsByClassName--------",document.getElementsByClassName("label")[0])
330
331 }
332 }
333 labelRenderer = new CSS2DRenderer();
334 labelRenderer.setSize(container.offsetWidth, container.offsetHeight);
335 labelRenderer.domElement.style.position = 'absolute';
336 labelRenderer.domElement.style.top = '180px';
337 labelRenderer.domElement.className = "labelRenderer";
338 document.getElementById("info").appendChild(labelRenderer.domElement);
339
340
341 // var controls = new OrbitControls( camera ,labelRenderer.domElement);
342 // // 控制缩放范围
343 // controls.maxDistance= 252500;
344 // controls.minDistance = 0;
345 // // 控制垂直旋转角度
346 // controls.maxPolarAngle =1.5
347 // controls.minPolarAngle = 0.1
348
349 // controls.enablePan = false
350 // 旋转中心点
351 // controls.target.set( 1000, 0, 1000 );
352 // controls.update();
353 animate2();
354 }
355 function animate2() {
356 ani2 = requestAnimationFrame(animate2);
357 if (renderer) {
358 renderer.render(scene, camera);
359 labelRenderer.render(scene, camera);
360 }
361 }
362
363
364 export function clearScene() {
365
366 // // 这是清空
367 // if (scene) {
368 // clearLabel();//清空对应的2d
369 // for (let i = 0; i < scene.children.length; i++) {
370 // // 清空设备层
371 // for (let item of scene.children) {
372 // scene.remove(item);
373 // }
374 // }
375 // for (let item of scene.children) {
376 // if (item.name == "sb") {
377 // scene.remove(item);
378 // }
379 // }
380
381 // }
382
383 if (container.childNodes[0]) {
384 container.removeChild(container.childNodes[0])
385 }
386 // scene.dispose();
387 // if (renderer) {
388 // renderer.dispose();
389 // }
390 // cancelAnimationFrame(ani)
391
392 function dispose(parent, child) {
393 if (child.children.length) {
394 let arr = child.children.filter(x => x);
395 arr.forEach(a => {
396 dispose(child, a)
397 })
398 }
399 if (child instanceof THREE.Mesh) {
400 // console.log('item', child)
401 if (Array.isArray(child.material) && child.material.length > 0) {
402 child.material.forEach(item => {
403 if (item.map) item.map.dispose();
404 item.dispose();
405 })
406 }
407 else {
408 if (child.material.map) child.material.map.dispose();
409 child.material.dispose();
410 }
411 child.geometry.dispose();
412 } else if (child.material) {
413 child.material.dispose();
414 }
415 child.remove();
416 parent.remove(child);
417 }
418
419 let arr = scene.children.filter(x => x)
420 arr.forEach(a => {
421 dispose(scene, a);
422 })
423
424
425
426 window.removeEventListener("resize", toResize);
427
428 scene.dispose();
429 if (renderer) {
430 console.log('查看memery字段即可', renderer.info) //查看memery字段即可
431 renderer.renderLists.dispose();
432 renderer.dispose();
433 renderer.forceContextLoss();
434 renderer.domElement = null;
435 renderer.content = null;
436 renderer = null;
437 }
438 cancelAnimationFrame(ani);
439 cancelAnimationFrame(ani)
440 THREE.Cache.clear();
441 }
442
443 function clearLabel() {
444
445
446 let ll = scene.getObjectByName("label");
447 if (ll) {
448 ll.parent.remove(ll)
449 }
450 if (document.getElementsByClassName("labelRenderer").length > 0) {
451 document.getElementsByClassName("labelRenderer")[0].parentNode.removeChild(document.getElementsByClassName("labelRenderer")[0])
452
453 }
454 let ll2 = scene.getObjectByName("labelRenderer");
455 //console.log("ll2.domElement------------",ll2)
456 if (ll2) {
457 //console.log("ll2.domElement------------222",ll2.domElement)
458 ll2.domElement.parent.remove(ll2.domElement)
459 ll2.parent.remove(ll2)
460 ll2.dispose();
461
462 }
463 }
464
465
466 export function addModel(obj) {
467 clearScene();
468 init(obj);
469 console.log(THREE.Cache)
470 }
471
472 function getBaseFacl(obj) {
473 var group = new THREE.Group();
474 group.name = "basesb";
475 let sb = {};
476 // 控制室模型
477 // let kzsPos = [{ x: 15408, y: -2236, z: 15000 }];
478 // obj.kzs.userData = { id: "id_kzs" }
479 // let kzs = obj.kzs.clone();
480 // kzs.rotateY(Math.PI);
481 // kzs.position.copy(new THREE.Vector3(kzsPos[0].x, kzsPos[0].y, kzsPos[0].z))
482 // group.add(kzs)
483 // let kzsPos1 = [{ x: 28080, y: -1500, z: -15757 }];
484 // obj.kzs.userData = { id: "id_kzs" }
485 // let kzs1 = obj.kzs.clone();
486 // kzs1.rotateY(Math.PI);
487 // kzs1.position.copy(new THREE.Vector3(kzsPos1[0].x, kzsPos1[0].y, kzsPos1[0].z))
488 // group.add(kzs1)
489 // let kzsPos2 = [{ x: -21202, y: -2085, z: -15757 }];
490 // obj.kzs.userData = { id: "id_kzs" }
491 // let kzs2 = obj.kzs.clone();
492 // // kzs2.rotateY(Math.PI);
493 // kzs2.position.copy(new THREE.Vector3(kzsPos2[0].x, kzsPos2[0].y, kzsPos2[0].z))
494 // group.add(kzs2)
495 let kzsPos3 = [{ x: -29000, y: 1250, z: 22000 }];
496 obj.kzs.userData = { id: "id_kzs" }
497 let kzs3 = obj.kzs.clone();
498 kzs3.position.copy(new THREE.Vector3(kzsPos3[0].x, kzsPos3[0].y, kzsPos3[0].z))
499 kzs3.scale.set(1.2, 1.2, 1.2);
500 group.add(kzs3)
501
502
503 scene.add(group);
504 }
505 function getFacl(obj) {
506
507 // var array = ['fj', 'cdzsq', 'sxt', 'qbbm', 'qbbf', 'covi', 'hztcq', 'kbxs', 'jjdh', 'light']//普瑞不需要加载的模型:xfsb,hld
508 // for (let key in obj) {
509 // obj[key].visible = array.indexOf(obj[key].name) === -1 ? false : true;
510 // }
511
512
513
514 let tunnerid = vueObj.$store.getters.tunnerid;
515 let arr = ["?tunnelId=" + tunnerid];
516
517 getFacs(arr.join('')).then(async response => {
518 let { code, value } = response.data;
519 console.log('全部设备信息', value)
520 // 单洞信息
521 await getHoles(tunnerid).then(response => {
522 let { code, value } = response.data;
523 if (value && value.length > 0) {
524
525
526 value.forEach(item => {
527
528 if (item.direction == 'left') {
529
530 vueObj.hole_1 = item;
531
532 } else if (item.direction == 'right') {
533
534 vueObj.hole_2 = item;
535
536 } else {
537 return;
538 }
539 })
540 }
541
542 });
543 // 取得分区数据
544 var sorted = groupBy(value, function (item) {
545 return [item.holeId];
546 });
547 if (sorted.length > 0) {
548
549 vueObj.hole_1_list = vueObj.hole_1.id == sorted[0][0].holeId ? sorted[0] : sorted[1];//左洞设备信息
550 vueObj.hole_2_list = vueObj.hole_2.id == sorted[0][0].holeId ? sorted[0] : sorted[1];//右洞设备信息
551
552 } else {
553 vueObj.hole_1_list = [];
554 vueObj.hole_2_list = [];
555 }
556 var hole_1_type = groupBy(vueObj.hole_1_list, function (item) {
557 return [item.classifyCode];
558 });
559 var hole_2_type = groupBy(vueObj.hole_2_list, function (item) {
560 return [item.classifyCode];
561 });
562 // 转换为子数组
563 toSonArr(hole_1_type, 1)
564 toSonArr(hole_2_type, 2)
565
566 var group = groupSb;
567 group.name = "sb";
568 let sb = {};
569
570
571 // 左洞的比例
572 let left_bl = 86000 / vueObj.hole_1.finishPosition;
573 let right_bl = 86000 / vueObj.hole_2.finishPosition;
574
575
576
577 let lightPos = [{ x: -30000, y: 4400, z: -12800 }, { x: -30000, y: 4400, z: -4150 }, { x: -30000, y: 4400, z: 4150 }, { x: -30000, y: 4400, z: 12800 }];//灯
578 for (let i = 0; i < 12; i++) {
579 // 加上设备信息
580 obj.light.userData = { id: "id_light_right1" + i }
581 let sb = obj.light.clone();
582 // sb.rotateY(40);
583 sb.rotateX(-Math.PI / 2);
584 sb.position.copy(new THREE.Vector3(lightPos[0].x + 5200 * i, lightPos[0].y, lightPos[0].z))
585 if (i >= 10) {
586 sb.position.copy(new THREE.Vector3(lightPos[0].x + 5200 * i + 1500, lightPos[0].y, lightPos[0].z - 3700))
587 }
588 group.add(sb)
589 }
590 for (let i = 0; i < 12; i++) {
591 // 加上设备信息
592 obj.light.userData = { id: "id_light_right2" + i }
593 let sb = obj.light.clone();
594 sb.position.copy(new THREE.Vector3(lightPos[1].x + 5200 * i, lightPos[1].y, lightPos[1].z))
595 if (i >= 10) {
596 sb.position.copy(new THREE.Vector3(lightPos[1].x + 5200 * i + 1500, lightPos[1].y, lightPos[1].z))
597 }
598 group.add(sb)
599 }
600 for (let i = 0; i < 12; i++) {
601 // 加上设备信息
602 obj.light.userData = { id: "id_light_left1" + i }
603 let sb = obj.light.clone();
604 sb.rotateX(-Math.PI / 2);
605 sb.position.copy(new THREE.Vector3(lightPos[2].x + 5200 * i, lightPos[2].y, lightPos[2].z))
606 if (i >= 10) {
607 sb.position.copy(new THREE.Vector3(lightPos[2].x + 5200 * i + 1500, lightPos[2].y, lightPos[2].z))
608 }
609 group.add(sb)
610 }
611 for (let i = 0; i < 12; i++) {
612 // 加上设备信息
613 obj.light.userData = { id: "id_light_left2" + i }
614 let sb = obj.light.clone();
615 sb.position.copy(new THREE.Vector3(lightPos[3].x + 5200 * i, lightPos[3].y, lightPos[3].z))
616 if (i >= 10) {
617 sb.position.copy(new THREE.Vector3(lightPos[3].x + 5200 * i + 1500, lightPos[3].y, lightPos[3].z + 3700))
618 }
619 group.add(sb)
620 }
621
622
623
624 let vd = vueObj.$data
625 let keysArr = Object.keys(vd)
626 //console.log('vueObj:-------',vueObj.$data)
627
628 keysArr.forEach(item => {
629 // console.log(item,item.indexOf('_',item.length - 2))
630 if (Array.isArray(vd[item]) && item.indexOf('_', item.length - 2) > 0) {
631 //console.log('item,vd[item]',item,vd[item])
632 localSb(vd[item], obj, left_bl, right_bl, group)
633
634 }
635 })
636 scene.add(group);
637
638 })
639 }
640 // 设备定位
641 async function localSb(list, obj, left_bl, right_bl, group) {
642
643 let sdLeftStartPosition = -42600;
644 let sdRightStartPosition = -42600;
645 if (list.length > 0) {
646
647 for (let i = 0; i < list.length; i++) {
648 console.log(list[i].name, list[i].typeCode, list[i])
649 let { typeCode } = list[i]
650 let param, posLeft, posRight, rotx = 0, roty = 0
651 switch (typeCode) {
652 case 'TrafficLights':
653 param = 'hld';
654 // 加上设备信息
655 obj[param].userData = list[i]
656 var d = list[i]
657 var sb = obj[param].clone();
658 var x, y, z;
659 if (d.direction == 'right') {
660 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 7000
661 y = 3800
662 z = 13400
663 roty = Math.PI
664 } else {
665 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 7000
666 y = 3800
667 z = -16700
668 }
669 sb.children[0].children[4].children[0].visible = false;//绿灯
670 sb.children[0].children[4].children[1].visible = true;//绿灯灰色
671 sb.children[0].children[5].children[1].visible = false;//黄灯
672 sb.children[0].children[5].children[2].visible = true;//黄灯灰色
673 sb.children[0].children[6].children[1].visible = false;//红灯
674 sb.children[0].children[6].children[2].visible = true;//红灯灰色
675 sb.children[0].children[7].children[2].visible = false;//箭头
676 sb.children[0].children[7].children[1].visible = true;//箭头灰色
677 sb.children[0].children[7].children[3].visible = false;//清楚箭头边缘绿色
678 sb.position.copy(new THREE.Vector3(x, y, z))
679 sb.rotateY(roty)
680 //sb.scale.set(1)
681 group.add(sb);
682 hldChangeState(sb);
683 break;
684 case 'Camera':
685 param = 'sxt'
686 // 加上设备信息
687 obj[param].userData = list[i]
688 var d = list[i]
689 var sb = obj[param].clone();
690 var x, y, z;
691 if (d.direction == 'right') {
692 rotx = Math.PI / 2
693 roty = Math.PI
694 } else {
695 rotx = Math.PI / 2
696 }
697 x = right_bl * Math.abs(list[i].position) + sdLeftStartPosition;
698 var direction = d.direction === 'right' ? 1 : -1;
699 y = 4000;
700 z = d.laneNum === 4 ? direction * 16700 : direction * 13200;
701 sb.position.copy(new THREE.Vector3(x, y, z))
702 sb.rotateY(roty)
703 sb.rotateX(rotx)
704 group.add(sb)
705 break;
706 case 'CoViDetector':
707 param = 'covi'
708 // 加上设备信息
709 obj[param].userData = list[i]
710 var d = list[i]
711 var sb = obj[param].clone();
712 var x, y, z;
713 if (d.direction == 'right') {
714 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
715 y = 3500
716 z = 13580
717 } else {
718 x = right_bl * Math.abs(list[i].position) + sdLeftStartPosition
719 y = 3500
720 z = -13750
721 }
722 sb.position.copy(new THREE.Vector3(x, y, z))
723 sb.scale.set(10, 10, 10);
724 group.add(sb)
725 break;
726 case 'FireFightingPump':
727 param = 'xfsb'
728 // 加上设备信息
729 obj[param].userData = list[i]
730 var d = list[i]
731 var sb = obj[param].clone();
732 var x, y, z;
733 if (d.direction == 'right') {
734 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
735 y = -2000
736 z = 14700
737 //roty = Math.PI
738 } else {
739 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition
740 y = -2000
741 z = -14700
742 }
743 sb.position.copy(new THREE.Vector3(x, y, z))
744 sb.rotateY(roty)
745 group.add(sb)
746 break;
747 case 'FireDetector':
748 param = 'hztcq'
749 // 加上设备信息
750 obj[param].userData = list[i]
751 var d = list[i]
752 var sb = obj[param].clone();
753 var x, y, z;
754 if (d.direction == 'right') {
755 y = 1500
756 z = d.position >= 645 ? 17700 : 14400;
757 roty = Math.PI
758 } else {
759 y = 1500
760 z = d.position >= 645 ? -17700 : -14400;
761 }
762 x = d.position >= 645 ? left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 1000 : left_bl * Math.abs(list[i].position) + sdLeftStartPosition;
763 sb.position.copy(new THREE.Vector3(x, y, z))
764 sb.rotateY(roty)
765 group.add(sb)
766 break;
767 case 'EmergencyCallBroadCast':
768 param = 'jjdh'
769 // 加上设备信息
770 obj[param].userData = list[i]
771 var d = list[i]
772 var sb = obj[param].clone();
773 var x, y, z;
774 if (d.direction == 'right') {
775 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
776 y = -600
777 z = 10250
778 roty = Math.PI
779 } else {
780 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition
781 y = -600
782 z = -10250
783 }
784 sb.position.copy(new THREE.Vector3(x, y, z))
785 sb.rotateY(roty)
786 group.add(sb)
787 break;
788 case 'WindSpeedDetector':
789 param = 'fsfx'
790 // 加上设备信息
791 obj[param].userData = list[i]
792 var d = list[i]
793 var sb = obj[param].clone();
794 var x, y, z;
795 if (d.direction == 'right') {
796 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
797 y = 3500
798 z = 13600
799 rotx = -Math.PI / 2
800 } else {
801 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition
802 y = 3500
803 z = -13600
804 rotx = Math.PI / 2
805 }
806 sb.position.copy(new THREE.Vector3(x, y, z))
807 sb.rotateX(rotx)
808 group.add(sb)
809 break;
810 case 'JetFans':
811 param = 'fj'
812 // 加上设备信息
813 obj[param].userData = list[i]
814 var d = list[i]
815 var sb = obj[param].clone();
816 var x, y, z;
817 x = right_bl * Math.abs(list[i].position) + sdLeftStartPosition;
818 var direction = d.direction === 'right' ? 1 : -1;
819 switch (d.laneNum) {
820 case 1:
821 y = 5000;
822 z = 5000 * direction;
823 break;
824 case 2:
825 y = 5900;
826 z = 8500 * direction;
827 break;
828 case 3:
829 y = 5000;
830 z = 12000 * direction;
831 break;
832
833 }
834 sb.position.copy(new THREE.Vector3(x, y, z))
835 group.add(sb)
836 fjArray.push(sb)
837 break;
838 case 'LaneLights':
839 param = 'cdzsq'
840 // 加上设备信息
841 obj[param].userData = list[i]
842 var d = list[i]
843 var sb = obj[param].clone();
844 var x, y, z;
845 x = right_bl * Math.abs(list[i].position) + sdLeftStartPosition;
846 y = 5300;
847 var direction = d.direction === 'right' ? 1 : -1;
848 switch (d.laneNum) {
849 case 1:
850 z = 5000 * direction;
851 break;
852 case 2:
853 z = 8500 * direction;
854 break;
855 case 3:
856 z = 12000 * direction;
857 break;
858 }
859 sb.position.copy(new THREE.Vector3(x, y, z))
860 group.add(sb)
861 cdzsqChangeState(sb)
862 break;
863 case 'PRFlexMessageBroadFType':
864 param = 'qbbf'
865 // 加上设备信息
866 obj[param].userData = list[i]
867 var d = list[i]
868 var sb = obj[param].clone();
869 var x, y, z;
870 if (d.direction == 'right') {
871 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 2000
872 y = 2400
873 z = 13400
874 } else {
875 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 2000
876 y = 2400
877 z = -16500
878 roty = Math.PI
879 }
880 sb.position.copy(new THREE.Vector3(x, y, z))
881 sb.rotateY(roty)
882 sb.scale.set(1, 1.2, 1.2)
883 group.add(sb)
884 var textContent = d.displayContent ? d.displayContent : '暂无内容';
885 qbbfSb = sb
886 qbbfChangeState(textContent);
887 break;
888 case 'PRFlexMessageBroad':
889 param = 'qbbm'
890 // 加上设备信息
891 obj[param].userData = list[i]
892 var d = list[i]
893 var sb = obj[param].clone();
894 var x, y, z;
895 if (d.direction == 'right') {
896 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 2000
897 y = 2250
898 z = 8400
899 roty = Math.PI
900 } else {
901 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 2000
902 y = 2250
903 z = -5900
904 }
905 sb.position.copy(new THREE.Vector3(x, y, z))
906 sb.rotateY(roty)
907 sb.scale.set(0.3, 0.8, 1.05);
908 group.add(sb)
909 var textContent = d.displayContent ? d.displayContent : '暂无内容';
910 qbbmSb = sb
911 qbbmChangeState(textContent);
912 break;
913 case 'PRFlexSpeedBroad':
914 param = 'kbxs'
915 // 加上设备信息
916 obj[param].userData = list[i]
917 var d = list[i]
918 var sb = obj[param].clone();
919 var x, y, z;
920
921 if (d.direction == 'right') {
922 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 10000
923 y = 1700
924 z = 2500
925 roty = Math.PI
926 } else {
927 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 10000
928 y = 1700
929 z = -2500
930 }
931 sb.position.copy(new THREE.Vector3(x, y, z));
932 sb.rotateY(roty)
933 group.add(sb)
934 var number = d.displaySpeed ? d.displaySpeed : 0;
935 if (d.direction == 'right') {
936 kbxsRightSb = sb
937 }
938 else {
939 kbxsLeftSb = sb
940 }
941 kbxsChangeState(number, d.direction);
942 break;
943
944 case 'FlexMessageBroadFType':
945 param = 'qbbf'
946 // 加上设备信息
947 obj[param].userData = list[i]
948 var d = list[i]
949 var sb = obj[param].clone();
950 var x, y, z;
951 if (d.direction == 'right') {
952 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 2000
953 y = 2400
954 z = 13400
955 } else {
956 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 2000
957 y = 2400
958 z = -16500
959 roty = Math.PI
960 }
961 sb.position.copy(new THREE.Vector3(x, y, z))
962 sb.rotateY(roty)
963 sb.scale.set(1, 1.2, 1.2)
964 group.add(sb)
965 var textContent = d.displayContent ? d.displayContent : '暂无内容';
966 qbbfSb = sb
967 qbbfChangeState(textContent);
968 break;
969 case 'FlexMessageBroadPortalType':
970 param = 'qbbm'
971 // 加上设备信息
972 obj[param].userData = list[i]
973 var d = list[i]
974 var sb = obj[param].clone();
975 var x, y, z;
976 if (d.direction == 'right') {
977 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 2000
978 y = 2250
979 z = 8400
980 roty = Math.PI
981 } else {
982 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 2000
983 y = 2250
984 z = -5900
985 }
986 sb.position.copy(new THREE.Vector3(x, y, z))
987 sb.rotateY(roty)
988 sb.scale.set(0.3, 0.8, 1.05);
989 group.add(sb)
990 var textContent = d.displayContent ? d.displayContent : '暂无内容';
991 qbbmSb = sb
992 qbbmChangeState(textContent);
993 break;
994 case 'FlexSpeedBroad':
995 param = 'kbxs'
996 // 加上设备信息
997 obj[param].userData = list[i]
998 var d = list[i]
999 var sb = obj[param].clone();
1000 var x, y, z;
1001
1002 if (d.direction == 'right') {
1003 x = right_bl * Math.abs(list[i].position) + sdRightStartPosition - 10000
1004 y = 1700
1005 z = 2500
1006 roty = Math.PI
1007 } else {
1008 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition + 10000
1009 y = 1700
1010 z = -2500
1011 }
1012 sb.position.copy(new THREE.Vector3(x, y, z));
1013 sb.rotateY(roty)
1014 group.add(sb)
1015 var number = d.displaySpeed ? d.displaySpeed : 0;
1016 if (d.direction == 'right') {
1017 kbxsRightSb = sb
1018 }
1019 else {
1020 kbxsLeftSb = sb
1021 }
1022 kbxsChangeState(number, d.direction);
1023 break;
1024 case 'PREmergencyCall':
1025 param = 'jjdh'
1026 // 加上设备信息
1027 obj[param].userData = list[i]
1028 var d = list[i]
1029 var sb = obj[param].clone();
1030 var x, y, z;
1031 if (d.direction == 'right') {
1032 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
1033 y = 1800
1034 z = 14410
1035 roty = Math.PI
1036 } else {
1037 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition
1038 y = 1800
1039 z = -14410
1040 }
1041 if (d.position >= 610) {
1042 z = d.direction == 'right' ? 17820 : -17820;
1043 }
1044 sb.position.copy(new THREE.Vector3(x, y, z))
1045 sb.rotateY(roty)
1046 group.add(sb)
1047 break;
1048
1049 case 'VehicleDetector':
1050 param = 'cljcq'
1051 // 加上设备信息
1052 obj[param].userData = list[i]
1053 var d = list[i]
1054 var sb = obj[param].clone();
1055 var x, y, z;
1056 if (d.direction == 'right') {
1057 x = left_bl * Math.abs(list[i].position) + sdRightStartPosition
1058 y = -2450
1059 z = 7300
1060 roty = -Math.PI / 2
1061 } else {
1062 x = left_bl * Math.abs(list[i].position) + sdLeftStartPosition
1063 y = -2450
1064 z = -7300
1065 roty = Math.PI / 2
1066 }
1067 sb.position.copy(new THREE.Vector3(x, y, z))
1068 sb.rotateY(roty)
1069 //sb.scale.set(10,10,10)
1070 group.add(sb)
1071 break;
1072 case 'FireFightingDoor':
1073 param = 'jlm'
1074 // 加上设备信息
1075 obj[param].userData = list[i]
1076 var sb = obj[param].clone();
1077 var x = 0;
1078 var y = -100;
1079 var z = 0;
1080 sb.position.copy(new THREE.Vector3(x, y, z))
1081 group.add(sb)
1082 jlmChangeState(sb);
1083 break;
1084 }
1085 }
1086 }
1087
1088 }
1089
1090 function groupBy(array, f) {
1091 if (array == undefined) {
1092 return []
1093 }
1094 var groups = {};
1095 array.forEach(function (o) {
1096 var group = JSON.stringify(f(o));
1097 groups[group] = groups[group] || [];
1098 groups[group].push(o);
1099 });
1100 // console.log('groups',groups)
1101 return Object.keys(groups).map(function (group) {
1102 return groups[group];
1103 });
1104 }
1105 function toSonArr(arr, i) {
1106 arr.forEach(function (o) {
1107 switch (o[0].classifyCode) {
1108 case '1':
1109 vueObj.$data['ventilationList_' + i] = o;
1110 // 氮氧化物检测器...
1111 break;
1112 case '2':
1113 vueObj.$data['lightList_' + i] = o;
1114 // 照明集中控制器...
1115 break;
1116 case '3':
1117 vueObj.$data['videomoniList_' + i] = o;
1118 // 摄像头...
1119 break;
1120 case '4':
1121 vueObj.$data['msgdeliverList_' + i] = o;
1122 // 紧急电话广播...
1123 break;
1124 case '5':
1125 vueObj.$data['firecontrolList_' + i] = o;
1126 // 消防水泵...
1127 break;
1128 case '6':
1129 vueObj.$data['traficcontrolList_' + i] = o;
1130 // 车道指示器...
1131 break;
1132 case '7':
1133 vueObj.$data['trafguideList_' + i] = o;
1134 console.log('7:', o[0].name)
1135 break;
1136 case '8':
1137 vueObj.$data['powerMoni_' + i] = o;
1138 // 电力监测仪表...
1139 break;
1140 default:
1141 //text = 'List';
1142 }
1143 })
1144
1145 }
1146
1147 //动态化风机 //旋转方向
1148 function fjRotate() {
1149 if (fjArray.length === 0) return;
1150 fjArray.forEach(item => {
1151 fjdirection = item.userData.direction === 'right' ? -1 : 1;
1152 switch (item.userData.defaultCommandStatus) {
1153 case '1'://正转
1154 item.children[2].children[2].children[1].rotateX(fjdirection * Math.PI / 6);
1155 item.children[2].children[2].children[2].rotateX(fjdirection * Math.PI / 6);
1156 break;
1157 case '2'://反转
1158 item.children[2].children[2].children[1].rotateX(fjdirection * -Math.PI / 6);
1159 item.children[2].children[2].children[2].rotateX(fjdirection * -Math.PI / 6);
1160 break;
1161 default:
1162 break;
1163 }
1164 })
1165 }
1166
1167 //车道指示器动态化
1168 async function cdzsqChangeState(obj) {
1169 if (obj.userData.typeCode !== 'LaneLights') return;
1170 groupSb.remove(obj);
1171
1172 var newobj = null;
1173 switch (obj.userData.defaultCommandStatus) {
1174 case '10':
1175 //禁止通行状态
1176 newobj = await cdzsqFactiNo();
1177 newobj.userData = obj.userData;
1178 newobj.position.copy(obj.position);
1179 break;
1180 case '6':
1181 //反向状态
1182 newobj = await cdzsqFacti();
1183 newobj.scale.set(10, 10, 10);
1184 newobj.userData = obj.userData;
1185 newobj.position.copy(obj.position);
1186 newobj.children[2].children[2].visible = true;
1187 newobj.children[2].children[4].visible = true;
1188 newobj.children[2].children[6].visible = true;
1189 break;
1190 case '9':
1191 //正向状态
1192 newobj = await cdzsqFacti();
1193 newobj.scale.set(10, 10, 10);
1194 newobj.rotateY(Math.PI)
1195 newobj.userData = obj.userData;
1196 newobj.position.copy(obj.position);
1197 newobj.children[2].children[2].visible = true;
1198 newobj.children[2].children[4].visible = true;
1199 newobj.children[2].children[6].visible = true;
1200 break;
1201 default://默认关闭状态
1202 newobj = await cdzsqFacti();
1203 newobj.scale.set(10, 10, 10);
1204 newobj.userData = obj.userData;
1205 newobj.position.copy(obj.position);
1206 newobj.children[2].children[2].visible = false;
1207 newobj.children[2].children[4].visible = false;
1208 newobj.children[2].children[6].visible = false;
1209 break;
1210 }
1211 if (newobj.userData.direction === 'left') newobj.rotateY(Math.PI)
1212 groupSb.add(newobj)
1213 //设置默认状态
1214 newobj.children[2].children[9].visible = false;
1215 newobj.children[2].children[10] && (newobj.children[2].children[10].visible = false);
1216
1217 }
1218
1219 //红绿灯动态化
1220 function hldChangeState(obj) {
1221 if (obj.userData.typeCode !== 'TrafficLights') return;
1222 switch (obj.userData.defaultCommandStatus) {
1223 case '1':
1224 //红灯状态
1225 obj.children[0].children[4].children[0].visible = false;//绿灯
1226 obj.children[0].children[4].children[1].visible = true;//绿灯灰色
1227 obj.children[0].children[5].children[1].visible = false;//黄灯
1228 obj.children[0].children[5].children[2].visible = true;//黄灯灰色
1229 obj.children[0].children[6].children[1].visible = true;//红灯
1230 obj.children[0].children[6].children[2].visible = false;//红灯灰色
1231 obj.children[0].children[7].children[2].visible = false;//箭头
1232 obj.children[0].children[7].children[1].visible = true;//箭头灰色
1233 break;
1234 case '2':
1235 //黄灯状态
1236 obj.children[0].children[4].children[0].visible = false;//绿灯
1237 obj.children[0].children[4].children[1].visible = true;//绿灯灰色
1238 obj.children[0].children[5].children[1].visible = true;//黄灯
1239 obj.children[0].children[5].children[2].visible = false;//黄灯灰色
1240 obj.children[0].children[6].children[1].visible = false;//红灯
1241 obj.children[0].children[6].children[2].visible = true;//红灯灰色
1242 obj.children[0].children[7].children[2].visible = false;//箭头
1243 obj.children[0].children[7].children[1].visible = true;//箭头灰色
1244 break;
1245 case '4':
1246 //绿灯状态
1247 obj.children[0].children[4].children[0].visible = true;//绿灯
1248 obj.children[0].children[4].children[1].visible = false;//绿灯灰色
1249 obj.children[0].children[5].children[1].visible = false;//黄灯
1250 obj.children[0].children[5].children[2].visible = true;//黄灯灰色
1251 obj.children[0].children[6].children[1].visible = false;//红灯
1252 obj.children[0].children[6].children[2].visible = true;//红灯灰色
1253 obj.children[0].children[7].children[2].visible = false;//箭头
1254 obj.children[0].children[7].children[1].visible = true;//箭头灰色
1255 break;
1256 case '8':
1257 //左转状态
1258 obj.children[0].children[4].children[0].visible = false;//绿灯
1259 obj.children[0].children[4].children[1].visible = true;//绿灯灰色
1260 obj.children[0].children[5].children[1].visible = false;//黄灯
1261 obj.children[0].children[5].children[2].visible = true;//黄灯灰色
1262 obj.children[0].children[6].children[1].visible = false;//红灯
1263 obj.children[0].children[6].children[2].visible = true;//红灯灰色
1264 obj.children[0].children[7].children[2].visible = true;//箭头
1265 obj.children[0].children[7].children[1].visible = false;//箭头灰色
1266 break;
1267 default://默认停止状态 '0'
1268 obj.children[0].children[4].children[0].visible = false;//绿灯
1269 obj.children[0].children[4].children[1].visible = true;//绿灯灰色
1270 obj.children[0].children[5].children[1].visible = false;//黄灯
1271 obj.children[0].children[5].children[2].visible = true;//黄灯灰色
1272 obj.children[0].children[6].children[1].visible = false;//红灯
1273 obj.children[0].children[6].children[2].visible = true;//红灯灰色
1274 obj.children[0].children[7].children[2].visible = false;//箭头
1275 obj.children[0].children[7].children[1].visible = true;//箭头灰色
1276 break;
1277 }
1278 }
1279
1280 // //可变限速数值动态化
1281 // export function kbxsChangeState(number,direction) {
1282 // number = String(number)
1283 // var speed=direction==='right'?speedRight:speedLeft;
1284 // var kbxsSb=direction==='right'?kbxsRightSb:kbxsLeftSb;
1285 // if (speed) {
1286 // speed.geometry.dispose();
1287 // speed.material.dispose();
1288 // kbxsSb.remove(speed);
1289 // }
1290 // textLoader.load('three/examples/fonts/gentilis_regular.typeface.json', function (font) {
1291 // var geometry = new THREE.TextGeometry(number, {
1292 // font: font,
1293 // size: 250,
1294 // height: 5,
1295 // curveSegments: 12,
1296 // bevelEnabled: true,
1297 // bevelThickness: 10,
1298 // bevelSize: 8,
1299 // bevelSegments: 5
1300 // });
1301 // speed = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: 0xff0000 }));
1302 // number.length === 2 ? speed.position.set(200, 780, 200) : (number.length === 3 ? speed.position.set(200, 780, 300) : speed.position.set(200, 780, 100))
1303 // speed.rotation.set(0, Math.PI / 2, 0);
1304 // kbxsSb.add(speed);
1305 // });
1306 // }
1307
1308 //可变限速数值动态化
1309 export function kbxsChangeState(number, direction) {
1310 number = String(number)
1311 var speed = direction === 'right' ? speedRight : speedLeft;
1312 var kbxsSb = direction === 'right' ? kbxsRightSb : kbxsLeftSb;
1313 if (speed) {
1314 speed.geometry.dispose();
1315 speed.material.dispose();
1316 kbxsSb.remove(speed);
1317 }
1318 function getTextCanvas(text) {
1319 var width = 45, height = 45;
1320 var canvas = document.createElement('canvas');
1321 canvas.width = width;
1322 canvas.height = height;
1323 var ctx = canvas.getContext('2d');
1324 ctx.fillStyle = '#000000';
1325 ctx.fillRect(0, 0, width, height);
1326 ctx.font = 40 + 'px " bold';
1327 ctx.fillStyle = '#00FF00';
1328 ctx.textAlign = 'center';
1329 ctx.textBaseline = 'middle';
1330 ctx.fillText(text, width / 2, height / 2);
1331 return canvas;
1332 }
1333 var geometry = new THREE.PlaneBufferGeometry(45, 45);
1334 var material = new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(getTextCanvas('60')) });// top
1335 speed = new THREE.Mesh(geometry, material);
1336 kbxsSb.add(speed)
1337 speed.scale.set(10, 10, 10)
1338 speed.position.set(200, 890, 0)
1339 speed.rotateY(Math.PI / 2)
1340
1341 }
1342
1343
1344 //可变信息板门架式文字动态化
1345 export function qbbmChangeState(textContent) {
1346 textContent = String(textContent);
1347 //textContent = `道路千万条,安全第一条;行车不规范,亲人两行泪!一二三四五,上山打老虎;老虎不在家,就当我没说。`
1348 if (textM) {
1349 textM.geometry.dispose();
1350 textM.material.dispose();
1351 qbbmSb.remove(textM);
1352 }
1353
1354 var width = textContent.length * 50 + 200;
1355 var height = 125;
1356 function getTextCanvas(text) {
1357 var canvas = document.createElement('canvas');
1358 canvas.width = width;
1359 canvas.height = height;
1360 var ctx = canvas.getContext('2d');
1361 ctx.fillStyle = '#050507';
1362 ctx.fillRect(0, 0, width, height);
1363 ctx.font = 50 + 'px " bold';
1364 ctx.fillStyle = '#FF0000';
1365 ctx.textAlign = 'center';
1366 ctx.textBaseline = 'middle';
1367 ctx.fillText(text, width / 2, height / 2);
1368 return canvas;
1369 }
1370 textMwidth = Number((1000 / width).toFixed(2));
1371 var geometry = new THREE.PlaneGeometry(1020, height);
1372 geometry.faceVertexUvs[0][0][0] = new THREE.Vector2(0, 1);
1373 geometry.faceVertexUvs[0][0][1] = new THREE.Vector2(0, 0);
1374 geometry.faceVertexUvs[0][0][2] = new THREE.Vector2(textMwidth, 1);
1375 geometry.faceVertexUvs[0][1][0] = new THREE.Vector2(0, 0);
1376 geometry.faceVertexUvs[0][1][1] = new THREE.Vector2(textMwidth, 0);
1377 geometry.faceVertexUvs[0][1][2] = new THREE.Vector2(textMwidth, 1);
1378 mapM = new THREE.CanvasTexture(getTextCanvas(textContent))
1379
1380 var material = new THREE.MeshBasicMaterial({ map: mapM });// top
1381 textM = new THREE.Mesh(geometry, material);
1382 qbbmSb.add(textM)
1383 textM.scale.set(10, 10, 10)
1384 textM.rotation.set(0, Math.PI / 2, 0)
1385 mapM.wrapS = THREE.RepeatWrapping;//无限水平平铺
1386 textM.position.set(1000, 1750, 0)
1387 }
1388
1389 //可变信息板F式文字动态化
1390 export function qbbfChangeState(textContent) {
1391 if (textF) {
1392 if (Array.isArray(textF)) {
1393 textF.forEach(item => {
1394 item.geometry.dispose();
1395 item.material.dispose();
1396 qbbfSb.remove(item);
1397 })
1398 }
1399 else {
1400 textF.geometry.dispose();
1401 textF.material.dispose();
1402 qbbfSb.remove(textF);
1403 }
1404 }
1405 clearInterval(intervalF);
1406 textF = [];
1407 textContent = String(textContent);
1408 var re = /[^\u4E00-\u9FA5]/g;
1409 textContent = textContent.replace(re, '');
1410 var index = 0;
1411 for (let i = 0; i < Math.ceil(textContent.length / 4); i++) {
1412 var str = textContent.substr(index, 4);
1413 index += 4;
1414 var width = 148;
1415 var height = 45;
1416 function getTextCanvas(text) {
1417 var canvas = document.createElement('canvas');
1418 canvas.width = width;
1419 canvas.height = height;
1420 var ctx = canvas.getContext('2d');
1421 ctx.fillStyle = '#0A0A0A';
1422 ctx.fillRect(0, 0, width, height);
1423 ctx.font = 30 + 'px " bold';
1424 ctx.fillStyle = '#FF0000';
1425 ctx.textAlign = 'center';
1426 ctx.textBaseline = 'middle';
1427 ctx.fillText(text, width / 2, height / 2);
1428 return canvas;
1429 }
1430 var geometry = new THREE.PlaneGeometry(148, height);
1431 mapF = new THREE.CanvasTexture(getTextCanvas(str))
1432 var material = new THREE.MeshBasicMaterial({ map: mapF });// top
1433 textF[i] = new THREE.Mesh(geometry, material);
1434 qbbfSb.add(textF[i]);
1435 textF[i].scale.set(10, 10, 10);
1436 textF[i].rotation.set(0, -Math.PI / 2, 0);
1437 if ((i + 1) % 2 === 1) {
1438 textF[i].position.set(-100, 1500, -405);
1439 }
1440 else {
1441 textF[i].position.set(-100, 1050, -405);
1442 }
1443 textF[i].visible = (i === 0 || i === 1) ? true : false;
1444
1445 }
1446 var indexs = 2;
1447 intervalF = setInterval(() => {
1448 textF.forEach(item => {
1449 item.visible = false;
1450 })
1451 textF[indexs] && (textF[indexs].visible = true);
1452 textF[indexs + 1] && (textF[indexs + 1].visible = true);
1453 if (indexs + 1 === textF.length || indexs + 2 === textF.length) {
1454 indexs = 0
1455 }
1456 else {
1457 indexs += 2;
1458 }
1459 }, 4000)
1460
1461
1462 }
1463
1464 //卷帘门动态化
1465 function jlmChangeState(obj) {
1466 if (obj.userData.typeCode !== 'FireFightingDoor') return;
1467 switch (obj.userData.defaultCommandStatus) {
1468 case "0"://全开
1469 obj.children[2].children[1].visible = false;//上
1470 obj.children[2].children[2].visible = false;//下
1471 break;
1472 case "1"://半开
1473 obj.children[2].children[1].visible = true;//上
1474 obj.children[2].children[2].visible = false;//下
1475 break;
1476 default:
1477 obj.children[2].children[1].visible = true;//上
1478 obj.children[2].children[2].visible = true;//下
1479 break;
1480 }
1481 }
1482
1483 //修改颜色
1484 export function colorChange(color, opacity) {
1485 let object = scene.children.find(item => item.name === 'dm')
1486 object.children[14].material.color.set(color)
1487 object.children[14].material.transparent = true;
1488 object.children[14].material.opacity = opacity;
1489
1490 object.children[15].material.color.set(color)
1491 object.children[15].material.transparent = true;
1492 object.children[15].material.opacity = opacity;
1493
1494 object.children[16].material.color.set(color)
1495 object.children[16].material.transparent = true;
1496 object.children[16].material.opacity = opacity;
1497
1498 object.children[17].material.color.set(color)
1499 object.children[17].material.transparent = true;
1500 object.children[17].material.opacity = opacity;
1501
1502 object.children[158].children[0].material.color.set(color)
1503 object.children[158].children[0].material.transparent = true;
1504 object.children[158].children[0].material.opacity = opacity;
1505 }
1506
1507 //情报板(门式)实现文字跑马灯效果
1508 function fontRun() {
1509 if (!textM) return;
1510 mapM.offset.x += 0.001
1511 }