浏览代码

[Feat 0000] 新增防火门模型

hongrunxia 3 天之前
父节点
当前提交
18a71d072d

+ 171 - 0
src/views/vent/monitorManager/fireDoorMonitor/fireDoor.threejs.fire.redGate.ts

@@ -0,0 +1,171 @@
+import * as THREE from 'three';
+import { useAppStore } from '/@/store/modules/app';
+
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+
+class FireDoor {
+  modelName = 'fireDoor-redGate';
+  model; //
+  group;
+  isLRAnimation = true; // 是否开启左右摇摆动画
+  direction = 1; // 摇摆方向
+  animationTimer: NodeJS.Timeout | null = null; // 摇摆开启定时器
+  player1;
+  player2;
+  deviceDetailCSS3D;
+  playerStartClickTime1 = new Date().getTime();
+  playerStartClickTime2 = new Date().getTime();
+
+  fmClock = new THREE.Clock();
+  mixers: THREE.AnimationMixer | undefined;
+  appStore = useAppStore();
+  damperOpenMesh;
+  damperClosedMesh;
+
+  clipActionArr = {
+    door: null as unknown as THREE.AnimationAction,
+  };
+
+  constructor(model) {
+    this.model = model;
+  }
+
+  addLight() {
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
+    directionalLight.position.set(344, 690, 344);
+    this.group?.add(directionalLight);
+    directionalLight.target = this.group as THREE.Object3D;
+
+    const pointLight2 = new THREE.PointLight(0xffeeee, 1, 300);
+    pointLight2.position.set(-4, 10, 1.8);
+    pointLight2.shadow.bias = 0.05;
+    this.group?.add(pointLight2);
+
+    const pointLight3 = new THREE.PointLight(0xffeeee, 1, 200);
+    pointLight3.position.set(-0.5, -0.5, 0.75);
+    pointLight3.shadow.bias = 0.05;
+    this.group?.add(pointLight3);
+  }
+  resetCamera() {
+    this.model.camera.far = 274;
+    this.model.orbitControls?.update();
+    this.model.camera.updateProjectionMatrix();
+  }
+  // 设置模型位置
+  setModalPosition() {
+    this.group?.scale.set(22, 22, 22);
+    this.group?.position.set(-20, 20, 9);
+  }
+
+  /* 风门动画 */
+  render() {
+    if (!this.model) {
+      return;
+    }
+    if (this.mixers && this.fmClock.running) {
+      this.mixers.update(2);
+    }
+  }
+
+  /* 点击风门 */
+  mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
+    console.log('摄像头控制信息', this.model?.orbitControls, this.model?.camera);
+  }
+
+  mouseUpModel() {}
+
+  /* 提取风门序列帧,初始化前后门动画 */
+  initAnimation() {
+    const fireGroup = this.group.children[0]?.getObjectByName('fireDoor-redGate');
+    if (fireGroup) {
+      const tracks = fireGroup.animations[0].tracks;
+
+      this.mixers = new THREE.AnimationMixer(fireGroup);
+
+      const door = new THREE.AnimationClip('door', 100, tracks);
+      const frontClipAction = this.mixers.clipAction(door, fireGroup);
+      frontClipAction.clampWhenFinished = true;
+      frontClipAction.loop = THREE.LoopOnce;
+      this.clipActionArr.door = frontClipAction;
+    }
+  }
+
+  // 播放动画
+  play(handlerState, timeScale = 0.01) {
+    let handler = () => {};
+    if (this.clipActionArr.door) {
+      switch (handlerState) {
+        case 1: // 打开门
+          handler = () => {
+            this.clipActionArr.door.paused = true;
+            this.clipActionArr.door.reset();
+            this.clipActionArr.door.time = 1.7;
+            this.clipActionArr.door.timeScale = -timeScale;
+            // this.clipActionArr.door.clampWhenFinished = true;
+            this.clipActionArr.door.play();
+            this.fmClock.start();
+
+            // 显示打开前门文字
+            if (this.damperOpenMesh) this.damperOpenMesh.visible = true;
+          };
+          break;
+        case 2: // 关闭门
+          handler = () => {
+            this.clipActionArr.door.paused = true;
+            this.clipActionArr.door.reset(); //
+            this.clipActionArr.door.time = 0;
+            this.clipActionArr.door.timeScale = timeScale;
+            // this.clipActionArr.door.clampWhenFinished = true;
+            this.clipActionArr.door.play();
+            this.fmClock.start();
+
+            if (this.damperOpenMesh) this.damperOpenMesh.visible = false;
+          };
+          break;
+        default:
+      }
+      handler();
+    }
+  }
+
+  mountedThree() {
+    this.group = new THREE.Object3D();
+    this.group.name = this.modelName;
+
+    return new Promise((resolve) => {
+      if (!this.model) {
+        resolve(null);
+      }
+      this.model.setGLTFModel([this.modelName], this.group).then(() => {
+        this.setModalPosition();
+        console.log(this.group);
+        // 初始化左右摇摆动画;
+        this.initAnimation();
+        // this.addLight();
+        // this.model.animate();
+        // resolve(this.model);
+      });
+    });
+  }
+
+  destroy() {
+    if (this.model) {
+      if (this.mixers) {
+        this.mixers.uncacheClip(this.clipActionArr.door.getClip());
+        this.mixers.uncacheAction(this.clipActionArr.door.getClip(), this.group);
+        this.mixers.uncacheRoot(this.group);
+
+        if (this.model.animations[0]) this.model.animations[0].tracks = [];
+      }
+      this.model.clearGroup(this.group);
+      this.clipActionArr.door = undefined;
+
+      this.mixers = undefined;
+
+      // document.getElementById('damper3D').parentElement.remove(document.getElementById('damper3D'))
+    }
+  }
+}
+export default FireDoor;

