浏览代码

模型优化

lianghanqiang 4 年之前
父节点
当前提交
cab30ee81c

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
     "@dvgis/dc-ui": "^1.0.0-Beta",
     "@jiaminghi/charts": "^0.2.18",
     "@jiaminghi/data-view": "^2.10.0",
+    "@tweenjs/tween.js": "^18.6.4",
     "animate.css": "^4.1.1",
     "avue-data": "^2.0.0",
     "avue-plugin-map": "^1.0.1",

二进制
public/gltf/5H/JZ_5H_BL_GC_B.jpg


二进制
public/gltf/5H/JZ_5H_BL_SY.jpg


二进制
public/gltf/5H/JZ_5H_LG_GC.jpg


二进制
public/gltf/5H/JZ_5H_LG_SY.jpg


二进制
public/gltf/5H/JZ_5_BoLi_GC.jpg


+ 21 - 2
src/components/3DScene/3DScene.vue

@@ -15,9 +15,10 @@ import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
 import Box1 from "../3DMap/map-components/infobox/box1";
 import InfoLayer from "../3DMap/map-components/InfoLayer";
 import MapForScene from "./map";
-
+import TWEEN from '@tweenjs/tween.js'
 import Box2 from "../3DMap/map-components/infobox/box2";
 import {getBox1, getCameraBox} from "./infoBox";
