فهرست منبع

新增风窗模型

hongrunxia 3 روز پیش
والد
کامیت
04b8e5869b

+ 1 - 1
src/layouts/default/header/components/user-dropdown/index.vue

@@ -47,7 +47,7 @@
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { useModal } from '/@/components/Modal';
-  import { useMessage } from '/src/hooks/web/useMessage';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { useGo } from '/@/hooks/web/usePage';
   import headerImg from '/@/assets/images/header.jpg';
   import { propTypes } from '/@/utils/propTypes';

+ 251 - 0
src/views/vent/monitorManager/windowMonitor/dandaoFcLt.threejs.ts

@@ -0,0 +1,251 @@
+import * as THREE from 'three';
+import { getTextCanvas } from '/@/utils/threejs/util';
+import gsap from 'gsap';
+
+class ddFc_lt {
+  model;
+  modelName = 'ddFc';
+  group: THREE.Object3D = new THREE.Object3D();
+  animationTimer;
+  isLRAnimation = true;
+  direction = 1;
+  windowsActionArr = {
+    frontWindow: [],
+  };
+  player1;
+  player2;
+  playerStartClickTime1 = new Date().getTime();
+  constructor(model) {
+    this.model = model;
+    this.group.name = 'ddFc';
+  }
+  addLight = () => {
+    if (!this.group || !this.group) return;
+
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
+    directionalLight.position.set(-437, 61, 559);
+    this.group.add(directionalLight);
+
+    const pointLight2 = new THREE.PointLight(0xffffff, 1, 150);
+    pointLight2.position.set(-101, 34, 16);
+    pointLight2.shadow.bias = 0.05;
+    this.group.add(pointLight2);
+
+    const pointLight3 = new THREE.PointLight(0xffffff, 1, 150);
+    pointLight3.position.set(19, 25, -7);
+    pointLight3.shadow.bias = 0.05;
+    this.group.add(pointLight3);
+
+    const pointLight6 = new THREE.PointLight(0xffffff, 1, 300);
+    pointLight6.position.set(51, 51, 9);
+    pointLight6.shadow.bias = 0.05;
+    this.group.add(pointLight6);
+  };
+
+  // 设置模型位置
+  setModalPosition() {
+    this.group?.scale.set(22, 22, 22);
+    this.group?.position.set(-35, 25, 15);
+  }
+
+  addMonitorText(selectData) {
+    if (!this.group) {
+      return;
+    }
+    const screenDownText = VENT_PARAM['modalText']
+      ? VENT_PARAM['modalText']
+      : History_Type['type'] == 'remote'
+      ? `国能神东煤炭集团监制`
+      : '煤炭科学技术研究院有限公司研制';
+
+    const screenDownTextX = 90 - (screenDownText.length - 10) * 6;
+    const textArr = [
+      {
+        text: `远程定量调节自动风窗`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 100,
+        y: 95,
+      },
+      {
+        text: `${selectData.OpenDegree ? '开度值(°)' : selectData.forntArea ? '过风面积(㎡)' : '过风面积(㎡)'}:`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 145,
+      },
+      {
+        text: selectData.OpenDegree
+          ? Number(`${selectData.OpenDegree}`).toFixed(2)
+          : selectData.forntArea
+          ? Number(`${selectData.forntArea}`).toFixed(2)
+          : '-',
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 145,
+      },
+      {
+        text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态:'}:`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 200,
+      },
+      {
+        text: `${
+          selectData.frontRearDP
+            ? selectData.frontRearDP
+            : selectData.windSpeed
+            ? selectData.windSpeed
+            : selectData.netStatus == '0'
+            ? '断开'
+            : '连接'
+        }`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 200,
+      },
+      {
+        text: `${selectData.fWindowM3 ? '过风量(m³/min)' : '风窗道数'}: `,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 250,
+      },
+      {
+        text: `${selectData.fWindowM3 ? selectData.fWindowM3 : selectData.nwindownum}`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 250,
+      },
+      {
+        text: screenDownText,
+        font: 'normal 28px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: screenDownTextX,
+        y: 300,
+      },
+    ];
+    getTextCanvas(750, 546, textArr, '').then((canvas: HTMLCanvasElement) => {
+      const textMap = new THREE.CanvasTexture(canvas); // 关键一步
+      const textMaterial = new THREE.MeshBasicMaterial({
+        // 关于材质并未讲解 实操即可熟悉                 这里是漫反射类似纸张的材质,对应的就有高光类似金属的材质.
+        map: textMap, // 设置纹理贴图
+        transparent: true,
+        side: THREE.DoubleSide, // 这里是双面渲染的意思
+      });
+      textMap.dispose();
+      textMaterial.blending = THREE.CustomBlending;
+      const monitorPlane = this.group?.getObjectByName('monitorText');
+      if (monitorPlane) {
+        monitorPlane.material = textMaterial;
+      } else {
+        const planeGeometry = new THREE.PlaneGeometry(526, 346); // 平面3维几何体PlaneGeometry
+        const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
+        planeMesh.name = 'monitorText';
+        planeMesh.scale.set(0.003, 0.0034, 0.004);
+        planeMesh.position.set(4.25, 0.44, -0.27);
+        this.group?.add(planeMesh);
+      }
+    });
+  }
+
+  /* 提取风门序列帧,初始化前后门动画 */
+  initAnimation() {
+    const meshArr01: THREE.Mesh[] = [];
+    const fcGroup = this.group?.getObjectByName('FengChuang_DaLiuTa')?.getObjectByName('FengChuang_DaLiuTa_1')?.getObjectByName('FengChuang_1_17');
+    if (fcGroup) {
+      fcGroup.children.filter((item: THREE.Mesh) => {
+        item.rotateOnAxis(new THREE.Vector3(0, 0, 1), 0);
+        meshArr01.push(item);
+      });
+    }
+    this.windowsActionArr.frontWindow = meshArr01;
+  }
+
+  play(rotationParam, flag) {
+    if (!this.windowsActionArr.frontWindow) {
+      return;
+    }
+    if (flag === 1) {
+      // 前风窗动画
+      this.windowsActionArr.frontWindow.forEach((mesh: THREE.Mesh) => {
+        gsap.to(mesh.rotation, {
+          z: THREE.MathUtils.degToRad(rotationParam.frontDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.frontDeg1 - mesh.rotation.z),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 0) {
+      ([...this.windowsActionArr.frontWindow] as THREE.Mesh[]).forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          z: THREE.MathUtils.degToRad(90),
+          overwrite: true,
+        });
+      });
+    }
+  }
+
+  /* 点击风窗,风窗全屏 */
+  mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
+    if (this.animationTimer) {
+      clearTimeout(this.animationTimer);
+      this.animationTimer = null;
+    }
+    // 判断是否点击到视频
+    intersects.find((intersect) => {
+      const mesh = intersect.object;
+      if (mesh.name === 'player1') {
+        if (new Date().getTime() - this.playerStartClickTime1 < 400) {
+          // 双击,视频放大
+          if (this.player1) {
+            this.player1.requestFullscreen();
+          }
+        }
+        this.playerStartClickTime1 = new Date().getTime();
+        return true;
+      }
+      return false;
+    });
+  }
+
+  mouseUpModel() {}
+
+  /* 风门动画 */
+  render() {
+    if (!this.model) {
+      return;
+    }
+  }
+
+  mountedThree() {
+    return new Promise((resolve) => {
+      this.model.setGLTFModel('ddFc-lt').then((gltf) => {
+        this.group = gltf[0];
+        this.group.name = this.modelName;
+        this.setModalPosition();
+        this.initAnimation();
+        resolve(null);
+      });
+    });
+  }
+
+  destroy() {
+    this.model.clearGroup(this.group);
+    this.windowsActionArr.frontWindow = undefined;
+    this.model = null;
+    this.group = null;
+  }
+}
+export default ddFc_lt;

