<template>
  <div
    v-loading="modelState"
    style="width: 100%"
    class="ModelLoading"
    element-loading-text="模型正在加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0)"
  >
    <div
      v-show="!modelState"
      id="modelContainers"
      ref="modelContainers"
      class="animate__animated animationTime2 animate__backInLeft"
    />
  </div>
</template>

<script>
import * as THREE from 'three'
import C3S3D from '@/utils/c3s-3d-1.0.1-e'
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min.js'
// 模型参数配置
import {
  CAMERA_MOVE_DATA,
  getTenToSixteenColor,
  getPointData
} from '@/utils/modelData.js'
export default {
  name: 'HelloWorld',
  components: {},
  props: {
    modelType: {
      type: String,
      default: () => 'byq'
    }
  },
  data() {
    return {
      loading: true,
      loadingText: 100,
      scale: 1,
      publicPath: process.env.BASE_URL,
      // 模型信息
      modelState: false,
      modelData: null,
      rotateAct: null,
      wrapper: null,
      inforData: [],
      byqMoveData: [
        {
          time: 500,
          cx: 0,
          cy: 0,
          cz: 6000,
          tx: 0,
          ty: 0,
          tz: 1200
        }, // 一层
        {
          time: 1200,
          cx: 0,
          cy: 0,
          cz: 1500,
          tx: 0,
          ty: 0,
          tz: 0
        }
      ],
      gisMoveData: [
        {
          time: 500,
          cx: 0,
          cy: 0,
          cz: 6000,
          tx: 0,
          ty: 800,
          tz: 1000
        }, // 一层
        {
          time: 1200,
          cx: 0,
          cy: 0,
          cz: 1000,
          tx: 0,
          ty: 0,
          tz: 0
        }
      ],
      geometry: null,
      modelDataObj: null,
      filePath: null,
      modelSiteId: {}
    }
  },
  watch: {
    modelType: function(val) {
      this.clearModel()
      C3S3D.destory(this.ThreeObjs)
      // this.modelCurrent(val);
      // this.createdInit();
      this.mountedGetData()
    }
  },
  created() {
    const modelParameter = JSON.parse(localStorage.getItem('getModelList'))
    for (let index = 0; index < modelParameter.length; index++) {
      const element = modelParameter[index]
      if (element.modelType == '211') {
        this.modelDataObj = JSON.parse(element.modelParams)
        this.modelSiteId = element
        this.filePath = element.filePath
        break
      }
    }
  },
  mounted() {
    this.mountedGetData()
  },
  beforeDestroy() {
    C3S3D.destory(this.ThreeObjs)
  },
  methods: {
    mountedGetData() {
      this.$store.dispatch('getModelData').then(() => {
        const type = this.modelType == 'byq' ? '111' : '211'
        const modelParameter = JSON.parse(localStorage.getItem('getModelList'))
        console.log('-5-95-5-5-5', modelParameter, type)
        for (let index = 0; index < modelParameter.length; index++) {
          const element = modelParameter[index]
          if (element.modelType == type) {
            this.modelDataObj = JSON.parse(element.modelParams)
            this.filePath = element.filePath
            break
          }
        }
        console.log(!this.modelDataObj, 'wqeqweqewqe')
        if (!this.modelDataObj) {
          this.$bus.$emit('animateState', true)
          return
        }
        this.$nextTick(() => {
          this.createdInit()
        })
      })
    },
    createdInit() {
      this.modelDataInit()
      this.init()
    },
    modelDataInit() {
      const data = this.modelDataObj
      this.modelData = {
        modelName: '111', // 模型名称
        modelZoom: data.modelZoom, // 模型缩放
        modelDraco: true, // 是否为Draco文件
        modelRotateAct: data.modelRotateAct, // 是否开启自动旋转
        modelPath: this.filePath, // 模型文件名称
        modelaPosition: data.position, // 模型位置
        cameraPosition: { x: 0, y: 0, z: 1000 }, // 场景相机位置
        rotationVal: data.rotation,
        Point: {
          color: data.pointLight.color,
          intensity: data.pointLight.intensity
        },
        Ambient: {
          color: data.ambientLight.color,
          intensity: data.ambientLight.intensity
        },
        pointIntensity: 0.3
      }
    },
    // 初始化
    init: function() {
      const data = this.modelData
      this.modelState = true
      const lightList = [
        // 环境光
        {
          type: 'Ambient',
          color: getTenToSixteenColor(data.Ambient.color),
          intensity: data.Ambient.intensity
        }
      ]
      // 环绕点光源
      const pointData = getPointData(
        data.Point.intensity,
        getTenToSixteenColor(data.Point.color)
      )
      if (pointData) {
        for (let index = 0; index < pointData.length; index++) {
          const element = pointData[index]
          lightList.push({
            type: 'Point',
            color: element.color,
            intensity: element.intensity,
            position: element.position
          })
        }
      }
      this.ThreeObjs = C3S3D.init({
        container: this.$refs.modelContainers,
        scene: {},
        camera: {
          far: 15000,
          fov: 45,
          position: [
            data.cameraPosition.x,
            data.cameraPosition.y,
            data.cameraPosition.z
          ]
        },
        controls: {
          noRotate: false,
          autoRotate: true,
          autoRotateSpeed: 2
        },
        renderer: {
          alpha: 0
        },
        // css3dRenderer: {},
        light: lightList,
        update: (dt) => {
          this.update(dt)
        },
        // 鼠标点击事件
        clickCallback: (e) => {
          // this.onMouseClick(e);
        },
        // 鼠标双击事件
        dblclickCallback: () => {},
        // 鼠标移动
        mousemoveCallback: (e) => {
          this.onMouseMove(e)
        },
        // 鼠标摁下
        mousedownCallback: () => {}
      })

      this.loadGltf()
      this.initOutline()
    },
    update() {
      // C3S3D.update(this.ThreeObjs);
    },
    initOutline() {
      C3S3D.initOutline({
        ThreeObjs: this.ThreeObjs,
        edgeStrength: 20,
        edgeThickness: 10,
        edgeGlow: 2,
        pulsePeriod: 5,
        visibleEdgeColor: 0x00ff00,
        hiddenEdgeColor: 0x00ff00,
        downSampleRatio: 1
      })
    },
    // 清除模型
    clearModel() {
      // 清除局部的模型
      if (this.ThreeObjs.scene !== null) {
        // 必须要清空当前div下的canvas不然canvas会继续叠加
        const domDiv = document.getElementById('modelContainers')
        if (domDiv !== null) {
          domDiv.removeChild(domDiv.firstChild)
        }
        // 确保3D相关对象已销毁
        window.cancelAnimationFrame(stop) // 可以取消动画
        this.ThreeObjs.scene = null
        this.ThreeObjs.camera = null
        this.ThreeObjs.renderer = null
        this.ThreeObjs.orbitControls = null
      }
    },

    loadGltf() {
      const group = new THREE.Object3D()
      this.ThreeObjs.scene.add(group)
      C3S3D.loadGltf({
        // url:
        //   process.env.VUE_APP_MODEL_API +
        //   this.modelData.modelPath.split('8022')[1],
        url: this.modelData.modelPath,
        parent: group,
        scale: this.modelData.modelZoom * 1.5,
        ThreeObjs: this.ThreeObjs,
        position: this.modelData.modelaPosition,
        rotation: {
          x: C3S3D.toRadian(this.modelData.rotationVal.x),
          y: C3S3D.toRadian(this.modelData.rotationVal.y),
          z: C3S3D.toRadian(this.modelData.rotationVal.z)
        },
        draco: this.modelData.modelDraco,
        onProgress: (percentage, val) => {
          if (percentage >= 100) {
            this.loading = false
          }
        },
        onLoad: (geometry) => {
          this.geometry = geometry
          this.modelState = false
          if (this.modelType == 'byq') {
            this.startAutoPatrol(this.geometry, this.byqMoveData)
          } else {
            this.startAutoPatrol(this.geometry, this.gisMoveData)
          }
        }
      })
    },
    onMouseClick(event) {
      const selectObject = C3S3D.getIntersectsFirstMesh(
        event,
        this.ThreeObjs,
        this.ThreeObjs.scene.children
      )
      if (selectObject) {
        // 模型组件点亮
        C3S3D.outlineLight(this.ThreeObjs, [selectObject])
        // C3S3D.spreadLeftAndRight(this.geometry, 1, 100, 0, 1000);
      } else {
        C3S3D.outlineLight(this.ThreeObjs, [])
      }
    },
    // 鼠标经过高亮部件
    onMouseMove(event) {
      const selectObject = C3S3D.getIntersectsFirstMesh(
        event,
        this.ThreeObjs,
        this.ThreeObjs.scene.children
      )
      if (this.modelData.modelRotateAct) {
        if (selectObject) {
          this.ThreeObjs.orbitControls.autoRotate = false
        } else {
          this.ThreeObjs.orbitControls.autoRotate = true
        }
      }
    },
    startAutoPatrol(val, data) {
      this.patrolPoints = data
      this.patrolIndex = 0
      this.doPatrol(this.patrolPoints[this.patrolIndex])
    },
    // 相机移动
    doPatrol(point) {
      const cameraPos = this.ThreeObjs.camera.position.clone()
      const targetPos = this.ThreeObjs.orbitControls.target.clone()
      this.patrolTween = C3S3D.createTween({
        start: {
          cx: cameraPos.x,
          cy: cameraPos.y,
          cz: cameraPos.z,
          tx: targetPos.x,
          ty: targetPos.y,
          tz: targetPos.z
        },
        to: {
          cx: point.cx,
          cy: point.cy,
          cz: point.cz,
          tx: point.tx,
          ty: point.ty,
          tz: point.tz
        },
        duration: point.time,

        delayTime: 1,
        onUpdate: (obj) => {
          this.ThreeObjs.camera.position.set(obj.cx, obj.cy, obj.cz)
          this.ThreeObjs.orbitControls.target.set(obj.tx, obj.ty, obj.tz)
        },
        onComplete: () => {
          this.patrolTween = null
          this.patrolIndex++
          if (this.patrolIndex >= this.patrolPoints.length) {
            // 模型加完成
            return
          }
        },
        easing: TWEEN.Easing.Linear.None
      })
    },
    // 相机视角移动动画
    startAutoPatrol(val, data) {
      this.patrolPoints = data
      this.patrolIndex = 0
      this.doPatrol(this.patrolPoints[this.patrolIndex])
    },
    // 相机移动
    doPatrol(point) {
      const cameraPos = this.ThreeObjs.camera.position.clone()
      const targetPos = this.ThreeObjs.orbitControls.target.clone()
      this.patrolTween = C3S3D.createTween({
        start: {
          cx: cameraPos.x,
          cy: cameraPos.y,
          cz: cameraPos.z,
          tx: targetPos.x,
          ty: targetPos.y,
          tz: targetPos.z
        },
        to: {
          cx: point.cx,
          cy: point.cy,
          cz: point.cz,
          tx: point.tx,
          ty: point.ty,
          tz: point.tz
        },
        duration: point.time,
        delayTime: 1,
        onUpdate: (obj) => {
          this.ThreeObjs.camera.position.set(obj.cx, obj.cy, obj.cz)
          this.ThreeObjs.orbitControls.target.set(obj.tx, obj.ty, obj.tz)
        },
        onComplete: () => {
          this.patrolTween = null
          this.patrolIndex++
          if (this.patrolIndex >= this.patrolPoints.length) {
            this.moveSatate = true
            this.$bus.$emit('animateState', true)
            return
          }
          this.doPatrol(this.patrolPoints[this.patrolIndex])
        },
        easing: TWEEN.Easing.Linear.None
      })
    }
  }
}
</script>