+import { createLogger } from 'vuex';
 
 export default {
   name: "Scene3D",
@@ -41,6 +42,7 @@ export default {
       mesh: null,
       controls: null,
       container: null,
+      tween: {},
     }
   },
   props: {
@@ -157,6 +159,7 @@ export default {
     },
     //初始化场景
     async init() {
+      
       //挂载容器
       let container = document.getElementById('3DScene');
 
@@ -196,7 +199,6 @@ export default {
 
       //控制器
         this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
-      console.log(this.controls,9999)
       this.controls.minDistance = this.controlsOption.minDistance;
       this.controls.maxDistance = this.controlsOption.maxDistance;
       this.controls.autoRotate = this.controlsOption.autoRotate;
@@ -221,6 +223,7 @@ export default {
       this.controls.update();
       this.renderer.render(this.scene, this.camera);
       this.labelRenderer.render( this.scene, this.camera );
+      TWEEN.update();
     },
     //设置背景颜色
     setBackground(color){
@@ -255,7 +258,23 @@ export default {
     onMouseClick(){
      // alert(1);
     },
+    //漫游视角到指定位置
+    flyto(to,from=this.camera.position,time=1000){
+      let _this = this;
+      const {x,y,z} = to;
+      console.log(this.controls,123456);
+      this.tween = new TWEEN.Tween(from)
+      .to({x:x+50,y:y+50,z:z+50},time)
+      .easing(TWEEN.Easing.Quadratic.InOut);
 
+      this.tween.onUpdate(function(){
+        _this.controls.target.set(x,y,z);
+      })
+      this.tween.onComplete(()=>{
+        this.camera.lookAt(to)
+      })
+      this.tween.start();
+    }
   },
 
   async mounted() {

+ 5 - 3
src/components/scene/mainScene.vue

@@ -272,11 +272,13 @@ export default {
       this.matingInfo.resize();
       this.enterpriseTypeInfo.resize();
     },
-    infoBoxShow(){
-      this.isOpen= !this.isOpen;
+    infoBoxShow(show){
+      if(typeof show == "undefined"){
+        this.isOpen= !this.isOpen;
+      }
       this.$children.forEach(item => {
         if(typeof item['isOpen'] != 'undefined'){
-          item['isOpen'] = this.isOpen;
+          item['isOpen'] = typeof show == "undefined"? this.isOpen:show;
         }
       })
     },

+ 148 - 37
src/views/park/index.vue

@@ -10,6 +10,30 @@
     <loading ref="loading" :schedule="loadingSchedule" :total="gltf.length" :current="finishNum" text="信阳榕基软件园"></loading>
     <!--  工具栏   -->
     <tools-bar :option="toolsOption" v-if="isReady"></tools-bar>
+    <!-- 操作面板 -->
+    <dv-border-box-7 :color="['rgba(0,0,0,0.5)','rgba(230, 160, 9, 0.5)']" backgroundColor="rgba(0,0,0,0.5)" v-if="handlePanelShow" class="handle-panel">
+      <div class="full">
+        <div class="center" style="width: 100%;height: 70px;">
+          <div class="center" style="width: 60%;height: 100%;">
+            <el-input  v-model="searchText" placeholder="请输入关键字"></el-input>
+          </div>
+          <div @click="handleNext(-1)" class="click" style="width: 15%;height: 100%;" :style="{background: 'url(/img/left.png) no-repeat center/50%'}"></div>
+          <div @click="handleNext(1)" class="click" style="width: 15%;height: 100%;" :style="{background: 'url(/img/right.png) no-repeat center/50%'}"></div>
+        </div>
+      <div class="search-body" >
+        <div class="full" v-if="searchType=='building'">
+          <div class="search-item" v-for="(item,index) of buildings">
+            <div @click="toBuilding(index)" class="center full building-click" style="color: white;font-size: 20px;letter-spacing: 3px;">{{item.text}}</div>
+          </div>
+        </div>
+      </div>
+      <div class="search-footer center">
+        <!-- <div class="center click" style="width: 30%;height: 100%;">上一页</div> -->
+        <div @click="quitToolPanel" class="center click" style="width: 40%;height: 100%;">退出</div>
+        <!-- <div class="center click" style="width: 30%;height: 100%;">下一页</div> -->
+      </div>
+      </div>
+    </dv-border-box-7>
   </div>
 </template>
 
@@ -29,12 +53,16 @@ export default {
   data(){
     return{
       mesh: {},
+      searchText: "",
+      searchType: "building",
+      searchIndex: 0,
       isReady: false,
+      handlePanelShow: false,
       toolsOption:[
         { icon: '/data/round.png',name: '旋转',event:this.round},
         { icon: '/data/full.png',name: '全屏',event:this.handleFull},
         { icon: '/img/building.png',name: '建筑信息',event:()=>{this.showBox(this.buildingObj)}},
-        { icon: '/img/camera.png',name: '摄像头',event:()=>{this.showBox(this.cameraObj)}},
+        { icon: '/img/camera.png',name: '摄像头',event:()=>{this.showCamera()}},
         { icon: '/img/infobox.png',name: '信息框',event:()=>{this.$refs['data-panel'].infoBoxShow()}},
       ],
       finishNum: 0,
@@ -43,6 +71,7 @@ export default {
       gltf: [
         '/gltf/7_8/20H.gltf',
         '/gltf/5H/5H.gltf',
+        '/gltf/3H/3H.gltf',
         '/gltf/7H/7H.gltf',
         '/gltf/13H/13H.gltf',
         '/gltf/14H/14H.gltf',
@@ -51,7 +80,7 @@ export default {
         '/gltf/DX2/DX2.gltf',
         '/gltf/TiKuai/TiKuai.gltf',
         '/gltf/SKY/Sky.gltf',
-        '/gltf/Tree_car/Tree_car.gltf',
+        '/gltf/Tree_Car/Tree_Car.gltf',
       ],
       controlsOption: {
         minDistance : 100,
@@ -87,12 +116,16 @@ export default {
       buildings: [
         { text: '软件园主楼',position: [100,115,100]},
         { text: '软件园副楼',position: [170,50,50]},
+        { text: '软件园A栋',position: [0,105,110]},
+        { text: '软件园B栋',position: [-70,105,110]},
+        { text: '软件园C栋',position: [-120,105,55]},
+        { text: '软件园D栋',position: [-120,105,-20]},
       ],
       cameraList: [
-        { number: 'HK-nm51658186',position: [-690,0,-1200],src: '/video/video1.mp4'},
-        { number: 'HK-nm51658186',position: [-2000,0,3000],src: '/video/video2.mp4'},
-        { number: 'HK-nm51658186',position: [3600,0,2000],src: '/video/video3.mp4'},
-        { number: 'HK-nm51658186',position: [1300,0,500],src: '/video/video4.mp4'},
+        { number: 'HK-nm51658186',position: [100,0,200],src: '/video/video1.mp4'},
+        { number: 'HK-nm51658186',position: [50,0,70],src: '/video/video2.mp4'},
+        { number: 'HK-nm51658186',position: [-100,0,100],src: '/video/video3.mp4'},
+        { number: 'HK-nm51658186',position: [100,0,20],src: '/video/video4.mp4'},
       ],
       cameraObj: {},
       buildingObj: {},
@@ -107,6 +140,21 @@ export default {
     this.$refs['loading'].showLoading();
   },
   methods: {
+    handleNext(num){
+      this.searchIndex=(this.searchIndex+num)%this.buildings.length;
+      if(this.searchIndex<0){
+        this.searchIndex=this.buildingObj.children.length+this.searchIndex;
+      }
+      this.buildingObj.children.forEach((item,index) => { 
+        console.log(this.searchIndex,index);
+        if(index==this.searchIndex){
+          this.$refs['scene'].flyto(item.position);
+          item.visible = true;
+        }else{
+          item.visible=false;
+        }
+      })
+    },
    async initScene(){
       this.$refs['scene'].scene.fog = new Three.Fog( this.$refs['scene'].scene.background, 1, 5000);
       //添加天空盒
@@ -131,33 +179,50 @@ export default {
      // this.$refs['scene'].controls.autoRotate = true;
 
     },
-    async addObj(){
-      for (const item of this.obj) {
-         await this.$refs['scene'].addObj(item.mtlUrl,item.objUrl,
-          (loadedMesh)=>{
-          // 加载完obj文件是一个场景组,遍历它的子元素,赋值纹理并且更新面和点的发现了
-          loadedMesh.children.forEach( (child) => {
-            if (child instanceof Three.Mesh) {
-              child.material.side = Three.DoubleSide;
-              child.material.color = (new Three.Color("rgb(255,255,255)"))
-              if(child.name=='TiKuai'){
-                child.material.color = (new Three.Color("rgb(200,200,200)"))
-              }
-            }
-            loadedMesh.castShadow = true;
-          });
-          loadedMesh.scale.set(15, 15, 15);
-          this.objs.push(loadedMesh);
-          this.$refs['scene'].scene.add(loadedMesh);
-        },
-          (xhr)=>
-          {
-            this.loadingSchedule = (Math.floor((xhr.loaded/xhr.total)*1000)*0.1+'').substring(0,4);
-            if(this.loadingSchedule=='100'){
-              this.finishNum++;
-            }
-          })
-      }
+    toBuilding(objIndex){
+      this.buildingObj.children.forEach((item,index)=>{
+        if(objIndex==index){
+          this.searchIndex = index;
+          this.$refs['scene'].flyto(item.position);
+          item.visible = true;
+        }else{
+          item.visible=false;
+        }
+      })
+    },
+    // async addObj(){
+    //   for (const item of this.obj) {
+    //      await this.$refs['scene'].addObj(item.mtlUrl,item.objUrl,
+    //       (loadedMesh)=>{
+    //       // 加载完obj文件是一个场景组,遍历它的子元素,赋值纹理并且更新面和点的发现了
+    //       loadedMesh.children.forEach( (child) => {
+    //         if (child instanceof Three.Mesh) {
+    //           child.material.side = Three.DoubleSide;
+    //           child.material.color = (new Three.Color("rgb(255,255,255)"))
+    //           if(child.name=='TiKuai'){
+    //             child.material.color = (new Three.Color("rgb(200,200,200)"))
+    //           }
+    //         }
+    //         loadedMesh.castShadow = true;
+    //       });
+    //       loadedMesh.scale.set(15, 15, 15);
+    //       this.objs.push(loadedMesh);
+    //       this.$refs['scene'].scene.add(loadedMesh);
+    //     },
+    //       (xhr)=>
+    //       {
+    //         this.loadingSchedule = (Math.floor((xhr.loaded/xhr.total)*1000)*0.1+'').substring(0,4);
+    //         if(this.loadingSchedule=='100'){
+    //           this.finishNum++;
+    //         }
+    //       })
+    //   }
+    // },
+    quitToolPanel(){
+      this.handlePanelShow = false;
+      this.buildingObj.children.forEach(item => {
+        item.visible = false;
+      })
     },
     async addGltf(){
       this.gltf.forEach(item => {
@@ -168,6 +233,7 @@ export default {
               child.castShadow = true;
               child.receiveShadow = true;
             if ( child.isMesh ) {
+              console.log(child,546546);
               child.material.color = new Three.Color("rgb(200,200,200)");
               child.material.side = Three.DoubleSide;
               child.material.emissive =  child.material.color;
@@ -185,7 +251,6 @@ export default {
           (xhr)=>{
             if(xhr.total==xhr.loaded){
               // this.finishNum++;
-
             }
           });
       })
@@ -231,10 +296,20 @@ export default {
     },
     showBox(list){
       this.$refs['scene'].controls.autoRotate = false;
+      this.handlePanelShow = true;
+      this.searchIndex = 0;
+      if(list.children.length>0){
+        list.children[0].visible = true;
+        this.$refs['data-panel'].infoBoxShow(false)
+        this.$refs['scene'].flyto(list.children[0].position)
+      }
+      
+    },
+    showCamera(){
+      const list = this.cameraObj;
       list.children.forEach((item,index) => {
-        item.visible = !item.visible;
-      })
-
+              item.visible = !item.visible;
+            })
     },
     handleFull(){
       fullscreenToggel();
@@ -247,5 +322,41 @@ export default {
 </script>
 
 <style scoped>
+  .handle-panel{
+    width: 20%;
+    height: 430px;
+    /* background: rgba(230, 160, 9, 0.5); */
+    position: absolute;
+    top: 200px;
+    left: 3%;
+  }
+  .search-body{
+    overflow-y: scroll;
+    width: 100%;height: 300px;
+  }
+  .search-footer{
+    width: 100%;height: 60px;
+    background: rgba(0, 0, 0, 0.5);
+    color: whitesmoke;
+    font-size: 18px;
+  }
+  .search-item{
+    width: 95%;
+    margin: auto;
+    height: 45px;
+    border-bottom: 1px solid #525252;
+  }
+  .click:hover{
+    cursor: pointer;
+    transform: translate(1px,1px);
+  }
+  .click:active{
+    cursor: pointer;
+    transform: translate(2px,2px);
+  }
+  .building-click:hover{
+      cursor: pointer;
+      text-shadow: 2px 2px 2px #ccffb4;
+  }
 
 </style>