+ 23 - 1
src/views/vent/monitorManager/windowMonitor/window.threejs.ts

@@ -13,6 +13,7 @@ import ddFc_2 from './dandaoFcBd2.threejs'; // ddFc_2 单道-一个大窗两列
 import ddFc_6 from './dandaoFcHjt.threejs'; // ddFc_6 单道-大窗1列扇叶(活鸡兔)
 import ddFc_7 from './dandaoFcBd3.threejs'; // ddFc_6 单道-大窗1列扇叶(活鸡兔)
 import threeFc_8 from './sandaoFc.threejs'; // ddFc_8 三道-大窗2列门式扇叶(三道沟)
+import ddFc_lt from './dandaoFcLt.threejs';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
 import { getDictItemsByCode } from '/@/utils/dict';
@@ -34,6 +35,7 @@ let model: UseThree,
   ddFc4: ddFc_4,
   ddFc6: ddFc_6,
   ddFc7: ddFc_7,
+  ddFc8: ddFc_lt,
   threeFc8: threeFc_8,
   singleWindowXkObj: singleWindowXk,
   group: THREE.Object3D,
@@ -69,6 +71,8 @@ const startAnimation = () => {
       ddFc6.mouseUpModel.call(ddFc6);
     } else if (windowType === 'ddFc7' && ddFc7) {
       ddFc7.mouseUpModel.call(ddFc7);
+    } else if (windowType === 'ddFc8' && ddFc8) {
+      ddFc8.mouseUpModel.call(ddFc8);
     } else if (windowType === 'sdFc1' && sdFc1) {
       sdFc1.mouseUpModel.call(sdFc1);
     } else if (windowType === 'sdFc3' && sdFc3) {
@@ -103,6 +107,8 @@ const mouseEvent = (event) => {
         ddFc6.mousedownModel.call(ddFc6, intersects);
       } else if (windowType === 'ddFc7' && ddFc7) {
         ddFc7.mousedownModel.call(ddFc7, intersects);
+      } else if (windowType === 'ddFc8' && ddFc8) {
+        ddFc8.mousedownModel.call(ddFc8, intersects);
       } else if (windowType === 'sdFc1' && sdFc1) {
         sdFc1.mousedownModel.call(sdFc1, intersects);
       } else if (windowType === 'sdFc3' && sdFc3) {
@@ -140,6 +146,8 @@ export const addMonitorText = (selectData) => {
     return ddFc6.addMonitorText.call(ddFc6, selectData);
   } else if (windowType === 'ddFc7' && ddFc7) {
     return ddFc7.addMonitorText.call(ddFc7, selectData);
+  } else if (windowType === 'ddFc8' && ddFc8) {
+    return ddFc8.addMonitorText.call(ddFc8, selectData);
   } else if (windowType === 'sdFc1' && sdFc1) {
     return sdFc1.addMonitorText.call(sdFc1, selectData);
   } else if (windowType === 'sdFc3' && sdFc3) {
@@ -258,6 +266,8 @@ export const play = (rotationParam, flag) => {
     return ddFc6.play.call(ddFc6, rotationParam, flag);
   } else if (windowType === 'ddFc7' && ddFc7) {
     return ddFc7.play.call(ddFc7, rotationParam, flag);
+  } else if (windowType === 'ddFc8' && ddFc8) {
+    return ddFc8.play.call(ddFc8, rotationParam, flag);
   } else if (windowType === 'sdFc1' && sdFc1) {
     return sdFc1.play.call(sdFc1, rotationParam, flag);
   } else if (windowType === 'sdFc3' && sdFc3) {
@@ -304,6 +314,12 @@ export const setModelType = (type) => {
       newP: { x: 66.257, y: 57.539, z: 94.313 },
       newT: { x: 0, y: 0, z: 0 },
     },
+    ddFc8: {
+      render: ddFc8 ? () => ddFc8.render() : null,
+      group: ddFc8 ? ddFc8.group : null,
+      newP: { x: 32.78, y: 64.88, z: 106.78 },
+      newT: { x: -6.12, y: 13.27, z: -4.64 },
+    },
     ddFc1: {
       render: ddFc1 ? () => ddFc1.render() : null,
       group: ddFc1 ? ddFc1.group : null,
@@ -424,6 +440,10 @@ export const mountedThree = () => {
           ddFc7 = new ddFc_7(model);
           await ddFc7.mountedThree();
           break;
+        case 'ddFc8':
+          ddFc8 = new ddFc_lt(model);
+          await ddFc8.mountedThree();
+          break;
         case 'sdFc3':
           sdFc3 = new sdFc_3(model);
           await sdFc3.mountedThree();
@@ -451,7 +471,7 @@ export const mountedThree = () => {
       }
     }
     model.animate();
-    // addMouseEvent();
+    addMouseEvent();
     resolve(null);
   });
 };
@@ -467,6 +487,7 @@ export const destroy = () => {
     if (ddFc4) ddFc4.destroy();
     if (ddFc6) ddFc6.destroy();
     if (ddFc7) ddFc7.destroy();
+    if (ddFc8) ddFc8.destroy();
     if (sdFc1) sdFc1.destroy();
     if (sdFc3) sdFc3.destroy();
     if (sdFc4) sdFc4.destroy();
@@ -485,6 +506,7 @@ export const destroy = () => {
     ddFc4 = null;
     ddFc6 = null;
     ddFc7 = null;
+    ddFc8 = null;
     sdFc1 = null;
     sdFc3 = null;
     sdFc4 = null;