+ 179 - 89
src/views/vent/monitorManager/fireDoorMonitor/fireDoor.threejs.ts

@@ -1,16 +1,15 @@
 import * as THREE from 'three';
 import UseThree from '../../../../utils/threejs/useThree';
-import FireDoor from './fireDoor.threejs.fire';
-import FireDoorF from './fireDoor.threejs.fireF';
-import FireDoorSsl from './fireDoor.threejs.ssl';
+import { getDictItemsByCode } from '/@/utils/dict';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
 
 // 模型对象、 文字对象
 let model,
   fireDoor, //液压风门
-  fireDoorF, //液压风门
+  fireDoorF, //保德风门
   fireDoorSsl, // 思山岭防火门
+  fireDoorRed, // 防火门
   group: THREE.Object3D,
   fhmType = '';
 
@@ -32,6 +31,9 @@ const startAnimation = () => {
     if (fhmType === 'fireDoorSsl') {
       fireDoorSsl?.mouseUpModel.call(fireDoorSsl);
     }
+    if (fhmType === 'fireDoorRed') {
+      fireDoorRed?.mouseUpModel.call(fireDoorRed);
+    }
   });
 };
 
@@ -48,6 +50,9 @@ const mouseEvent = (event) => {
       if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
         fireDoorSsl?.mousedownModel.call(fireDoorSsl, intersects);
       }
+      if (fhmType === 'fireDoorRed' && fireDoorRed) {
+        fireDoorRed?.mousedownModel.call(fireDoorRed, intersects);
+      }
     });
     // console.log('摄像头控制信息', model.orbitControls, model.camera);
   }
@@ -63,93 +68,137 @@ export const play = (handlerState, flag?) => {
   if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
     return fireDoorSsl.play.call(fireDoorSsl, handlerState, flag);
   }