<style lang="scss">
@import "@/assets/stylesheet/index";
.ModelLoading {
  width: 100%;
  position: absolute;
  height: 100%;
  top: 0;
  z-index: 1;
  .el-loading-spinner {
    position: fixed;
    left: 50% !important;
    transform: translateX(-50%) !important;
  }
  .el-loading-spinner .el-loading-text {
    color: #28c4fe !important;
    font-size: vw(32) !important;
  }
  .el-loading-spinner i {
    color: #28c4fe !important;
    font-size: vw(44) !important;
  }
}
#modelContainers {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  overflow: hidden;
}

.control-box-baozha {
  width: 300px;
  /* height: 40px; */
}
.device {
  width: 100%;
  height: vw(80);
  line-height: vw(80);
  text-align: center;
}
.progress {
  min-width: vw(300);
  height: vw(120);
  display: flex;
  flex-flow: column;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: vw(10);
  margin-top: vw(-60);
  margin-left: vw(-200);
  background: rgba(13, 159, 228, 0.2);
  color: #fff;
  padding: 0 vw(20);
  span {
    margin-top: vw(20);
  }
}
/deep/ .el-progress {
  width: vw(500) !important;
}
/deep/ .el-progress-bar {
  padding-right: 0px;
}
/deep/ .el-progress__text {
  display: none;
}
</style>
