Koishi 3 mesiacov pred
rodič
commit
92623634cb

BIN
public/static/model/fengjiduli/model.glb


+ 201 - 56
src/components/modelUnpack.vue

@@ -1,6 +1,24 @@
 
 <template>
-  <div ref="threeCanvas" style="width: 100%; height: 100%"></div>
+  <div class="modelBox">
+    <div ref="threeCanvas" style="width: 100%; height: 100%"></div>
+    <div class="bjSelectBox">
+        <el-select
+          v-model="bj"
+          placeholder="完整展示"
+          style="width: 300px"
+          clearable
+          @change="bjChange"
+        >
+          <el-option
+            v-for="item in bjList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.uuid"
+          />
+        </el-select>
+    </div>
+  </div>
 </template>
  
 <script>
@@ -62,6 +80,9 @@ export default {
       orbitControls: null,
       css3DRenderer: null,
       animationId: null,
+      basicModel: null,
+      bj: "",
+      bjList: [],
     };
   },
 
@@ -74,6 +95,27 @@ export default {
   },
 
   methods: {
+    bjChange(uuid) {
+      let modelBjList = this.scene.children.find((modelEle) => {
+        return !modelEle.isLight && !modelEle.isLineSegments;
+      });
+      if (uuid) {
+        modelBjList.children.forEach((ele) => {
+          if (ele.uuid === uuid) {
+            this.focusOnPart(ele);
+            ele.visible = true;
+          } else {
+            ele.visible = false;
+          }
+        });
+      } else {
+        this.focusOnPart(this.basicModel);
+        modelBjList.children.forEach((ele) => {
+          ele.visible = true;
+        });
+      }
+    },
+
     initThree(options) {
       this.$nextTick(() => {
         const parentDom = getComputedStyle(
@@ -111,24 +153,24 @@ export default {
         });
 
         // 添加灯光
-        const ambientLight = new THREE.AmbientLight(0xffffff, 1);
+        const ambientLight = new THREE.AmbientLight(0xffffff, 5);
         scene.add(ambientLight);
-        const directionalLight1 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight1 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight1.position.set(0, 0, 1);
         scene.add(directionalLight1);
-        const directionalLight2 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight2 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight2.position.set(0, 0, -1);
         scene.add(directionalLight2);
-        const directionalLight3 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight3 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight3.position.set(1, 0, 0);
         scene.add(directionalLight3);
-        const directionalLight4 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight4 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight4.position.set(-1, 0, 0);
         scene.add(directionalLight4);
-        const directionalLight5 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight5 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight5.position.set(0, 1, 0);
         scene.add(directionalLight5);
-        const directionalLight6 = new THREE.DirectionalLight(0xffffff, 5);
+        const directionalLight6 = new THREE.DirectionalLight(0xffffff, 3);
         directionalLight6.position.set(0, -1, 0);
         scene.add(directionalLight6);
 
@@ -205,7 +247,7 @@ export default {
           options?.dom?.appendChild(warning);
         }
 
-        this.addModel({ fileName: "SolarPowerPlant" });
+        this.addModel({ fileName: "fengji" });
       });
     },
 
@@ -230,42 +272,134 @@ export default {
       const loader = this.loader[fileType];
       loader.setResourcePath(`./static/model/${fileName}/`);
       loader.load(`./static/model/${fileName}/model.${fileType}`, (result) => {
-        const model = result.scene;
+        this.basicModel = this.formatModel(result.scene);
+        this.basicModel.isCurrentAddModel = true;
 
-        const camera = this.camera;
+        let bjList = [];
+        this.basicModel.children.forEach((bj) => {
+          bjList.push(bj);
+        });
 
-        // model.traverse((child) => {
-        //   if (child.material) {
-        //     child.material.emissive = child.material.color;
-        //     child.material.emissiveMap = child.material.map;
-        //   }
-        // });
+        this.bjList = bjList;
 
-        // model.children.forEach((item, index) => {
-        //   item.castShadow = true;
-        //   item.receiveShadow = true;
-        // });
+        this.collectMaterialInfo(this.basicModel);
+        this.scene.add(this.basicModel);
+      });
+    },
 
-        const baseBoxSize = new THREE.Vector3(100, 100, 100);
-        // 计算模型的包围盒(bounding box)
-        const boundingBox = new THREE.Box3().setFromObject(model);
-        const modelSize = new THREE.Vector3();
-        boundingBox.getSize(modelSize);
+    // 调整视角到选中部件
+    focusOnPart(part) {
+      const box = new THREE.Box3().setFromObject(part);
+      const size = box.getSize(new THREE.Vector3());
+      const center = box.getCenter(new THREE.Vector3());
+      const speed = 0.5;
+
+      // 计算最佳相机距离
+      const maxDim = Math.max(size.x, size.y, size.z);
+      const cameraDistance = maxDim * parseFloat(speed);
+
+      // 计算相机位置
+      const direction = this.orbitControls.target
+        .clone()
+        .sub(this.camera.position)
+        .normalize();
+      const cameraPosition = center
+        .clone()
+        .sub(direction.multiplyScalar(cameraDistance));
+
+      // 是否启用平滑过渡
+      const smooth = true;
+
+      if (smooth) {
+        // 平滑过渡到新位置
+        this.animateCamera(
+          this.camera.position,
+          cameraPosition,
+          this.orbitControls.target,
+          center,
+          speed
+        );
+      } else {
+        // 直接设置新位置
+        this.camera.position.copy(cameraPosition);
+        this.orbitControls.target.copy(center);
+        this.orbitControls.update();
+      }
+    },
 
-        // 计算模型的最大尺寸
-        const maxModelSize = Math.max(modelSize.x, modelSize.y, modelSize.z);
+    // 平滑移动相机
+    animateCamera(fromPosition, toPosition, fromTarget, toTarget, speed) {
+      const that = this;
+      const duration = 1000; // 动画持续时间(ms)
+      const startTime = Date.now();
 
-        // 计算缩放比例,使模型尺寸不超过基准盒子的尺寸
-        const scaleFactor = baseBoxSize.clone().divideScalar(maxModelSize);
+      // 缓动函数
+      let easeInOutCubic = (t) => {
+        return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
+      };
 
-        // 将模型等比例缩放到适应基准盒子大小
-        model.scale.set(scaleFactor.x, scaleFactor.y, scaleFactor.z);
+      function update() {
+        const elapsed = Date.now() - startTime;
+        const progress = Math.min(elapsed / duration, 1);
 
-        camera.position.z = 200;
-        console.log(222, model);
-        this.collectMaterialInfo(model);
-        this.scene.add(model);
-      });
+        // 使用缓动函数
+        const easeProgress = easeInOutCubic(progress);
+
+        // 插值计算相机位置和目标位置
+        that.camera.position.lerpVectors(
+          fromPosition,
+          toPosition,
+          easeProgress
+        );
+        that.orbitControls.target.lerpVectors(
+          fromTarget,
+          toTarget,
+          easeProgress
+        );
+        that.orbitControls.update();
+
+        if (progress < 1) {
+          requestAnimationFrame(update);
+        }
+      }
+
+      update();
+    },
+
+    formatModel(model) {
+      this.renderer.outputColorSpace = THREE.SRGBColorSpace;
+      const camera = this.camera;
+
+      // model.traverse((child) => {
+      //   if (child.material) {
+      //     child.material.emissive = child.material.color;
+      //     child.material.emissiveMap = child.material.map;
+      //   }
+      // });
+
+      // model.children.forEach((item, index) => {
+      //   item.castShadow = true;
+      //   item.receiveShadow = true;
+      // });
+
+      const baseBoxSize = new THREE.Vector3(100, 100, 100);
+      // 计算模型的包围盒(bounding box)
+      const boundingBox = new THREE.Box3().setFromObject(model);
+      const modelSize = new THREE.Vector3();
+      boundingBox.getSize(modelSize);
+
+      // 计算模型的最大尺寸
+      const maxModelSize = Math.max(modelSize.x, modelSize.y, modelSize.z);
+
+      // 计算缩放比例,使模型尺寸不超过基准盒子的尺寸
+      const scaleFactor = baseBoxSize.clone().divideScalar(maxModelSize);
+
+      // 将模型等比例缩放到适应基准盒子大小
+      model.scale.set(scaleFactor.x, scaleFactor.y, scaleFactor.z);
+
+      camera.position.z = 200;
+      console.log("model", model);
+      return model;
     },
 
     collectMaterialInfo(model) {
@@ -285,29 +419,26 @@ export default {
 
           materials.forEach((material, index) => {
             if (material.name === "Mesh_225") {
-              
             }
             info.push(`材质 ${materialCount}-${index + 1}: ${material.type}`);
-              info.push(`  名称: ${material.name || "未命名"}`);
-              info.push(
-                `  颜色: ${
-                  material.color ? material.color.getHexString() : "无"
-                }`
-              );
-              info.push(`  贴图: ${material.map ? "有" : "无"}`);
-              info.push(`  自发光贴图: ${material.emissiveMap ? "有" : "无"}`);
-              info.push(
-                `  金属粗糙度贴图: ${material.metalnessMap ? "有" : "无"}`
-              );
-              info.push(`  法线贴图: ${material.normalMap ? "有" : "无"}`);
-              info.push("---");
-
-              // 保存原始材质引用
-              originalMaterials.set(node.uuid + "-" + index, material);
+            info.push(`  名称: ${material.name || "未命名"}`);
+            info.push(
+              `  颜色: ${material.color ? material.color.getHexString() : "无"}`
+            );
+            info.push(`  贴图: ${material.map ? "有" : "无"}`);
+            info.push(`  自发光贴图: ${material.emissiveMap ? "有" : "无"}`);
+            info.push(
+              `  金属粗糙度贴图: ${material.metalnessMap ? "有" : "无"}`
+            );
+            info.push(`  法线贴图: ${material.normalMap ? "有" : "无"}`);
+            info.push("---");
+
+            // 保存原始材质引用
+            originalMaterials.set(node.uuid + "-" + index, material);
           });
         }
       });
-      console.log(333, info);
+      // console.log(333, info);
     },
 
     overrideMaterials() {
@@ -386,4 +517,18 @@ export default {
     },
   },
 };
-</script>
+</script>
+
+<style lang="less" scoped>
+.modelBox {
+  width: 100%;
+  height: 100%;
+  position: relative;
+
+  .bjSelectBox {
+    position: absolute;
+    left: 5px;
+    top: 5px;
+  }
+}
+</style>

+ 2 - 2
src/views/cesium.vue

@@ -164,7 +164,7 @@ export default {
 
   data() {
     return {
-      showFjDialog: false,
+      showFjDialog: true,
       showFjDialogActiveName: "jcxx",
       checkMode: false, // 调试模式
       allyShow: false,
@@ -305,7 +305,7 @@ export default {
 
       // 添加一些3D模型
       this.addModel(
-        "./static/model/SolarPowerPlant/model.glb",
+        "./static/model/fengjiduli/model.glb",
         "风机",
         106.169866,
         38.46637