<template>
  <div class="bigBox">
    <div class="left" v-show="isShow">
      <div class="leftOne">
        <div class="one">
          <lineChart v-if="flag" :speed="agentSpeed" :indexData="propsIndex" :propsName="propsName" :times="times" :stop="isAnimation" />
        </div>
        <div class="two">
          <lineChartTwo v-if="flag" :speed="targetSpeed" :indexData="propsIndex" :propsName="propsName" :times="times" :stop="isAnimation" />
        </div>
        <div class="three">
          <lineChartThree v-if="flag" :speed="propsDistance" :reportShow="reportShow" :times="times" :stop="isAnimation" />
        </div>
      </div>
      <div class="leftTwo">
        <div class="twoD" ref="twoD" v-if="flag">
          <lineChartFive v-if="flag" :propsData="propsCoordinates" :indexData="propsIndex" :propsName="propsName" :stop="isAnimation" />
        </div>
        <div class="four">
          <lineChartFour v-if="flag" :propsName="propsName" :direction="propsDirection" :indexData="propsIndex" :times="times" :stop="isAnimation" />
          <!-- <discChart
            v-if="flag"
            :propsData="1"
          /> -->
        </div>
      </div>
    </div>

    <div id="container" ref="box">
      <div class="infoTag" ref="infoTag"></div>
      <div class="SVShow" v-show="isShow">
        <!-- <div class="modelInfo">场景详细信息！！！！</div> -->
        <!-- <p class="modelInfo">{{ senceInfo }}</p> -->
        <p v-for="(item, index) in senceInfo" :key="index">{{ item }}</p>
      </div>
      <div class="tool">
        <button class="btn" style="width: 120px;" @click="goback">返 回 上 一 级</button>
        <el-select v-model="fileName" :disabled="selectDisabled" placeholder="请选择文件" @change="getFileContext">
          <el-option v-for="item in fileList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
        <el-select v-model="playSpeedData" @change="playSpeed">
          <el-option v-for="item in speedOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
        <el-select v-model="algoData" placeholder="请选择算法">
          <el-option v-for="item in algoOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
        <button class="btn" @click="Suspend">暂 停</button>
        <button class="btn" @click="Begin">开 始</button>
        <button class="btn" @click="playBack" :disabled="!isShow">回 放</button>
        <input type="file" ref="fileInput" style="display: none" @change="importData" accept=".json" />
      </div>
      <div class="small" id="small" ref="small" v-show="isShow"></div>
    </div>
    <div class="right">
      <div class="textShow" v-show="isShow">
        <div class="textShowBox">
          <p v-for="(item, index) in eventText" :key="index">{{ item }}</p>
          <div class="report" v-show="reportShow">
            <p style="color: black" v-for="(item, index) in reportInfo" :key="index">
              {{ item }}
            </p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import TWEEN from '@tweenjs/tween.js'
// 引入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// import { BufferGeometryUtils } from 'three';
// import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
import lineChart from '@/views/3dDemo/lineChart'
import lineChartTwo from '@/views/3dDemo/lineChartTwo'
import lineChartThree from '@/views/3dDemo/lineChartThree'
import lineChartFour from '@/views/3dDemo/lineChartFour'
import lineChartFive from '@/views/3dDemo/lineChartFive'
// import discChart from "@/views/3dDemo/discChart";
import '@/assets/css/global.css'

let light
let scene = null
let sceneSmall = null
let camera = null
const SHADOW_MAP_WIDTH = 2048,
  SHADOW_MAP_HEIGHT = 1024
