123
						commit
						c61eb163e0
					
				
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 5.5 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
						 | 
				
			
			@ -14,6 +14,7 @@
 | 
			
		|||
import bimStore from '@/store/modules/bim';
 | 
			
		||||
import { nextTick } from "vue";
 | 
			
		||||
const myTree = ref("myTree");
 | 
			
		||||
import Bus from '@/utils/bus.js';
 | 
			
		||||
const applicationOptions = [
 | 
			
		||||
    {
 | 
			
		||||
        value: '0',
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +63,10 @@ onMounted(() => {
 | 
			
		|||
});
 | 
			
		||||
const handleNodeClick = (value) => {
 | 
			
		||||
    bimStore().setActivateTree(value);
 | 
			
		||||
    emit('handleNodeClick', value)
 | 
			
		||||
    emit('handleNodeClick', value);
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        Bus.emit('clickApplication');
 | 
			
		||||
    }, 100)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,13 @@
 | 
			
		|||
<script setup>
 | 
			
		||||
import bimStore from '@/store/modules/bim';
 | 
			
		||||
import { nextTick } from "vue";
 | 
			
		||||
import bus from '@/utils/bus.js'
 | 
			
		||||
import Bus from '@/utils/bus.js';
 | 
			
		||||
 | 
			
		||||
const myTree = ref("myTree");
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    isSetTree: { // 
 | 
			
		||||
        default: false,
 | 
			
		||||
        type: Boolean
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
const buildOptions = [
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,85 +67,106 @@ const data = reactive({
 | 
			
		|||
                    value: 100
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            children: [
 | 
			
		||||
                {
 | 
			
		||||
                    label: '原料糖化车间一',
 | 
			
		||||
                    id: '0-1',
 | 
			
		||||
                    url: '/jz/glb/scene.gltf',
 | 
			
		||||
                    children: [{
 | 
			
		||||
                        label: '罐子1',
 | 
			
		||||
                        id: '0-0-1',
 | 
			
		||||
                        children:[]
 | 
			
		||||
                    },{
 | 
			
		||||
                        label: '罐子2',
 | 
			
		||||
                        id: '0-0-2',
 | 
			
		||||
                        children:[]
 | 
			
		||||
                    }],
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '原料糖化车间一',
 | 
			
		||||
                        area: '5200 ㎡',
 | 
			
		||||
                        status: '启用',
 | 
			
		||||
                        desc: '原料糖化车间一,负责原料糖化,启用于2011年'
 | 
			
		||||
                    },
 | 
			
		||||
                    deviceInfo: [
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '生产设备',
 | 
			
		||||
                            name: '立仓',
 | 
			
		||||
                            value: 15
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '空调设备',
 | 
			
		||||
                            name: '新风机组',
 | 
			
		||||
                            value: 50
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '安防设备',
 | 
			
		||||
                            name: '摄像头',
 | 
			
		||||
                            value: 80
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '消防设备',
 | 
			
		||||
                            name: '烟感',
 | 
			
		||||
                            value: 50
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
 | 
			
		||||
            children: [{
 | 
			
		||||
                label: '糖化间',
 | 
			
		||||
                id: '0-0-1',
 | 
			
		||||
                clickName: 'tanghua_room',
 | 
			
		||||
                info: {
 | 
			
		||||
                    name: '糖化间',
 | 
			
		||||
                    area: '9436 ㎡',
 | 
			
		||||
                    status: '启用',
 | 
			
		||||
                    desc: '糖化间,负责原料糖化,启用于2011年'
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    label: '原料糖化车间二',
 | 
			
		||||
                    id: '0-2',
 | 
			
		||||
                    url: '/jz/glb/scene.gltf',
 | 
			
		||||
                    children: [],
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '原料糖化车间二',
 | 
			
		||||
                        area: '4236 ㎡',
 | 
			
		||||
                        status: '启用',
 | 
			
		||||
                        desc: '原料糖化车间二,负责原料糖化,启用于2013年'
 | 
			
		||||
                deviceInfo: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '生产设备',
 | 
			
		||||
                        name: '立仓',
 | 
			
		||||
                        value: 95
 | 
			
		||||
                    },
 | 
			
		||||
                    deviceInfo: [
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '生产设备',
 | 
			
		||||
                            name: '立仓',
 | 
			
		||||
                            value: 30
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '空调设备',
 | 
			
		||||
                            name: '新风机组',
 | 
			
		||||
                            value: 80
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '安防设备',
 | 
			
		||||
                            name: '摄像头',
 | 
			
		||||
                            value: 100
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: '消防设备',
 | 
			
		||||
                            name: '烟感',
 | 
			
		||||
                            value: 50
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '空调设备',
 | 
			
		||||
                        name: '新风机组',
 | 
			
		||||
                        value: 100
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '安防设备',
 | 
			
		||||
                        name: '摄像头',
 | 
			
		||||
                        value: 90
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '消防设备',
 | 
			
		||||
                        name: '烟感',
 | 
			
		||||
                        value: 100
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                children: []
 | 
			
		||||
            }, {
 | 
			
		||||
                label: '原料处理间',
 | 
			
		||||
                id: '0-0-2',
 | 
			
		||||
                clickName: 'yuanliao_room',
 | 
			
		||||
                info: {
 | 
			
		||||
                    name: '原料处理间',
 | 
			
		||||
                    area: '9436 ㎡',
 | 
			
		||||
                    status: '启用',
 | 
			
		||||
                    desc: '原料糖化车间,负责原料糖化,启用于2011年'
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
                deviceInfo: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '生产设备',
 | 
			
		||||
                        name: '立仓',
 | 
			
		||||
                        value: 85
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '空调设备',
 | 
			
		||||
                        name: '新风机组',
 | 
			
		||||
                        value: 130
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '安防设备',
 | 
			
		||||
                        name: '摄像头',
 | 
			
		||||
                        value: 100
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '消防设备',
 | 
			
		||||
                        name: '烟感',
 | 
			
		||||
                        value: 150
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                children: []
 | 
			
		||||
            },{
 | 
			
		||||
                label: '投料间',
 | 
			
		||||
                id: '0-0-3',
 | 
			
		||||
                clickName: 'touliao_room',
 | 
			
		||||
                info: {
 | 
			
		||||
                    name: '投料间',
 | 
			
		||||
                    area: '836 ㎡',
 | 
			
		||||
                    status: '启用',
 | 
			
		||||
                    desc: '投料间,负责原料糖化,启用于2011年'
 | 
			
		||||
                },
 | 
			
		||||
                deviceInfo: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '生产设备',
 | 
			
		||||
                        name: '立仓',
 | 
			
		||||
                        value: 115
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '空调设备',
 | 
			
		||||
                        name: '新风机组',
 | 
			
		||||
                        value: 90
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '安防设备',
 | 
			
		||||
                        name: '摄像头',
 | 
			
		||||
                        value: 100
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: '消防设备',
 | 
			
		||||
                        name: '烟感',
 | 
			
		||||
                        value: 40
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                children: []
 | 
			
		||||
            }],
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    checkedkeys: ""
 | 
			
		||||
| 
						 | 
				
			
			@ -162,17 +180,14 @@ onMounted(() => {
 | 
			
		|||
    })
 | 
			
		||||
});
 | 
			
		||||
const handleNodeClick = (value) => {
 | 
			
		||||
    if(props.isSetTree) {// 是否存值
 | 
			
		||||
        bimStore().setActivateTree(value);
 | 
			
		||||
    }
 | 
			
		||||
    bimStore().setActivateTree(value);
 | 
			
		||||
    const isParent = value.children.length > 0;
 | 
			
		||||
    emit('handleNodeClick', value, isParent);
 | 
			
		||||
 | 
			
		||||
    bus.emit('foo');
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        Bus.emit('clickBuild', isParent);
 | 
			
		||||
    }, 100)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.treeDiv {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ onMounted(() => {
 | 
			
		|||
})
 | 
			
		||||
 | 
			
		||||
watch(deviceInfo, (value) => {
 | 
			
		||||
    console.log(34, value);
 | 
			
		||||
    if (value) {
 | 
			
		||||
        initData();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
<script setup>
 | 
			
		||||
import bimStore from '@/store/modules/bim';
 | 
			
		||||
import { nextTick } from "vue";
 | 
			
		||||
import Bus from '@/utils/bus.js'
 | 
			
		||||
const myTree = ref("myTree");
 | 
			
		||||
const deviceOptions = [
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -39,26 +40,46 @@ const data = reactive({
 | 
			
		|||
            },
 | 
			
		||||
            children: [
 | 
			
		||||
                {
 | 
			
		||||
                    label: '立仓',
 | 
			
		||||
                    label: '设备一',
 | 
			
		||||
                    id: '0-1',
 | 
			
		||||
                    url: '/jz/glb/scene.gltf',
 | 
			
		||||
                    clickName: 'set1',
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '立仓',
 | 
			
		||||
                        name: '设备一',
 | 
			
		||||
                        type: '生产设备',
 | 
			
		||||
                        status: '启用'
 | 
			
		||||
                    },
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    label: '糖浆罐',
 | 
			
		||||
                    label: '设备二',
 | 
			
		||||
                    id: '0-2',
 | 
			
		||||
                    url: '/seraphine/scene.gltf',
 | 
			
		||||
                    clickName: 'set2',
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '糖浆罐',
 | 
			
		||||
                        name: '设备二',
 | 
			
		||||
                        type: '生产设备',
 | 
			
		||||
                        status: '启用'
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    label: '设备三',
 | 
			
		||||
                    id: '0-3',
 | 
			
		||||
                    clickName: 'set3',
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '设备三',
 | 
			
		||||
                        type: '空调设备',
 | 
			
		||||
                        status: '启用'
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    label: '设备四',
 | 
			
		||||
                    id: '0-4',
 | 
			
		||||
                    clickName: 'set4',
 | 
			
		||||
                    info: {
 | 
			
		||||
                        name: '设备四',
 | 
			
		||||
                        type: '安防设备',
 | 
			
		||||
                        status: '启用'
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +95,10 @@ onMounted(() => {
 | 
			
		|||
});
 | 
			
		||||
const handleNodeClick = (value) => {
 | 
			
		||||
    bimStore().setActivateDeviceTree(value);
 | 
			
		||||
    emit('handleNodeClick', value)
 | 
			
		||||
    emit('handleNodeClick', value);
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        Bus.emit('clickDevice');
 | 
			
		||||
    }, 100)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,377 +0,0 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="container">
 | 
			
		||||
    <div id="model"></div>
 | 
			
		||||
    <button
 | 
			
		||||
      id="btns"
 | 
			
		||||
      :style="{ cursor: isDisabled ? '' : 'pointer' }"
 | 
			
		||||
      :disabled="isDisabled"
 | 
			
		||||
      type="isDisabled:"
 | 
			
		||||
      @click="toHomeView(1)"
 | 
			
		||||
    >
 | 
			
		||||
      主视角
 | 
			
		||||
    </button>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import * as THREE from "three";
 | 
			
		||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
 | 
			
		||||
 | 
			
		||||
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
 | 
			
		||||
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
 | 
			
		||||
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
 | 
			
		||||
import TWEEN from "@tweenjs/tween.js";
 | 
			
		||||
export default {
 | 
			
		||||
  name: "ThreeModel",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      isDisabled: true,
 | 
			
		||||
      scene: null,
 | 
			
		||||
      renderer: null,
 | 
			
		||||
      controls: null,
 | 
			
		||||
      light: null,
 | 
			
		||||
      light2: null,
 | 
			
		||||
      group: new THREE.Group(),
 | 
			
		||||
      composer: null, // 控制发光
 | 
			
		||||
      outlinePass: null,
 | 
			
		||||
      renderPass: null,
 | 
			
		||||
      // 选中的模型
 | 
			
		||||
      selectedObjects: [],
 | 
			
		||||
      mouse: new THREE.Vector2(),
 | 
			
		||||
      raycaster: new THREE.Raycaster(),
 | 
			
		||||
      tween: null,
 | 
			
		||||
      //定义模型架子的长度
 | 
			
		||||
      long: 100,
 | 
			
		||||
      //定义模型架子的宽度
 | 
			
		||||
      tall: 24,
 | 
			
		||||
      //定义模型架子横纵板的宽度
 | 
			
		||||
      thickness: 0.4,
 | 
			
		||||
      positionObj: null,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  computed: {},
 | 
			
		||||
  watch: {},
 | 
			
		||||
  created() {},
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.init();
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    //创建模型视图
 | 
			
		||||
    initScene() {
 | 
			
		||||
      this.scene = new THREE.Scene();
 | 
			
		||||
    },
 | 
			
		||||
    //初始化相机
 | 
			
		||||
    initCamera() {
 | 
			
		||||
      const { long, tall } = this;
 | 
			
		||||
      this.camera = new THREE.PerspectiveCamera(
 | 
			
		||||
        45,
 | 
			
		||||
        window.innerWidth / window.innerHeight,
 | 
			
		||||
        0.1,
 | 
			
		||||
        50000
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      this.camera.position.set(0, -(5 * tall) / 12, (6 * long) / 5);
 | 
			
		||||
    },
 | 
			
		||||
    //初始化灯光
 | 
			
		||||
    initLight() {
 | 
			
		||||
      let ambientLight = new THREE.AmbientLight(0x404040);
 | 
			
		||||
      this.scene.add(ambientLight);
 | 
			
		||||
      this.light = new THREE.DirectionalLight(0x333333);
 | 
			
		||||
      this.light.position.set(60, 30, 40);
 | 
			
		||||
      this.light2 = new THREE.DirectionalLight(0xdddddd);
 | 
			
		||||
      this.light2.position.set(-20, 20, -20);
 | 
			
		||||
      this.scene.add(this.light);
 | 
			
		||||
      this.scene.add(this.light2);
 | 
			
		||||
    },
 | 
			
		||||
    //加载渲染器
 | 
			
		||||
    initRender() {
 | 
			
		||||
      //dom元素渲染器
 | 
			
		||||
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
 | 
			
		||||
      this.renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染区域尺寸
 | 
			
		||||
      this.renderer.setClearColor(0x000000, 0); // 设置背景颜色
 | 
			
		||||
      //window.devicePixelRatio 当前设备的物理分辨率与css分辨率之比
 | 
			
		||||
      this.renderer.setPixelRatio(window.devicePixelRatio);
 | 
			
		||||
      //按层级先后渲染
 | 
			
		||||
      this.renderer.sortObjects = true;
 | 
			
		||||
      document.getElementById("model").appendChild(this.renderer.domElement);
 | 
			
		||||
    },
 | 
			
		||||
    //创建载入模型
 | 
			
		||||
    initModel() {
 | 
			
		||||
      const { long, tall, thickness } = this;
 | 
			
		||||
      //坐标系
 | 
			
		||||
      // let axes = new THREE.AxesHelper(4000);
 | 
			
		||||
      // this.scene.add(axes);
 | 
			
		||||
 | 
			
		||||
      //所有横板
 | 
			
		||||
      for (let index = 1; index <= tall / 4 - 1; index++) {
 | 
			
		||||
        let geometry = new THREE.BoxGeometry(long, thickness, 12);
 | 
			
		||||
        let material = new THREE.MeshLambertMaterial({
 | 
			
		||||
          color: 0x808080,
 | 
			
		||||
          opacity: 0.7,
 | 
			
		||||
          transparent: true,
 | 
			
		||||
        }); //材质对象Material
 | 
			
		||||
        let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
 | 
			
		||||
        mesh.position.set(0, index * 4, 0); //设置mesh3模型对象的xyz坐标为120,0,0
 | 
			
		||||
        this.scene.add(mesh); //网格模型添加到场景中
 | 
			
		||||
      }
 | 
			
		||||
      //所有纵板
 | 
			
		||||
      for (let index = 1; index <= long / 4 + 1; index++) {
 | 
			
		||||
        let geometry = new THREE.BoxGeometry(thickness, tall, 12);
 | 
			
		||||
        let material = new THREE.MeshLambertMaterial({
 | 
			
		||||
          color: 0x808080,
 | 
			
		||||
          opacity: 0.7,
 | 
			
		||||
          transparent: true,
 | 
			
		||||
        }); //材质对象Material
 | 
			
		||||
        let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
 | 
			
		||||
        mesh.position.set(-long / 2 + (index - 1) * 4, tall / 2, 0); //设置mesh3模型对象的xyz坐标为120,0,0
 | 
			
		||||
        this.scene.add(mesh); //网格模型添加到场景中
 | 
			
		||||
      }
 | 
			
		||||
      //正面所有箱子
 | 
			
		||||
      let list1 = new Array(tall / 4);
 | 
			
		||||
      for (let i = 0; i < list1.length; i++) {
 | 
			
		||||
        list1[i] = new Array(long / 4);
 | 
			
		||||
        //不一定写for循环赋值,还可以直接赋值,在数量有限的情况下
 | 
			
		||||
        for (let j = 0; j < long / 4; j++) {
 | 
			
		||||
          // a[i][j] = i + j;
 | 
			
		||||
          let geometry = new THREE.BoxGeometry(3, 3, 5);
 | 
			
		||||
          let material = new THREE.MeshLambertMaterial({
 | 
			
		||||
            color: 0x00b1f7,
 | 
			
		||||
            opacity: 0.4,
 | 
			
		||||
            transparent: true,
 | 
			
		||||
          });
 | 
			
		||||
          let mesh = new THREE.Mesh(geometry, material);
 | 
			
		||||
          mesh.name = i + 1 + "-" + (j + 1);
 | 
			
		||||
          mesh.position.set(-long / 2 + j * 4 + 2, i * 4 + 2, 3);
 | 
			
		||||
          this.scene.add(mesh);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      //背面所有箱子
 | 
			
		||||
      let list2 = new Array(tall / 4);
 | 
			
		||||
      for (let i = 0; i < list2.length; i++) {
 | 
			
		||||
        list2[i] = new Array(long / 4);
 | 
			
		||||
        //不一定写for循环赋值,还可以直接赋值,在数量有限的情况下
 | 
			
		||||
        for (let j = 0; j < long / 4; j++) {
 | 
			
		||||
          // a[i][j] = i + j;
 | 
			
		||||
          let geometry = new THREE.BoxGeometry(3, 3, 5);
 | 
			
		||||
          let material = new THREE.MeshLambertMaterial({
 | 
			
		||||
            color: 0x00b1f7,
 | 
			
		||||
            opacity: 0.4,
 | 
			
		||||
            transparent: true,
 | 
			
		||||
          });
 | 
			
		||||
          let mesh = new THREE.Mesh(geometry, material);
 | 
			
		||||
 | 
			
		||||
          mesh.name = "-" + (i + 1) + "-" + (j + 1);
 | 
			
		||||
          mesh.position.set(-long / 2 + j * 4 + 2, i * 4 + 2, -3);
 | 
			
		||||
          this.scene.add(mesh);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    //高亮显示模型(呼吸灯)
 | 
			
		||||
    outlineObj(selectedObjects) {
 | 
			
		||||
      // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
 | 
			
		||||
      this.composer = new EffectComposer(this.renderer);
 | 
			
		||||
      // 新建一个场景通道  为了覆盖到原理来的场景上
 | 
			
		||||
      this.renderPass = new RenderPass(this.scene, this.camera);
 | 
			
		||||
      this.composer.addPass(this.renderPass);
 | 
			
		||||
      // 物体边缘发光通道
 | 
			
		||||
      this.outlinePass = new OutlinePass(
 | 
			
		||||
        new THREE.Vector2(window.innerWidth, window.innerHeight),
 | 
			
		||||
        this.scene,
 | 
			
		||||
        this.camera,
 | 
			
		||||
        selectedObjects
 | 
			
		||||
      );
 | 
			
		||||
      this.outlinePass.edgeStrength = 8.0; // 高光边缘边框的亮度
 | 
			
		||||
      this.outlinePass.edgeGlow = 1; // 光晕[0,1]  边缘微光强度
 | 
			
		||||
      this.outlinePass.usePatternTexture = false; // 是否使用父级的材质,纹理覆盖
 | 
			
		||||
      this.outlinePass.edgeThickness = 3; // 边框宽度,高光厚度
 | 
			
		||||
      this.outlinePass.downSampleRatio = 1; // 边框弯曲度
 | 
			
		||||
      this.outlinePass.pulsePeriod = 2; // 呼吸闪烁的速度,数值越大,律动越慢
 | 
			
		||||
      this.outlinePass.visibleEdgeColor.set(parseInt(0x00f6ff)); // 呼吸显示的颜色
 | 
			
		||||
      this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0); // 呼吸消失的颜色
 | 
			
		||||
      // this.outlinePass.clear = true
 | 
			
		||||
      this.composer.addPass(this.outlinePass); // 加入高光特效
 | 
			
		||||
      this.outlinePass.selectedObjects = selectedObjects; // 需要高光的模型
 | 
			
		||||
    },
 | 
			
		||||
    // 鼠标点击模型
 | 
			
		||||
    onMouseClick(event) {
 | 
			
		||||
      //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1
 | 
			
		||||
      this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
 | 
			
		||||
      this.mouse.y = -(event.clientY / (window.innerHeight - 50)) * 2 + 1;
 | 
			
		||||
      // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
 | 
			
		||||
      this.raycaster.setFromCamera(this.mouse, this.camera);
 | 
			
		||||
      // 获取raycaster直线和所有模型相交的数组集合
 | 
			
		||||
      let intersects = this.raycaster.intersectObjects(this.scene.children);
 | 
			
		||||
      if (!intersects[0]) {
 | 
			
		||||
        return;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (!intersects[0].object.name == "") {
 | 
			
		||||
          this.selectedObjects = [];
 | 
			
		||||
          this.selectedObjects.push(intersects[0].object);
 | 
			
		||||
          this.outlineObj(this.selectedObjects);
 | 
			
		||||
          this.positionObj = {
 | 
			
		||||
            x: intersects[0].object.position.x,
 | 
			
		||||
            y: intersects[0].object.position.y,
 | 
			
		||||
            z: intersects[0].object.position.z,
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          this.initTween(
 | 
			
		||||
            this.positionObj.x,
 | 
			
		||||
            this.positionObj.y,
 | 
			
		||||
            this.positionObj.z
 | 
			
		||||
          );
 | 
			
		||||
          this.isDisabled = false;
 | 
			
		||||
 | 
			
		||||
          this.controls.autoRotate = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // 相机移动动画
 | 
			
		||||
    initTween(targetX, targetY, targetZ) {
 | 
			
		||||
      // 需要保留this
 | 
			
		||||
      let initPosition = {
 | 
			
		||||
        x: this.camera.position.x,
 | 
			
		||||
        y: this.camera.position.y,
 | 
			
		||||
        z: this.camera.position.z,
 | 
			
		||||
      };
 | 
			
		||||
      let tween = new TWEEN.Tween(initPosition)
 | 
			
		||||
        .to({ x: targetX, y: targetY, z: targetZ }, 2000)
 | 
			
		||||
        .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
      let onUpdate = (pos) => {
 | 
			
		||||
        let x = pos.x;
 | 
			
		||||
        let y = pos.y;
 | 
			
		||||
        let z = pos.z;
 | 
			
		||||
        if (pos.z < 0) {
 | 
			
		||||
          this.camera.position.set(x, y, z - 12);
 | 
			
		||||
        } else {
 | 
			
		||||
          this.camera.position.set(x, y, z + 12);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
      tween.onUpdate(onUpdate);
 | 
			
		||||
      tween.start();
 | 
			
		||||
      // this.controls.target.set(0, 0, 0);
 | 
			
		||||
      if (this.positionObj.z < 0) {
 | 
			
		||||
        this.controls.target.set(
 | 
			
		||||
          this.positionObj.x,
 | 
			
		||||
          this.positionObj.y - 0.4,
 | 
			
		||||
          -12
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        this.controls.target.set(
 | 
			
		||||
          this.positionObj.x,
 | 
			
		||||
          this.positionObj.y - 0.4,
 | 
			
		||||
          12
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    toHomeView(id) {
 | 
			
		||||
      const { long, tall } = this;
 | 
			
		||||
      if (id === 1) {
 | 
			
		||||
        let initPosition = {
 | 
			
		||||
          x: this.camera.position.x,
 | 
			
		||||
          y: this.camera.position.y,
 | 
			
		||||
          z: this.camera.position.z,
 | 
			
		||||
        };
 | 
			
		||||
        let tween = new TWEEN.Tween(initPosition)
 | 
			
		||||
          .to({ x: 0, y: -(5 * tall) / 12, z: (6 * long) / 5 }, 2000)
 | 
			
		||||
          .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
        let onUpdate = (pos) => {
 | 
			
		||||
          let x = pos.x;
 | 
			
		||||
          let y = pos.y;
 | 
			
		||||
          let z = pos.z;
 | 
			
		||||
          this.camera.position.set(x, y, z);
 | 
			
		||||
        };
 | 
			
		||||
        tween.onUpdate(onUpdate);
 | 
			
		||||
        tween.start();
 | 
			
		||||
        this.controls.target.set(0, 0, 0);
 | 
			
		||||
        this.isDisabled = true;
 | 
			
		||||
        this.controls.autoRotate = true;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    //根据浏览器窗口自适应
 | 
			
		||||
    onWindowResize() {
 | 
			
		||||
      this.renderer.setSize(window.innerWidth, window.innerHeight);
 | 
			
		||||
      this.camera.aspect = window.innerWidth / window.innerHeight;
 | 
			
		||||
      this.camera.updateProjectionMatrix();
 | 
			
		||||
    },
 | 
			
		||||
    //使用OrbitControls控制三维场景缩放和旋转等功能
 | 
			
		||||
    initControls() {
 | 
			
		||||
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
 | 
			
		||||
      //动态阻尼系数 即鼠标拖拽旋转的灵敏度
 | 
			
		||||
      this.controls.dampingFactor = 0.25;
 | 
			
		||||
      // this.controls.target.set(0, 900, 0)
 | 
			
		||||
      // //上下旋转范围
 | 
			
		||||
      this.controls.minPolarAngle = 0;
 | 
			
		||||
      this.controls.maxPolarAngle = 1.5;
 | 
			
		||||
      this.controls.autoRotate = true;
 | 
			
		||||
      //惯性滑动,滑动大小默认0.25
 | 
			
		||||
      this.controls.dampingFactor = 0.25;
 | 
			
		||||
      //滚轮是否可控制zoom,zoom速度默认1
 | 
			
		||||
      //缩放倍数
 | 
			
		||||
      this.controls.zoomSpeed = 1.0;
 | 
			
		||||
      //最大最小相机移动距离(景深相机)
 | 
			
		||||
      this.controls.minDistance = 1;
 | 
			
		||||
      this.controls.maxDistance = Infinity;
 | 
			
		||||
      //水平方向视角限制
 | 
			
		||||
      this.minAzimuthAngle = -Math.PI * 2;
 | 
			
		||||
      this.maxAzimuthAngle = Math.PI * 2;
 | 
			
		||||
      this.controls.enabledPan = true;
 | 
			
		||||
      this.keyPanSpeed = 7.0;
 | 
			
		||||
    },
 | 
			
		||||
    //运行动画
 | 
			
		||||
    animate() {
 | 
			
		||||
      TWEEN.update();
 | 
			
		||||
      this.renderer.render(this.scene, this.camera);
 | 
			
		||||
      this.controls.update();
 | 
			
		||||
      if (this.composer) {
 | 
			
		||||
        this.composer.render();
 | 
			
		||||
      }
 | 
			
		||||
      requestAnimationFrame(this.animate);
 | 
			
		||||
    },
 | 
			
		||||
    //初始化函数,页面加载完成是调用
 | 
			
		||||
    init() {
 | 
			
		||||
      this.initScene();
 | 
			
		||||
      this.initCamera();
 | 
			
		||||
      this.initLight();
 | 
			
		||||
      this.initRender();
 | 
			
		||||
      this.initModel();
 | 
			
		||||
      this.initControls();
 | 
			
		||||
      this.animate();
 | 
			
		||||
      window.onresize = this.onWindowResize;
 | 
			
		||||
      window.onclick = this.onMouseClick;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.container {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
#btns {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  background-color: #031b34;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  left: 50%;
 | 
			
		||||
  width: 80px;
 | 
			
		||||
  height: 30px;
 | 
			
		||||
  line-height: 30px;
 | 
			
		||||
  transform: translate(-50%, -50%);
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  z-index: 9999;
 | 
			
		||||
  color: #00eeff;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  box-shadow: 0px 0px 2px 1px #00f6ff;
 | 
			
		||||
  border-radius: 6px;
 | 
			
		||||
  border: 1px solid #00f6ff;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*模型样式*/
 | 
			
		||||
#model {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,6 @@
 | 
			
		|||
            主视角
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
   
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
import * as THREE from "three";
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +20,7 @@ import {
 | 
			
		|||
// import renderModel from "../renderModel";
 | 
			
		||||
import homeIcon from '@/assets/image/bg7.jpg'
 | 
			
		||||
import TWEEN from "@tweenjs/tween.js";
 | 
			
		||||
import bus from '@/utils/bus.js'
 | 
			
		||||
import Bus from '@/utils/bus.js'
 | 
			
		||||
 | 
			
		||||
let scene = ref(null);
 | 
			
		||||
let renderer = ref(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -59,10 +58,24 @@ watch(() => props.sceneUrl, val => {
 | 
			
		|||
    init();
 | 
			
		||||
    loadSence();
 | 
			
		||||
});
 | 
			
		||||
// 建筑树点击
 | 
			
		||||
Bus.on('clickBuild', (isParent) => {
 | 
			
		||||
    // Todo
 | 
			
		||||
    console.log('clickBuild', isParent);
 | 
			
		||||
})
 | 
			
		||||
// 设备树点击
 | 
			
		||||
Bus.on('clickDevice', e => {
 | 
			
		||||
    // Todo
 | 
			
		||||
    console.log('clickDevice');
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 系统树点击
 | 
			
		||||
Bus.on('clickApplication', e => {
 | 
			
		||||
    // Todo
 | 
			
		||||
    console.log('clickApplication');
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
    bus.on('foo', e => {
 | 
			
		||||
         
 | 
			
		||||
    })
 | 
			
		||||
    init();
 | 
			
		||||
    loadSence();
 | 
			
		||||
    // 启动动画
 | 
			
		||||
| 
						 | 
				
			
			@ -129,17 +142,17 @@ const initTween = (targetX, targetY, targetZ) => {
 | 
			
		|||
        z: camera.position.z,
 | 
			
		||||
    };
 | 
			
		||||
    let tween = new TWEEN.Tween(initPosition)
 | 
			
		||||
    .to({ x: targetX, y: targetY, z: targetZ }, 2000)
 | 
			
		||||
    .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
        .to({ x: targetX, y: targetY, z: targetZ }, 2000)
 | 
			
		||||
        .easing(TWEEN.Easing.Sinusoidal.InOut);
 | 
			
		||||
    let onUpdate = (pos) => {
 | 
			
		||||
    let x = pos.x;
 | 
			
		||||
    let y = pos.y;
 | 
			
		||||
    let z = pos.z;
 | 
			
		||||
    if (pos.z < 0) {
 | 
			
		||||
        camera.position.set(x, y, z - 12);
 | 
			
		||||
    } else {
 | 
			
		||||
        camera.position.set(x, y, z + 12);
 | 
			
		||||
    }
 | 
			
		||||
        let x = pos.x;
 | 
			
		||||
        let y = pos.y;
 | 
			
		||||
        let z = pos.z;
 | 
			
		||||
        if (pos.z < 0) {
 | 
			
		||||
            camera.position.set(x, y, z - 12);
 | 
			
		||||
        } else {
 | 
			
		||||
            camera.position.set(x, y, z + 12);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    tween.onUpdate(onUpdate);
 | 
			
		||||
    tween.start();
 | 
			
		||||
| 
						 | 
				
			
			@ -191,14 +204,14 @@ const onMouseDown = (event) => {
 | 
			
		|||
    if (!intersects[0]) {
 | 
			
		||||
        return;
 | 
			
		||||
    } else {
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
        if (intersects[0].object.name.indexOf('box') > -1) {
 | 
			
		||||
            selectedObjects = [];
 | 
			
		||||
            selectedObjects.push(intersects[0].object);
 | 
			
		||||
            positionObj = {
 | 
			
		||||
            x: intersects[0].object.position.x,
 | 
			
		||||
            y: intersects[0].object.position.y,
 | 
			
		||||
            z: intersects[0].object.position.z,
 | 
			
		||||
                x: intersects[0].object.position.x,
 | 
			
		||||
                y: intersects[0].object.position.y,
 | 
			
		||||
                z: intersects[0].object.position.z,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            initTween(
 | 
			
		||||
| 
						 | 
				
			
			@ -235,6 +248,7 @@ const toHomeView = () => {
 | 
			
		|||
    height: 100%;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button {
 | 
			
		||||
    width: 80px;
 | 
			
		||||
    height: 80px;
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +260,7 @@ const toHomeView = () => {
 | 
			
		|||
    bottom: 15px;
 | 
			
		||||
    left: 10px;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    text-align: center; 
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    background: rgb(7, 207, 221);
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
    <!-- 底部菜单 -->
 | 
			
		||||
    <MenuTab @changeMenu="changeMenu"></MenuTab>
 | 
			
		||||
    <!-- 左侧建筑菜单 -->
 | 
			
		||||
    <BuildTree v-if="activateIndex == 0" isSetTree="true" @handleNodeClick="handleBuildClick"></BuildTree>
 | 
			
		||||
    <BuildTree v-if="activateIndex == 0"  @handleNodeClick="handleBuildClick"></BuildTree>
 | 
			
		||||
    <!-- 建筑信息 -->
 | 
			
		||||
    <BuildInfo v-if="buildInfo && activateIndex == 0"></BuildInfo>
 | 
			
		||||
    <!-- 资产信息 -->
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ const handleDeviceClick = (value) => {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
const handleApplicationClick = (value) => {
 | 
			
		||||
  console.log(value);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const changeMenu = (index) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue