Просмотр исходного кода

[Wip 0000] 局部风机双巷模型开发

houzekong 1 неделя назад
Родитель
Сommit
2c3ec7fc11

BIN
public/model/glft/jbfj/jbfj-dual_2025-01-22.glb


BIN
public/model/glft/jbfj/jbfj-dual_2025-02-27.glb


+ 1 - 1
src/utils/threejs/main.worker.ts

@@ -46,7 +46,7 @@ export function initModalWorker() {
     'jbfj/jbfj-hd_2025-01-09.glb',
     'jbfj/jbfj-fm_2023-06-02.glb',
     'jbfj/jbfj-fc_2023-06-02.glb',
-    'jbfj/jbfj-dual_2025-01-22.glb',
+    'jbfj/jbfj-dual_2025-02-27.glb',
     'ztfj/dj1_2023-06-02.glb',
     'ztfj/dj2_2023-06-02.glb',
     'ztfj/bg_2023-06-02.glb',

+ 1 - 1
src/views/vent/monitorManager/fanLocalMonitor/fanLocal.threejs.ts

@@ -4,7 +4,6 @@ import FanLocal from './fanLocal.threejs.base';
 import FanLocalDual from './fanLocalDual.threejs.base';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
-import { modal } from 'vxe-table';
 
 /** 模型总控制器 */
 let model: UseThree;
@@ -81,6 +80,7 @@ export function setModelType(modelType: 'fanLocal' | 'fanLocalDual' | string, su
       context.group.children.forEach((e) => {
         e.visible = false;
       });
+      // model.scene?.remove(context.group);
 
       if (modelType === type) {
         group = context?.group as THREE.Object3D;

+ 147 - 109
src/views/vent/monitorManager/fanLocalMonitor/fanLocalDual.threejs.base.ts

@@ -1,8 +1,8 @@
 import * as THREE from 'three';
 // import { setModalCenter } from '/@/utils/threejs/util';
 import Smoke from '../../comment/threejs/Smoke';
-import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer';
-// import * as dat from 'dat.gui';
+import { CSS3DObject, CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer';
+import * as dat from 'dat.gui';
 // const gui = new dat.GUI();
 // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
 
@@ -14,6 +14,7 @@ class ModelContext {
   group?: THREE.Object3D;
   /** 本模型所包含的所有元素合集 */
   private elements: unknown[] = [];
+  private cssSprites: CSS3DSprite[] = [];
   /** 本模型支持的 Object3DGroup 模块 */
   private modules: {
     /** 模块名称 */
@@ -41,38 +42,16 @@ class ModelContext {
     });
   }
 
-  /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入传入的锚点中 */
-  initCssElement() {
-    // selectors.forEach((selector, index) => {
-    //   const element = document.querySelector(selector) as HTMLElement;
-    //   if (element) {
-    //     const css3D = new CSS3DSprite(element);
-    //     this.cssSprites.push(css3D);
-    //     css3D.name = selector;
-    //     css3D.scale.set(0.05, 0.05, 0.05);
-    //     // const ff = gui.addFolder(`css元素${index}`);
-    //     // ff.add(css3D.position, 'x', -100, 100);
-    //     // ff.add(css3D.position, 'y', -100, 100);
-    //     // ff.add(css3D.position, 'z', -100, 100);
-    //     if (index < anchors.length) {
-    //       const [x, y, z] = anchors[index];
-    //       css3D.position.set(x, y, z);
-    //       this.group?.add(css3D);
-    //     } else {
-    //       console.warn(`指定的元素${selector}没有合适的位置放置`);
-    //     }
-    //   }
-    // });
-  }
-
   mountedThree() {
     return new Promise((resolve) => {
       this.model.setGLTFModel([this.modelName]).then(async (gltf) => {
         this.group = gltf[0];
         if (this.group) {
+          this.group.scale.set(2, 2, 2);
           // setModalCenter(this.group);
           this.addLight();
           this.setModelPosition();
+          this.initCssElement();
           this.initModules().then(resolve);
         }
       });
@@ -139,85 +118,52 @@ class ModelContext {
     });
   }
   stopAnimation(eles: unknown[]) {
-    eles.forEach((g) => {
-      if (g instanceof Smoke) {
-        g.stopSmoke();
-      }
+    const smokes = eles.filter((g) => {
+      return g instanceof Smoke;
     });
+    return Promise.all(smokes.map((e) => e.stopSmoke()));
   }
 
   /** 核心方法,初始化本模型的各个模块,这些模块可以实现特定场景的展示、控制等功能 */
   async initModules() {
     if (this.elements.length > 0) return;
     // 右侧风机-主风机进风
-    const curveFan1Right = this.generateSmokePath(
-      [
-        new THREE.Vector3(-85.685, 4.208, 43.895),
-        new THREE.Vector3(-85.685, 2.208, 41.895),
-        new THREE.Vector3(-85.685, 2.188, 35.327),
-        new THREE.Vector3(-85.685, 0.784, 33.086),
-        new THREE.Vector3(-85.685, 0.784, 27.848),
-        new THREE.Vector3(-85.685, 4.724, 21.565),
-        new THREE.Vector3(-85.685, 4.724, -12.993),
-        new THREE.Vector3(-26.191, 4.724, -13.232),
-        new THREE.Vector3(-25.608, 4.724, -47.022),
-        new THREE.Vector3(80.038, 4.724, -47.022),
-      ],
-      true
-    );
+    const curveFan1Right = this.generateSmokePath(['dian', 'dian1', 'dian2', 'dian3', 'dian4', 'dian5', 'dian6', 'dian7', 'dian8'], true);
     // 右侧风机-备风机进风
-    const curveFan2Right = this.generateSmokePath(
-      [
-        new THREE.Vector3(-85.685, 1.475, 43.895),
-        new THREE.Vector3(-85.685, -0.525, 41.895),
-        new THREE.Vector3(-85.685, -0.525, 35.327),
-        new THREE.Vector3(-85.685, 0.784, 33.086),
-        new THREE.Vector3(-85.685, 0.784, 27.848),
-        new THREE.Vector3(-85.685, 4.724, 21.565),
-        new THREE.Vector3(-85.685, 4.724, -12.993),
-        new THREE.Vector3(-26.191, 4.724, -13.232),
-        new THREE.Vector3(-25.608, 4.724, -47.022),
-        new THREE.Vector3(80.038, 4.724, -47.022),
-      ],
-      true
-    );
+    const curveFan2Right = this.generateSmokePath(['dian9', 'dian10', 'dian2', 'dian3', 'dian4', 'dian5', 'dian6', 'dian7', 'dian8'], true);
     // 左侧风机-主风机进风
-    const curveFan1Left = this.generateSmokePath(
-      [
-        new THREE.Vector3(-85.685, 4.188, 4.729),
-        new THREE.Vector3(-85.685, 2.188, 2.729),
-        new THREE.Vector3(-85.685, 2.188, -3.84),
-        new THREE.Vector3(-85.685, 0.784, -6.081),
-        new THREE.Vector3(-85.685, 0.784, -12.912),
-        new THREE.Vector3(80.251, 0.784, -12.912),
-      ],
-      true
-    );
+    const curveFan1Left = this.generateSmokePath(['dian11', 'dian12', 'dian15', 'dian16', 'dian17'], true);
     // 左侧风机-备风机进风
-    const curveFan2Left = this.generateSmokePath(
-      [
-        new THREE.Vector3(-85.685, 1.475, 4.729),
-        new THREE.Vector3(-85.685, -0.525, 2.729),
-        new THREE.Vector3(-85.685, -0.508, -3.84),
-        new THREE.Vector3(-85.685, 0.784, -6.081),
-        new THREE.Vector3(-85.685, 0.784, -12.912),
-        new THREE.Vector3(80.251, 0.784, -12.912),
-      ],
-      true
-    );
+    const curveFan2Left = this.generateSmokePath(['dian14', 'dian13', 'dian15', 'dian16', 'dian17'], true);
+    // 右侧巷道-回风前段
+    const curveTunnelRight = this.generateSmokePath(['dian18', 'dian19', 'dian20']);
+    // 左侧巷道-回风前段
+    const curveTunnelLeft = this.generateSmokePath(['dian20', 'dian22']);
+    // 左侧巷道-回风全长
+    const curveTunnelMajor = this.generateSmokePath(['dian21', 'dian22']);
+
     const group1 = new THREE.Group();
-    const smokeFan1Right = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400);
+    const smokeFan1Right = new Smoke('/model/img/texture-smoke.png', '#ffffff', 10, 0.75, 0.5, 400);
     smokeFan1Right.setPath(curveFan1Right);
     this.elements.push(smokeFan1Right);
-    const smokeFan2Right = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400);
+    const smokeFan2Right = new Smoke('/model/img/texture-smoke.png', '#ffffff', 10, 0.75, 0.5, 400);
     smokeFan2Right.setPath(curveFan2Right);
     this.elements.push(smokeFan2Right);
-    const smokeFan1Left = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400);
+    const smokeFan1Left = new Smoke('/model/img/texture-smoke.png', '#ffffff', 10, 0.75, 0.5, 400);
     smokeFan1Left.setPath(curveFan1Left);
     this.elements.push(smokeFan1Left);
-    const smokeFan2Left = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400);
+    const smokeFan2Left = new Smoke('/model/img/texture-smoke.png', '#ffffff', 10, 0.75, 0.5, 400);
     smokeFan2Left.setPath(curveFan2Left);
     this.elements.push(smokeFan2Left);
+    const smokeTunnelRight = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.35, 1.5, 200);
+    smokeTunnelRight.setPath(curveTunnelRight);
+    this.elements.push(smokeTunnelRight);
+    const smokeTunnelLeft = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.35, 1.5, 200);
+    smokeTunnelLeft.setPath(curveTunnelLeft);
+    this.elements.push(smokeTunnelLeft);
+    const smokeTunnelMajor = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.35, 1.5, 200);
+    smokeTunnelMajor.setPath(curveTunnelMajor);
+    this.elements.push(smokeTunnelMajor);
 
     await smokeFan1Right.setPoints();
     this.group?.add(smokeFan1Right.points);
@@ -227,58 +173,146 @@ class ModelContext {
     this.group?.add(smokeFan1Left.points);
     await smokeFan2Left.setPoints();
     this.group?.add(smokeFan2Left.points);
-    // const element = document.getElementById('inputBox') as HTMLElement;
-    // if (element) {
-    //   const fanLocalCSS3D = new CSS3DObject(element);
-    //   fanLocalCSS3D.name = 'text1';
-    //   fanLocalCSS3D.scale.set(0.04, 0.04, 0.04);
-    //   fanLocalCSS3D.rotation.y = -Math.PI / 2;
-    //   fanLocalCSS3D.position.set(-85.68, 5.97, -3.39);
-    //   group1.add(fanLocalCSS3D);
-    //   this.elements.push(fanLocalCSS3D);
-    // }
+    await smokeTunnelRight.setPoints();
+    this.group?.add(smokeTunnelRight.points);
+    await smokeTunnelLeft.setPoints();
+    this.group?.add(smokeTunnelLeft.points);
+    await smokeTunnelMajor.setPoints();
+    this.group?.add(smokeTunnelMajor.points);
 
+    // 双巷道的通风机都开启有4种情况
+    this.modules.push({
+      name: 'fan1RightOpen&fan1LeftOpen',
+      context: group1,
+      behavior: () => {
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan1Right, smokeFan1Left, smokeTunnelRight, smokeTunnelMajor]);
+        });
+      },
+    });
+    this.modules.push({
+      name: 'fan2RightOpen&fan1LeftOpen',
+      context: group1,
+      behavior: () => {
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan2Right, smokeFan1Left, smokeTunnelRight, smokeTunnelMajor]);
+        });
+      },
+    });
+    this.modules.push({
+      name: 'fan1RightOpen&fan2LeftOpen',
+      context: group1,
+      behavior: () => {
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan1Right, smokeFan2Left, smokeTunnelRight, smokeTunnelMajor]);
+        });
+      },
+    });
+    this.modules.push({
+      name: 'fan2RightOpen&fan2LeftOpen',
+      context: group1,
+      behavior: () => {
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan2Right, smokeFan2Left, smokeTunnelRight, smokeTunnelMajor]);
+        });
+      },
+    });
+    // 只有一个风机启动有4种情况
     this.modules.push({
       name: 'fan1RightOpen',
       context: group1,
       behavior: () => {
-        this.weakElements(this.elements);
-        this.startAnimation([smokeFan1Right]);
-        this.strongElements([smokeFan1Right]);
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan1Right, smokeTunnelMajor]);
+        });
       },
     });
     this.modules.push({
       name: 'fan2RightOpen',
       context: group1,
       behavior: () => {
-        this.weakElements(this.elements);
-        this.startAnimation([smokeFan2Right]);
-        this.strongElements([smokeFan2Right]);
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan2Right, smokeTunnelMajor]);
+        });
       },
     });
     this.modules.push({
       name: 'fan1LeftOpen',
       context: group1,
       behavior: () => {
-        this.weakElements(this.elements);
-        this.startAnimation([smokeFan1Left]);
-        this.strongElements([smokeFan1Left]);
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan1Left, smokeTunnelRight, smokeTunnelLeft]);
+        });
       },
     });
     this.modules.push({
       name: 'fan2LeftOpen',
       context: group1,
       behavior: () => {
-        this.weakElements(this.elements);
-        this.startAnimation([smokeFan2Left]);
-        this.strongElements([smokeFan2Left]);
+        this.stopAnimation(this.elements).then(() => {
+          this.startAnimation([smokeFan2Left, smokeTunnelRight, smokeTunnelLeft]);
+        });
+      },
+    });
+  }
+
+  /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入传入的锚点中 */
+  initCssElement() {
+    const selectors = [
+      {
+        query: '#inputBox2',
+        position: [-90, 9, -10],
       },
+      {
+        query: '#inputBox3',
+        position: [-90, 9, 30],
+      },
+      {
+        query: '#T1_1',
+        position: [80, 9, -10],
+      },
+      {
+        query: '#T1_2',
+        position: [20, 9, -10],
+      },
+      {
+        query: '#T2_1',
+        position: [-40, 9, -50],
+      },
+      {
+        query: '#T2_2',
+        position: [30, 9, -50],
+      },
+      {
+        query: '#T3',
+        position: [58, 9, -50],
+      },
+    ];
+    selectors.forEach(({ query, position }, index) => {
+      const element = document.querySelector(query) as HTMLElement;
+      if (element) {
+        const css3D = new CSS3DSprite(element);
+        this.cssSprites.push(css3D);
+        css3D.name = query;
+        css3D.scale.set(0.05, 0.05, 0.05);
+        // const ff = gui.addFolder(`css元素${index}`);
+        // ff.add(css3D.position, 'x', -100, 100);
+        // ff.add(css3D.position, 'y', -100, 100);
+        // ff.add(css3D.position, 'z', -100, 100);
+        css3D.position.set(position[0], position[1], position[2]);
+        this.group?.add(css3D);
+      }
     });
   }
 
   /** 生成适用于 Smoke 的曲线数据,输入途径点,输出路径,如果是进风类型,首个线段将有扩散效果,出风则是末尾线段有扩散效果 */
-  generateSmokePath(points: THREE.Vector3[], airIn?: boolean, airOut?: boolean) {
+  generateSmokePath(namelist: string[], airIn?: boolean, airOut?: boolean) {
+    if (!this.group) return;
     const result: any[] = [];
+    const points: THREE.Vector3[] = namelist.map((name) => {
+      const obj = this.group?.getObjectByName(name);
+      return obj?.position as THREE.Vector3;
+    });
     for (let index = 1; index < points.length; index++) {
       const path0 = points[index - 1];
       const path1 = points[index];
@@ -298,6 +332,10 @@ class ModelContext {
         path.isSpread = index === points.length - 1;
         path.spreadDirection = 1;
       }
+      if (!airIn && !airOut) {
+        path.isSpread = false;
+        path.spreadDirection = 1;
+      }
       result.push(path);
     }
     return result;

Разница между файлами не показана из-за своего большого размера
+ 666 - 596
src/views/vent/monitorManager/fanLocalMonitor/index.vue


Некоторые файлы не были показаны из-за большого количества измененных файлов