+  if (fhmType === 'fireDoorRed' && fireDoorRed) {
+    return fireDoorRed.play.call(fireDoorRed, handlerState, flag);
+  }
 };
 
 // 切换风门类型
 export const setModelType = (type) => {
   fhmType = type;
+  const fhmConfigurations = {
+    fireDoor: {
+      render: fireDoor ? () => fireDoor.render() : null,
+      group: fireDoor ? fireDoor.group : null,
+      newP: { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
+      newT: { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
+    },
+    fireDoorF: {
+      render: fireDoorF ? () => fireDoorF.render() : null,
+      group: fireDoorF ? fireDoorF.group : null,
+      newP: { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
+      newT: { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
+    },
+    fireDoorSsl: {
+      render: fireDoorSsl ? () => fireDoorSsl.render() : null,
+      group: fireDoorSsl ? fireDoorSsl.group : null,
+      newP: { x: 342.74781900192056, y: 183.50210411099545, z: 451.0806333923029 },
+      newT: { x: 72.33938301176254, y: -35.03891296652319, z: -37.91742549963208 },
+    },
+    fireDoorRed: {
+      render: fireDoorRed ? () => fireDoorRed.render() : null,
+      group: fireDoorRed ? fireDoorRed.group : null,
+      newP: { x: 66.257, y: 57.539, z: 94.313 },
+      newT: { x: -2.28, y: -0.91, z: -5.68 },
+    },
+  };
+  const config = fhmConfigurations[fhmType];
+  const oldCameraPosition = { x: -1000, y: 100, z: 500 };
   return new Promise((resolve) => {
     // 暂停风门1动画
-    if (fhmType === 'fireDoor' && fireDoor && fireDoor.group) {
-      if (fireDoor.clipActionArr.door) {
-        fireDoor.clipActionArr.door.reset();
-        fireDoor.clipActionArr.door.time = 0.5;
-        fireDoor.clipActionArr.door.stop();
-      }
+    // if (fhmType === 'fireDoor' && fireDoor && fireDoor.group) {
+    //   if (fireDoor.clipActionArr.door) {
+    //     fireDoor.clipActionArr.door.reset();
+    //     fireDoor.clipActionArr.door.time = 0.5;
+    //     fireDoor.clipActionArr.door.stop();
+    //   }
+
+    //   if (fireDoor.damperOpenMesh) fireDoor.damperOpenMesh.visible = false;
+    //   if (fireDoor.damperClosedMesh) fireDoor.damperClosedMesh.visible = true;
+    //   model.scene.remove(group);
+    //   model.startAnimation = fireDoor.render.bind(fireDoor);
+    //   group = fireDoor.group;
+    //   group.rotation.y = 0;
+    //   const oldCameraPosition = { x: -1000, y: 100, z: 500 };
+    //   setTimeout(async () => {
+    //     resolve(null);
+    //     model.scene.add(fireDoor.group);
+    //     await animateCamera(
+    //       oldCameraPosition,
+    //       { x: 0, y: 0, z: 0 },
+    //       { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
+    //       { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
+    //       model,
+    //       0.8
+    //     );
+    //   }, 300);
+    // } else if (fhmType === 'fireDoorF' && fireDoorF && fireDoorF.group) {
+    //   if (fireDoorF.clipActionArr.door) {
+    //     fireDoorF.clipActionArr.door.reset();
+    //     fireDoorF.clipActionArr.door.time = 0;
+    //     fireDoorF.clipActionArr.door.stop();
+    //   }
+    //   model.scene.remove(group);
+    //   model.startAnimation = fireDoorF.render.bind(fireDoorF);
+    //   group = fireDoorF.group;
+    //   group.rotation.y = 0;
+    //   const oldCameraPosition = { x: -1000, y: 100, z: 500 };
+    //   setTimeout(async () => {
+    //     resolve(null);
+    //     model.scene.add(fireDoorF.group);
+    //     await animateCamera(
+    //       oldCameraPosition,
+    //       { x: 0, y: 0, z: 0 },
+    //       { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
+    //       { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
+    //       model,
+    //       0.8
+    //     );
+    //   }, 300);
+    // } else if (fhmType === 'fireDoorSsl' && fireDoorSsl && fireDoorSsl.group) {
+    //   // if (fireDoorSsl.clipActionArr.door) {
+    //   //   fireDoorSsl.clipActionArr.door.reset();
+    //   //   fireDoorSsl.clipActionArr.door.time = 0;
+    //   //   fireDoorSsl.clipActionArr.door.stop();
+    //   // }
+    //   // model.scene.remove(group);
+    //   // model.startAnimation = fireDoorSsl.render.bind(fireDoorSsl);
+    //   group = fireDoorSsl.group;
+    //   group.rotation.y = 0;
+    //   const oldCameraPosition = { x: -1000, y: 100, z: 500 };
+    //   setTimeout(async () => {
+    //     resolve(null);
+    //     model.scene.add(fireDoorSsl.group);
+    //     await animateCamera(
+    //       oldCameraPosition,
+    //       { x: 0, y: 0, z: 0 },
+    //       {
+    //         x: 342.74781900192056,
+    //         y: 183.50210411099545,
+    //         z: 451.0806333923029,
+    //       },
+    //       {
+    //         x: 72.33938301176254,
+    //         y: -35.03891296652319,
+    //         z: -37.91742549963208,
+    //       },
+    //       model,
+    //       0.8
+    //     );
+    //   }, 300);
+    // }
+    if (config && config.group) {
+      model.startAnimation = config.render;
+      group = config.group;
 
-      if (fireDoor.damperOpenMesh) fireDoor.damperOpenMesh.visible = false;
-      if (fireDoor.damperClosedMesh) fireDoor.damperClosedMesh.visible = true;
-      model.scene.remove(group);
-      model.startAnimation = fireDoor.render.bind(fireDoor);
-      group = fireDoor.group;
-      group.rotation.y = 0;
-      const oldCameraPosition = { x: -1000, y: 100, z: 500 };
-      setTimeout(async () => {
-        resolve(null);
-        model.scene.add(fireDoor.group);
-        await animateCamera(
-          oldCameraPosition,
-          { x: 0, y: 0, z: 0 },
-          { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
-          { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
-          model,
-          0.8
-        );
-      }, 300);
-    } else if (fhmType === 'fireDoorF' && fireDoorF && fireDoorF.group) {
-      if (fireDoorF.clipActionArr.door) {
-        fireDoorF.clipActionArr.door.reset();
-        fireDoorF.clipActionArr.door.time = 0;
-        fireDoorF.clipActionArr.door.stop();
-      }
-      model.scene.remove(group);
-      model.startAnimation = fireDoorF.render.bind(fireDoorF);
-      group = fireDoorF.group;
-      group.rotation.y = 0;
-      const oldCameraPosition = { x: -1000, y: 100, z: 500 };
-      setTimeout(async () => {
-        resolve(null);
-        model.scene.add(fireDoorF.group);
-        await animateCamera(
-          oldCameraPosition,
-          { x: 0, y: 0, z: 0 },
-          { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
-          { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
-          model,
-          0.8
-        );
-      }, 300);
-    } else if (fhmType === 'fireDoorSsl' && fireDoorSsl && fireDoorSsl.group) {
-      // if (fireDoorSsl.clipActionArr.door) {
-      //   fireDoorSsl.clipActionArr.door.reset();
-      //   fireDoorSsl.clipActionArr.door.time = 0;
-      //   fireDoorSsl.clipActionArr.door.stop();
-      // }
-      // model.scene.remove(group);
-      // model.startAnimation = fireDoorSsl.render.bind(fireDoorSsl);
-      group = fireDoorSsl.group;
-      group.rotation.y = 0;
-      const oldCameraPosition = { x: -1000, y: 100, z: 500 };
       setTimeout(async () => {
+        await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
+        model.scene?.add(config.group);
         resolve(null);
-        model.scene.add(fireDoorSsl.group);
-        await animateCamera(
-          oldCameraPosition,
-          { x: 0, y: 0, z: 0 },
-          {
-            x: 342.74781900192056,
-            y: 183.50210411099545,
-            z: 451.0806333923029,
-          },
-          {
-            x: 72.33938301176254,
-            y: -35.03891296652319,
-            z: -37.91742549963208,
-          },
-          model,
-          0.8
-        );
-      }, 300);
+      }, 1000);
+    } else {
+      resolve(null);
+      throw new Error(`Unsupported fhmType: ${fhmType}`);
     }
   });
 };
@@ -161,6 +210,8 @@ export const initCameraCanvas = async (playerVal1) => {
     return await fireDoorF.initCamera.call(fireDoorF, playerVal1);
   } else if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
     return await fireDoorSsl.initCamera.call(fireDoorSsl, playerVal1);
+  } else if (fhmType === 'fireDoorRed' && fireDoorRed) {
+    return await fireDoorRed.initCamera.call(fireDoorRed, playerVal1);
   }
 };
 const setControls = () => {
@@ -172,20 +223,53 @@ const setControls = () => {
   }
 };
 
+const loadModel = (code): Promise<any> => {
+  if (code === 'fireDoor') return import('./fireDoor.threejs.fire').then((r) => r.default);
+  if (code === 'fireDoorF') return import('./fireDoor.threejs.fireF').then((r) => r.default);
+  if (code === 'fireDoorSsl') return import('./fireDoor.threejs.ssl').then((r) => r.default);
+  if (code === 'fireDoorRed') return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
+  return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
+};
+
 export const mountedThree = () => {
   return new Promise(async (resolve) => {
     model = new UseThree('#damper3D', '', '#deviceDetail');
     model.setEnvMap('test1.hdr');
     model.renderer.toneMappingExposure = 1.0;
     model.camera.position.set(100, 0, 1000);
-    fireDoor = new FireDoor(model);
-    fireDoor.mountedThree();
-
-    fireDoorF = new FireDoorF(model);
-    fireDoorF.mountedThree();
-
-    fireDoorSsl = new FireDoorSsl(model);
-    fireDoorSsl.mountedThree();
+    const dictCodes = getDictItemsByCode('fireDoorStyle');
+    if (dictCodes && dictCodes.length > 0) {
+      for (let i = 0; i < dictCodes.length; i++) {
+        const dict = dictCodes[i];
+        switch (dict.value) {
+          case 'fireDoor':
+            const FireDoor = await loadModel('fireDoor');
+            fireDoor = new FireDoor(model);
+            fireDoor.mountedThree();
+            break;
+          case 'fireDoorF':
+            const FireDoorF = await loadModel('fireDoorF');
+            fireDoorF = new FireDoorF(model);
+            fireDoorF.mountedThree();
+            break;
+          case 'fireDoorSsl':
+            const FireDoorSsl = await loadModel('fireDoorSsl');
+            fireDoorSsl = new FireDoorSsl(model);
+            fireDoorSsl.mountedThree();
+            break;
+          case 'fireDoorRed':
+            const FireDoorRed = await loadModel('fireDoorRed');
+            fireDoorRed = new FireDoorRed(model);
+            fireDoorRed.mountedThree();
+            break;
+        }
+      }
+      resolve(null);
+    } else {
+      const FireDoorRed = await loadModel('');
+      fireDoorRed = new FireDoorRed(model);
+      fireDoorRed.mountedThree();
+    }
     resolve(null);
     setControls();
     model.animate();
@@ -204,6 +288,12 @@ export const destroy = () => {
     model.isRender = false;
     if (fireDoor) fireDoor.destroy();
     fireDoor = null;
+    if (fireDoorF) fireDoorF.destroy();
+    fireDoorF = null;
+    if (fireDoorSsl) fireDoorSsl.destroy();
+    fireDoorSsl = null;
+    if (fireDoorRed) fireDoorRed.destroy();
+    fireDoorRed = null;
     // @ts-ignore-next-line
     group = null;
     model.mixers = [];

+ 7 - 7
src/views/vent/monitorManager/fireDoorMonitor/index.vue

@@ -205,7 +205,7 @@
   const MonitorDataTable = ref();
   let contrlValue = '';
   const playerRef = ref();
-  const deviceType = ref('door');
+  const deviceType = ref('gate');
   // const deviceType = ref('firedoor');
   const activeKey = ref('1'); // tab
   const loading = ref(false);
@@ -316,12 +316,12 @@
     const baseData: any = deviceBaseList.value.find((baseData: any) => baseData.id === selectRow.deviceID);
     Object.assign(selectData, initData, selectRow, baseData);
     doorDeviceState = 1; //记录设备状态,为了与下一次监测数据做比较
-    let type = 'fireDoor';
-    if (selectData.modelType == 'bd_qt') {
-      type = 'fireDoor';
-    } else if (selectData.modelType == 'bd_kj') {
-      type = 'fireDoorF';
-    }
+    let type = 'fireDoorRed';
+    // if (selectData.modelType == 'bd_qt') {
+    //   type = 'fireDoor';
+    // } else if (selectData.modelType == 'bd_kj') {
+    //   type = 'fireDoorF';
+    // }
     await setModelType(type);
     loading.value = false;
     isdoorOpenRunning = true; //开关门动作是否在进行