let containerWidth, containerHeight
const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()
export default {
  name: 'threeDemo',
  components: {
    lineChart,
    lineChartTwo,
    lineChartThree,
    lineChartFour,
    lineChartFive
    // discChart
  },
  data() {
    return {
      jsonData: null,
      // 场景
      // scene: null,
      // sceneSmall: null,
      // 渲染器
      renderer: null,
      smallRenderer: null,
      // 摄像机
      // camera: null,
      OrbitControl: null,
      // 物体形状
      geometry: null,
      // 物体材质
      material: [],
      // 坐标轴
      axes: null,
      // container
      container: null,
      // 网格模型
      mesh: null,
      // 模型
      models: [],
      // 时间和事件
      allTimes: [],
      // 所有事件
      allEvents: [],
      eventText: [],
      // 改变的距离
      distance: [],
      // 所有距离
      allDistance: [],
      particleSystem: null,
      // 倍速
      playSpeedData: 1,
      speedOptions: [
        { value: 1, label: '1倍速' },
        { value: 4, label: '4倍速' },
        { value: 8, label: '8倍速' },
        { value: 16, label: '16倍速' },
        { value: 32, label: '32倍速' },
        { value: 64, label: '64倍速' },
        { value: 128, label: '128倍速' }
      ],
      // 暂停和开始
      isAnimation: false,
      animationId: null,
      waveAnimateId: null,
      // 保存动画值
      animationValues: {},
      waveImg: require('../../assets/界面.jpg'),
      // 保存导入的文件
      file: null,
      fileList: [],
      fileName: null,
      isFile: false,
      isShow: false,
      flag: false,
      // props的值
      agentSpeed: [],
      targetSpeed: [],
      times: [],
      propsDistance: [],
      mixer: null,
      propsDirection: [],
      propsName: [],
      propsIndex: null,
      propsCoordinates: [],
      // 场景信息
      senceInfo: '',
      // 评估报告展示
      reportShow: false,
      reportInfo: null,
      selectDisabled: false,
      tagArray: [],
      waweShow: false,
      tween: null,
      tween1: null,
      tweenTargetPosition: null,
      maxNum: null,
      // 选择算法
      algoData: '',
      // 算法选项
      algoOptions: [
        {
          value: '选项1',
          label: '算法1'
        },
        {
          value: '选项2',
          label: '算法2'
        },
        {
          value: '选项3',
          label: '算法3'
        }
      ]
    }
  },
  mounted() {
    this.getFile()
    this.fileName=this.$route.params.fileName
    this.getFileContext()
    this.initContainer()
    this.initSmall()
    this.initOrbitControls()
    // this.createCube();
    this.createWave()
    this.waveModel()
  },
  beforeDestroy() {
    window.removeEventListener('mousemove', this.onMouseMove);
    this.clearSence()
    cancelAnimationFrame(this.animationId);
    
  },
  methods: {
    getFile() {
      this.$axios.get(`/api/`).then((res) => {
        console.log('res', res)
        if (res.status === 200) {
          if (res.data.length === 0) {
            this.$message.error('文件夹下暂无数据，请添加数据')
          }
          res.data.forEach((item, index) => {
            this.fileList.push({
              label: item,
              value: item
            })
          })
        } else {
          this.$message.warning('读文件列表有误')
        }
      })
      containerWidth = document.getElementById('container').clientWidth
      containerHeight = document.getElementById('container').clientHeight
    },
    goback(){
      window.removeEventListener('mousemove', this.onMouseMove);
      this.isAnimation = false
      cancelAnimationFrame(this.animationId);
      this.renderer.dispose();
      this.renderer.forceContextLoss();
      this.renderer.content = null;
      this.renderer = null;
      this.clearSence()
      this.$router.push({ name:'simulationSystem'})
    },
    // 初始化场景
    initContainer() {
      let container = this.$refs.box
      this.container = container
      // 创建场景
      scene = new THREE.Scene()

      // 创建相机、相机位置、设置相机方向(指向的场景对象)
      camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 1, 20000)
      camera.position.set(1000, 0, 1000)
      camera.lookAt(scene.position)
      // this.camera.lookAt(0, 0, 0)

      //创建渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
      // this.renderer.setClearAlpha(0.1);
      // this.renderer.setClearColor(0x000000,0)
      this.renderer.setSize(container.clientWidth, container.clientHeight)
      // 将渲染器添加到页面
      container.appendChild(this.renderer.domElement)

      // 环境光
      var ambienLight = new THREE.AmbientLight(0xcccccc, 0.5)
      scene.add(ambienLight)
      light = new THREE.DirectionalLight(0xffffff, 3)
      light.position.set(0, 1500, 1000)
      light.castShadow = true
      light.shadow.camera.top = 2000
      light.shadow.camera.bottom = -2000
      light.shadow.camera.left = -2000
      light.shadow.camera.right = 2000
      light.shadow.camera.near = 1200
      light.shadow.camera.far = 2500
      light.shadow.bias = 0.0001

      light.shadow.mapSize.width = SHADOW_MAP_WIDTH
      light.shadow.mapSize.height = SHADOW_MAP_HEIGHT

      scene.add(light)

      // this.axes = new THREE.AxesHelper(500)
      // this.scene.add(this.axes)
    },
    // 初始化小窗口
    initSmall() {
      let small = this.$refs.small
      sceneSmall = new THREE.Scene()
      const geometry = new THREE.CircleGeometry()

      const material = new THREE.MeshStandardMaterial({})
      const mesh = new THREE.Mesh(geometry, material)
      sceneSmall.add(mesh)
      //创建渲染器
      this.smallRenderer = new THREE.WebGLRenderer()
      small.appendChild(this.smallRenderer.domElement)
      this.axes = new THREE.AxesHelper(2500)
      sceneSmall.background = new THREE.Color('#000')
      sceneSmall.add(this.axes)
    },
    // 初始化控制器
    initOrbitControls() {
      // 创建轨道控制器 相机围绕模型看到的角度
      this.OrbitControl = new OrbitControls(camera, this.renderer.domElement)
      // 设置轨道自然
      this.OrbitControl.enableDamping = true
      this.OrbitControl.enableRotate = false //禁止旋转
      this.OrbitControl.keys = {
        LEFT: 'ArrowLeft', // left arrow
        UP: 'ArrowUp', // up arrow
        RIGHT: 'ArrowRight', // right arrow
        BOTTOM: 'ArrowBottom' // down arrow
      }
      // 设置惯性
      this.OrbitControl.update()
      this.addEvent(window, 'keydown', this.onKeyDown)
    },
    onKeyDown(e) {
      // const camera = camera
      const controls = this.OrbitControl

      if (!camera || !controls) {
        return
      }
      const sensitivity = 3 // you may want to put it into settings
      const p = new THREE.Vector3() // camera's position
      camera.getWorldPosition(p)
      const t = controls.target // target point
      const newTarget = t.clone()
      if (e.code === 'ArrowLeft' || e.code === 'ArrowRight') {
        const ANGLE = sensitivity
        let theta = (Math.PI * ANGLE) / 180
        if (e.code === 'ArrowLeft') {
          theta = -theta
        }
        const newPos = new THREE.Vector3()
        newPos.x = p.x * Math.cos(theta) - p.z * Math.sin(theta)
        newPos.z = p.z * Math.cos(theta) + p.x * Math.sin(theta)
        camera.position.set(newPos.x, p.y, newPos.z)
        controls.target = newTarget
        controls.update()
      } else if (e.code === 'ArrowUp' || e.code === 'ArrowDown') {
        const ANGLE2 = sensitivity
        let theta2 = (Math.PI * ANGLE2) / 180
        const distVec = new THREE.Vector3(t.x - p.x, t.y - p.y, t.z - p.z)
        const dist = distVec.length()
        const deltaY = t.y - p.y
        if (e.code === 'ArrowDown') {
          theta2 = -theta2
        }
        const angle = Math.asin(deltaY / dist) + theta2
        if (angle < -Math.PI / 2 || angle > Math.PI / 2) {
          return // cannot rotate that much
        }
        const newDeltaY = Math.sin(angle) * dist
        newTarget.y = t.y + (newDeltaY - deltaY)
        controls.target = newTarget
        controls.update()
      }
    },
    addEvent(target, type, handler) {
      target.addEventListener(type, handler)
    },
    // 创建立方体
    createCube() {
      const size = this.maxNum * 2
      this.geometry = new THREE.BoxGeometry(size, size, size)
      // this.geometry = new THREE.SphereGeometry(500, 60, 40);
      this.geometry.scale(1, 1, 1)
      // 创建矩形网格
      this.mesh = new THREE.Mesh(this.geometry, this.material)
      this.mesh.geometry.scale(1, 1, 1)
      scene.add(this.mesh) //网格模型添加到场景中
    },
    // 动画
    animate(modelInfo) {
      console.log("222");
      if (this.isAnimation) {
        setTimeout(() => {
          this.animationId = requestAnimationFrame(() => this.animate(modelInfo))
          this.modelMove(modelInfo)
          // 渲染场景
          this.tween?.update()
          // this.tween1?.update();
          this.renderer?.render(scene, camera)
          this.smallRenderer.render(sceneSmall, camera)
        }, 150)
      }
    },
    // 创建扩散波
    createWave() {
      // var textureLoader = new THREE.TextureLoader();
      // 底部半径、顶部半径、高度和面的数量
      const geometry = new THREE.CylinderGeometry(150, 150, 10, 500)
      const geometry2 = new THREE.CylinderGeometry(200, 200, 10, 500)
      const material = new THREE.MeshBasicMaterial({
        color: 0x0078d4,
        side: THREE.DoubleSide,
        transparent: true
        // map: textureLoader.load(this.waveImg),
      })
      const circle = new THREE.Mesh(geometry, [material]) //用数组只贴边面
      const circle2 = new THREE.Mesh(geometry2, [material]) //用数组只贴边面
      circle.name = 'circle'
      circle2.name = 'circle2'
      circle.position.set(-1000, 1000, -1000)
      circle2.position.set(-1000, 1000, -1000)
      scene.add(circle)
      scene.add(circle2)

      let s = 0,
        p = 0
      const scaleFactor = 3 // 调整这个值以控制波纹的扩大速度

      const render1 = () => {
        if (s > 160) {
          s = 0
          p = 160
        }
        circle.scale.set(1 + (s / 60) * scaleFactor, 1, 1 + (s / 60) * scaleFactor)
        circle2.scale.set(1 + (s / 60) * scaleFactor, 1, 1 + (s / 60) * scaleFactor)
        circle.material[0].opacity = p / 160
        circle2.material[0].opacity = p / 160
        s++
        p--
        this.waveAnimateId = requestAnimationFrame(render1)
      }
      render1()
    },
    // 引入发射扩散波模型
    waveModel() {
      const objLoader = new OBJLoader()
      const material = new THREE.MeshStandardMaterial({ color: 0xfbc31d })
      objLoader.load('/models/obj.obj', (model) => {
        model.scale.set(0.03, 0.03, 0.03)
        model.name = 'waveModel'
        model.traverse(function (child) {
          if (child instanceof THREE.Mesh) {
            child.material = material // 设置模型的材质
            // child.name='waveModel'
          }
        })
        model.position.set(-1000, 1000, -1000)
        scene.add(model)
      })
    },
    // 模型加载
    createRole(data, callback) {
      const [index, modelInfo] = data
      const material = new THREE.MeshStandardMaterial({
        color: modelInfo.color
      })
      const objLoader = new OBJLoader()
      objLoader.load(
        this.models[index].path,
        (model) => {
          const size = this.models[index].scale
          model.scale.set(size, size, size)
          model.position.copy(this.models[index].route[0])
          model.traverse(function (child) {
            if (child instanceof THREE.Mesh) {
              child.material = material // 设置模型的材质
            }
          })
          this.models[index].model = model
          scene.add(model)
          // 在模型加载成功后执行回调
          if (typeof callback === 'function') {
            callback(model)
          }
        },
        undefined,
        (error) => {
          console.error(error)
        }
      )
    },
    // 控制模型运动
    modelMove(modelInfo) {
      if (modelInfo.pathIndex === modelInfo.route.length && this.eventText.length === this.allEvents.length) {
        this.reportShow = true
        return
      }
      if (this.playSpeedData <= modelInfo.route.length - modelInfo.pathIndex) {
        let index = modelInfo.pathIndex
        const currentPoint = modelInfo.route[index]
        if (modelInfo.route.length - modelInfo.pathIndex > 1) {
          const nextPoint = modelInfo.route[index + this.playSpeedData]
          const direction = new THREE.Vector3().subVectors(nextPoint, currentPoint).normalize()
          // 计算模型当前位置向下一个位置的方向向量来确定模型的朝向
          modelInfo.model.lookAt(modelInfo.model.position.clone().add(direction))
          modelInfo.movedRoute.push(modelInfo.model?.position.clone())
          modelInfo.model.position.copy(modelInfo.route[index])

          // 调用生成轨迹函数
          this.makeCurve(modelInfo)
        }
        if (modelInfo.name === 'agent' || modelInfo.name === 'agent1') {
          // this.agentSpeed.push(modelInfo.speed[index]);
          // this.times.push(this.allTimes[index]);
          this.times.push(...this.allTimes.slice(modelInfo.prevIndex, index))
          // this.propsDistance.push(...this.distance.slice(modelInfo.prevIndex,index));

          this.propsIndex = index
          // 展示生成事件文字
          this.showText(this.allTimes[index])
        }
        if (modelInfo.name.startsWith('agent')) {
          this.agentSpeed[modelInfo.name]?.push(...modelInfo.speed.slice(modelInfo.prevIndex, index))
          // this.propsDistance.push(...this.distance.slice(modelInfo.prevIndex,index));
          // 距离
          this.showDistance(this.allTimes[index], modelInfo.name)
          if (this.allDistance[modelInfo.name][index] <= 3) {
            // && !this.waweShow
            for (let i = scene.children.length - 1; i >= 0; i--) {
              const child = scene.children[i]
              if (child.name === 'circle2' || child.name === 'circle' || child.name === 'waveModel') {
                scene.remove(child)
                child.children.forEach((child) => {
                  child.remove(child)
                  if (child instanceof THREE.Mesh) {
                    child.geometry.dispose()
                    child.material.dispose()
                  }
                })
                // cancelAnimationFrame(this.waveAnimateId);
                // this.waveAnimateId = null;
              }
            }
            // this.waweShow = true;
            let position = {
              x: modelInfo.route[index].x - 30,
              y: modelInfo.route[index].y + 30,
              z: modelInfo.route[index].z - 30
            }
            this.tween = new TWEEN.Tween(camera.position)
              .to(position, 2000)
              .onUpdate(() => {
                camera.lookAt(this.tweenTargetPosition.x, this.tweenTargetPosition.y, this.tweenTargetPosition.z)
                this.OrbitControl.target = new THREE.Vector3(this.tweenTargetPosition.x, this.tweenTargetPosition.y, this.tweenTargetPosition.z)
              })
              .start()
          }
        }
        this.propsDirection[modelInfo.name]?.push(...modelInfo.direction.slice(modelInfo.prevIndex, index))
        if (modelInfo.name === 'target') {
          // this.targetSpeed.push(modelInfo.speed[index]);
          this.targetSpeed.push(...modelInfo.speed.slice(modelInfo.prevIndex, index))
          this.tweenTargetPosition = {
            x: modelInfo.route[index].x,
            y: modelInfo.route[index].y,
            z: modelInfo.route[index].z
          }
        }
        modelInfo.prevIndex = index
        modelInfo.pathIndex += this.playSpeedData
      } else {
        this.playSpeedData = 1
      }
    },
    makeCurve(modelInfo) {
      const particleGeometry = new THREE.BufferGeometry()
      const particleMaterial = new THREE.PointsMaterial({
        color: modelInfo.curveColor,
        size: 3
      })
      const routePoint = modelInfo.route.length
      if (modelInfo.movedRoute.length >= 2) {
        const curve = new THREE.CatmullRomCurve3(modelInfo.movedRoute)
        curve.curveType = 'catmullrom'
        curve.closed = false
        curve.tension = 0.5
        const points = curve.getPoints(routePoint) // 获取曲线上的n个点

        particleGeometry.setFromPoints(points)

        this.particleSystem = new THREE.Points(particleGeometry, particleMaterial)
        if (modelInfo.name.startsWith('agent')) {
          this.particleSystem.userData.distance = this.allDistance[modelInfo.name][modelInfo.pathIndex]
          this.particleSystem.userData.time = this.allTimes[modelInfo.pathIndex]
          this.particleSystem.userData.name = modelInfo.name
        }
        scene.add(this.particleSystem)
        this.tagArray.push(this.particleSystem)
      } else {
        // console.error('Not enough points to create curve.')
        return
      }
    },
    onMouseMove(event) {
      const infoTag = this.$refs.infoTag
      mouse.x = (event.layerX / containerWidth) * 2 - 1
      mouse.y = -(event.layerY / containerHeight) * 2 + 1
      raycaster.setFromCamera(mouse, camera)
      var intersects = raycaster.intersectObjects(this.tagArray)
      if (intersects.length === 0) {
        infoTag.style.display = 'none'
        return
      } //有相交物体时
      if (intersects.length > 0) {
        let object = intersects[0].object
        if (object.userData.name?.startsWith('agent')) {
          infoTag.innerHTML = `名称：雷${object.userData.name.substr(-1)}
          <br>时间：${object.userData.time}
          <br>距离：${object.userData.distance}km`
          infoTag.style.display = 'block'
          infoTag.style.cursor = 'pointer'
          infoTag.style.left = event.layerX + 10 + 'px' //一定要拼接 px
          infoTag.style.top = event.layerY + 10 + 'px'
        } else {
          return
        }
      }
    },
    getFileContext() {
      if(!this.fileName){
        this.$message.warning('请手动选择回放的数据')
        return
      }
      const data = { fileName: this.fileName }
      this.$axios.post('/api/fileContent', data).then((res) => {
        // console.log("11",res);
        if (res.status === 200 && res.data.code === 200) {
          this.jsonData = res.data.data
          this.handelData(this.jsonData)
          this.selectDisabled = true
        } else {
          this.$message.warning('文件读取内容失败')
        }
      })
      // this.$axios.get('/api/readTxt').then((res)=>{
      //   console.log("11",res);
      // })
    },
    // 触发文件上传输入框的点击事件
    importBtn() {
      this.$refs.fileInput.click()
    },
    // 导入数据
    importData(event) {
      // importData(file) {
      const file = event?.target.files[0] // 获取上传的文件
      // console.log("导入",file);
      if (file) {
        const reader = new FileReader() // 创建一个文件阅读器对象

        reader.onload = (e) => {
          try {
            const content = e.target.result // 获取文件内容
            const jsonContent = JSON.parse(content) // 解析 JSON

            this.jsonData = jsonContent // 将 JSON 数据存储在组件的数据中
            this.jsonData = jsonContent.filter((item, index) => index % 3 === 0 || item[1].events.length !== 0)
            this.handelData(this.jsonData)
          } catch (error) {
            console.error('Error reading the file:', error)
          }
        }
        reader.readAsText(file) // 以文本形式读取文件内容
      }
    },
    handelData(rawData1) {
      const rawData = rawData1.filter((item, index) => {
        return index % 10 === 0 || item[1].events.length !== 0 || item[1].report
      })
      // console.log('rawData', rawData)
      const color = [0xc1232b, 0x5470c6, 0xfac858, 0xee6666]
      this.models = []
      this.allTimes = []
      this.allEvents = []
      this.direction = []
      this.distance = []
      let beginCoordinate = null
      let maxData = 0
      const agents = {}
      const target = {
        path: '/models/qianting.obj',
        name: 'target',
        route: [],
        pathIndex: 0,
        model: null,
        scale: 15,
        isMoving: false,
        movedRoute: [],
        color: 0x3cf44b,
        curveColor: 0x3cf44b,
        speed: [],
        direction: [],
        nowSpeed: null,
        coordinate: [],
        prevIndex: 0
      }
      this.senceInfo = rawData[0][1].info
      rawData.forEach((data) => {
        if (data[1].events.length !== 0) {
          this.allEvents.push({
            time: data[0],
            event: data[1].events
          })
        }
        if (data[1].report) {
          this.reportInfo = data[1].report
        }
        this.allTimes.push(data[0])
        Object.keys(data[1].distance).forEach((key, index) => {
          const dis = Number(parseFloat(data[1].distance[key]).toFixed(2))
          if (!this.distance[key]) {
            this.distance[key] = [[parseFloat(data[0]), dis]]
            this.allDistance[key] = []
          }
          this.allDistance[key].push(dis)
          if (this.distance[key][this.distance[key].length - 1][1] !== dis) {
            this.distance[key].push([parseFloat(data[0]), dis])
          }
          if (!this.propsDistance[key]) {
            this.propsDistance[key] = []
            this.propsDistance[key].push(this.distance[key][0])
          }
        })
        // 处理代理数据
        Object.keys(data[1]).forEach((key, index) => {
          if (key.startsWith('agent')) {
            if (!agents[key]) {
              agents[key] = {
                path: '/models/yulei2.obj',
                name: key,
                route: [],
                pathIndex: 0,
                model: null,
                scale: 15,
                isMoving: false,
                movedRoute: [],
                color: 0xe6194b,
                curveColor: color[index],
                speed: [],
                direction: [],
                nowSpeed: null,
                coordinate: [],
                prevIndex: 0
              }
            }
            if (!beginCoordinate) {
              beginCoordinate = [data[1][key].agent_center_x, data[1][key].agent_center_y]
            }
            agents[key].route.push(new THREE.Vector3(data[1][key].agent_center_x / 2, 100, data[1][key].agent_center_y / 2))
            agents[key].speed.push(parseInt(data[1][key].agent_speed))
            agents[key].direction.push(
              data[1][key].agent_direction > 180 ? -(360 - parseInt(data[1][key].agent_direction)) : parseInt(data[1][key].agent_direction)
            )
            agents[key].coordinate.push([data[1][key].agent_center_x - beginCoordinate[0], data[1][key].agent_center_y - beginCoordinate[1]])
            maxData = Math.max(data[1][key].agent_center_x, data[1][key].agent_center_y, maxData)
          }
        })
        // 处理目标数据
        const targetX = data[1].target.target_center_x
        const targetY = data[1].target.target_center_y
        target.route.push(new THREE.Vector3(targetX / 2, 100, targetY / 2))
        target.speed.push(parseInt(data[1].target.target_speed))
        target.direction.push(
          data[1].target.target_direction > 180 ? -(360 - parseInt(data[1].target.target_direction)) : parseInt(data[1].target.target_direction)
        )
        target.coordinate.push([targetX - beginCoordinate[0], targetY - beginCoordinate[1]])
        maxData = Math.max(targetX, targetY, maxData)
      })
      this.maxNum = Math.ceil(maxData)
      this.models = [].concat(...[Object.values(agents), target])

      // console.log("this.models", this.models);
      // console.log("this.distance",this.distance);
      // console.log("this.allDistance",this.allDistance);

      this.models.forEach((modelInfo, index) => {
        // this.propsDirection.push(modelInfo.direction);
        this.propsDirection[modelInfo.name] = []
        this.propsName.push(modelInfo.name)
        this.propsCoordinates[modelInfo.name] = modelInfo.coordinate

        if (modelInfo.name.startsWith('agent')) {
          this.agentSpeed[modelInfo.name] = []
        }
        this.createRole([index, modelInfo], () => {
          this.isAnimation = true
          this.animate(modelInfo)
          this.isFile = true
        })
      })
      this.isShow = true
      this.flag = true
      this.createCube()
      window.addEventListener('mousemove', this.onMouseMove)
    },
    // 倍速播放
    playSpeed() {
      this.playSpeedData = parseInt(this.playSpeedData)
    },
    // 暂停按钮
    Suspend() {
      this.isAnimation = false
    },
    // 开始按钮
    Begin() {
      if (!this.isAnimation) {
        this.isAnimation = true
        this.models.forEach((modelInfo) => {
          this.animate(modelInfo) // 重新开始动画循环
        })
      }
    },
    showDistance(time, name) {
      const filterData = this.distance[name]?.filter((item) => item[0] <= parseFloat(time))
      if (filterData?.length !== this.propsDistance[name]?.length) {
        this.propsDistance[name] = filterData
      }
      //console.log('propsDistance', this.propsDistance)
      // if(this.distance[name].some(item => item[0] === parseFloat(time)) && !(this.propsDistance[name].some(item => item[0] === parseFloat(time)))){
      //   this.propsDistance[name].push(this.distance[name].find(item => item[0] === parseFloat(time)));
      //   console.log("this.propsDistance",this.propsDistance);
      // }
    },
    // 显示文本解释
    showText(index) {
      // allEvent 所有有事件的时间事件集合
      this.allEvents?.forEach((item) => {
        if (parseFloat(index) >= parseFloat(item.time)) {
          if (!this.eventText?.includes(item.event)) {
            this.eventText.push(item.event)
          }
        }
      })
    },
    // 回放!!!!
    playBack() {
      // this.clearSence()
      this.Suspend()
      this.clearSence()
      this.flag = false
      if (this.waweShow) {
        this.createWave()
        this.waweShow = false
      }
      setTimeout(() => {
        this.clearSence()
        cancelAnimationFrame(this.animationId)
        this.animationId = null
        this.waveModel()

        this.handelData(this.jsonData)
      }, 100)
    },
    // 清除场景中的信息
    clearSence() {
      for (let i = scene.children.length - 1; i >= 0; i--) {
        const child = scene.children[i]
        if (child instanceof THREE.Group) {
          scene.remove(child)
          child.children.forEach((child) => {
            child.remove(child)
            // 如果子对象是 Mesh，则需要手动释放几何体和材质
            if (child instanceof THREE.Mesh) {
              child.geometry.dispose()
              child.material.dispose()
            }
          })
        }
        if (child instanceof THREE.Points) {
          scene.remove(child)
          if (child && child.geometry) {
            child.geometry.dispose()
          } else if (child && child.material) {
            child.material.dispose()
          } else {
            console.log('未找到数据')
          }
        }
        if (child === this.particleSystem) {
          scene.remove(child)
          if (child.geometry) {
            child.geometry.dispose()
          }
          if (child.material) {
            child.material.dispose()
          }
          // 可以在这里将 this.particleSystem 设为 null，以防止后续误用
          this.particleSystem = null
        }
        //清除数据
        this.models = []
        this.allTimes = []
        this.allEvents = []
        this.distance = []
        this.direction = []
        this.eventText = []
        this.agentSpeed = []
        this.targetSpeed = []
        this.times = []
        this.propsDistance = []
        this.propsDirection = []
      }
    }
  }
}
</script>

<style scoped>
/* *{
  padding: 0;
  margin: 0;
  box-sizing:content-box
} */
.bigBox {
  width: 100%;
  height: 100%;
  /* width: 5760px;
  height: 1080px; */
  display: flex;
  position: relative;
}

#container {
  width: 1920px;
  height: 1080px;
  position: absolute;
  left: 1920px;
  top: 0;
}
.infoTag {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 5px;
  /* margin: 4px; */
}
.right {
  width: 1800px;
  height: 1080px;
  position: absolute;
  right: 0;
  top: 0;
}

.left {
  width: 1920px;
  height: 1080px;
  display: flex;
  flex-direction: row;
}
.leftOne {
  width: 900px;
  height: 1080px;
  position: absolute;
  top: 0;
  left: 50px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}

.leftTwo {
  width: 800px;
  height: 1080px;
  position: absolute;
  top: 0;
  left: 1050px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}
.one {
  background: url('../../assets/鱼雷速度.png') center no-repeat;
}

.two {
  background: url('../../assets/目标速度.jpg') center no-repeat;
}
.three {
  background: url('../../assets/雷目距离.jpg') center no-repeat;
  /* background: url("../../assets/目标速度.jpg") center no-repeat; */
}

.one,
.two,
.three {
  width: 900px;
  height: 300px;
  background-size: 900px 300px;
  position: relative;
  /* top: 50%; */
  /* margin: 1.875rem 1.25rem 0.9375rem 0.9375rem; */
}

.four {
  background: url('../../assets/航向角.jpg') center no-repeat;
}

/* .two,
.four {
  left: 700px;
} */

.four {
  width: 900px;
  height: 300px;
  background-size: 900px 300px;
  position: relative;
  margin: 25px 0 0 -50px;
}

.twoD {
  background: url('../../assets/右框.jpg') center no-repeat;
}

.twoD {
  width: 850px;
  height: 650px;
  background-size: 850px 650px;
  margin-top: 25px;
  margin-left: -20px;
  z-index: 9999;
}

.SVShow {
  background: url('../../assets/右框.jpg') center no-repeat;
}
.SVShow {
  width: 430px;
  height: 300px;
  background-size: 430px 300px;
  display: flex;
  align-items: center;
  flex-direction: column;
  position: absolute;
  z-index: 9999;
  top: 8%;
}
.SVShow >>> p {
  width: 380px;
  color: white;
  font-size: 1.6rem;
  /* margin-left: 30px; */
  margin: 0;
  padding: 10px;
  overflow: hidden;
}

.modelInfo {
  /* height: 50px;
  line-height: 50px; */
  margin: 20px;
  color: white;
  font-size: 1.75rem;
}
.report {
  width: 1630px;
  background-color: white;
  margin: 30px;
  padding-top: 15px;
  font-family: Simsun;
}
.tool {
  width: 1100px;
  height: 80px;
  line-height: 80px;
  position: absolute;
  bottom: 0;
  font-size: 16px;
  margin: 20px;
}

.btn {
  width: 80px;
  height: 40px;
  background-color: #01192a;
  /* background: url("../../assets/界面.jpg") center no-repeat;
  background-size: 80px 40px; */
  color: #02d1fd;
  font-weight: 700;
  box-shadow: inset 0 0 7px 3px #215c76;
  margin: 0 15px;
  /* inset 表示内阴影 */
}

.textShow {
  background: url('../../assets/右框.jpg') center no-repeat;
}
.textShow {
  width: 1700px;
  height: 1000px;
  background-size: 1700px 1000px;
  /* opacity: 0.4; */
  position: absolute;
  z-index: 9999;
  top: 40px;
  overflow: hidden;
}
.textShowBox {
  width: 1800px;
  height: 950px;
  overflow: hidden;
  overflow-y: scroll;
  margin-top: 25px;
}
.textShow >>> p {
  width: 1600px;
  color: white;
  font-size: 2.125rem;
  padding: 0px 30px;
  /* margin-left: 30px; */
  overflow: hidden;
}

.small {
  width: 9.375rem;
  height: 9.375rem;
  overflow: hidden;
  border: 1px solid gray;
  border-radius: 50%;
  position: absolute;
  background-color: rgb(17, 17, 17);
  bottom: 3.125rem;
  right: 0;
}

.small >>> canvas {
  transform: translateX(-73px);
}
::v-deep .el-select {
  width: 150px;
  margin: 0 20px;
}

::v-deep .el-input__inner {
  background-color: transparent;
  color: white;
}

::v-deep .el-select-dropdown__item {
  color: #fff;
}

::v-deep .el-scrollbar,
::v-deep .el-select-dropdown {
  background-color: transparent !important;
  color: #fff !important;
}

::v-deep .el-scrollbar__wrap,
::v-deep .el-select-dropdown__list {
  background-color: #0b1a37;
  color: #fff !important;
}

::v-deep .el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  background-color: rgba(0, 0, 0, 0.3);
  color: #fff;
}
::v-deep .el-select .el-input.is-disabled .el-input__inner {
  background-color: transparent;
}
</style>
