whyczyk
2021-04-22 05e680c785847a9559b68712ad25960bd899391f
3D系统提交
5个文件已修改
42个文件已添加
3926 ■■■■■ 已修改文件
package-lock.json 173 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/aircondition.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/batter.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/channel.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/distribution/behind.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/distribution/fore.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/distribution/left.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/distribution/right.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/distribution/top.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/doorControl.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/door_left.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/door_right.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/floor.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/floor3.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/glass.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/message.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rack_door_back.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rack_front_door.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rack_inside.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rectifier/behind.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rectifier/left.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rectifier/right.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/rectifier/top.png 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/server1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/server2.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/BK.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/DN.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/FR.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/LF.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/RT.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/skybox/UP.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/switchStation/behind.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/switchStation/fore.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/switchStation/left.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/switchStation/top.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/tv.jpg 补丁 | 查看 | 原始文档 | blame | 历史
public/three/images/window.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/three/InitThree.js 1418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/three/data.js 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/three/plugin/DragControls.js 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/three/plugin/ThreeBSP.js 717 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/three/plugin/Tween.js 895 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PageMenu.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/room.vue 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -1328,6 +1328,14 @@
      "integrity": "sha1-qcpLcKGLJwzLK8Cqr+/R1Ia36nQ=",
      "dev": true
    },
    "@types/three": {
      "version": "0.103.2",
      "resolved": "https://registry.npmjs.org/@types/three/-/three-0.103.2.tgz",
      "integrity": "sha512-zhtf0Qs5wLJpIn1+VWCpzSgpKayj/GSWZ6woiuz09FW59KEDeLpnBkYz6lbblVpRmGdlnG8nd0unaASshOvcXw==",
      "requires": {
        "three": "*"
      }
    },
    "@types/uglify-js": {
      "version": "3.11.1",
      "resolved": "https://registry.npm.taobao.org/@types/uglify-js/download/@types/uglify-js-3.11.1.tgz",
@@ -1687,16 +1695,6 @@
          "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
          "dev": true
        },
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1606792266928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
          "dev": true,
          "optional": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "cacache": {
          "version": "13.0.1",
          "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz?cache=0&sync_timestamp=1594429684526&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-13.0.1.tgz",
@@ -1723,53 +1721,6 @@
            "unique-filename": "^1.1.1"
          }
        },
        "chalk": {
          "version": "4.1.0",
          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz",
          "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
          "dev": true,
          "optional": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
          "dev": true,
          "optional": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
          "dev": true,
          "optional": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
          "dev": true,
          "optional": true
        },
        "loader-utils": {
          "version": "2.0.0",
          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
          "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
          "dev": true,
          "optional": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^2.1.2"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
@@ -1784,16 +1735,6 @@
          "requires": {
            "figgy-pudding": "^3.5.1",
            "minipass": "^3.1.1"
          }
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1608035266405&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
          "dev": true,
          "optional": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        },
        "terser-webpack-plugin": {
@@ -1811,18 +1752,6 @@
            "source-map": "^0.6.1",
            "terser": "^4.6.12",
            "webpack-sources": "^1.4.3"
          }
        },
        "vue-loader-v16": {
          "version": "npm:vue-loader@16.1.2",
          "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-16.1.2.tgz?cache=0&sync_timestamp=1608187947155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-16.1.2.tgz",
          "integrity": "sha1-XAO2xQ0qX5g8fOuhXFDXjKKymPQ=",
          "dev": true,
          "optional": true,
          "requires": {
            "chalk": "^4.1.0",
            "hash-sum": "^2.0.0",
            "loader-utils": "^2.0.0"
          }
        }
      }
@@ -10042,6 +9971,11 @@
        "neo-async": "^2.6.0"
      }
    },
    "three": {
      "version": "0.111.0",
      "resolved": "https://registry.npmjs.org/three/-/three-0.111.0.tgz",
      "integrity": "sha512-AcTqyGJ3H75AIusOuADy0LsP958QKQwm/YhABHFMzd6RFXPNVay1rlSbbG6WYv7KM72G2THMMwqbjQd4dVHMkQ=="
    },
    "throttle-debounce": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
@@ -10583,6 +10517,87 @@
        }
      }
    },
    "vue-loader-v16": {
      "version": "npm:vue-loader@16.2.0",
      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz",
      "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==",
      "dev": true,
      "optional": true,
      "requires": {
        "chalk": "^4.1.0",
        "hash-sum": "^2.0.0",
        "loader-utils": "^2.0.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.0",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
          "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
          "dev": true,
          "optional": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "optional": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true,
          "optional": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true,
          "optional": true
        },
        "loader-utils": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
          "dev": true,
          "optional": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^2.1.2"
          }
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "optional": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "vue-router": {
      "version": "3.4.9",
      "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.9.tgz?cache=0&sync_timestamp=1607347284428&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.4.9.tgz",
package.json
@@ -13,7 +13,9 @@
    "postcss-px2rem": "^0.3.0",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
    "vuex": "^3.4.0",
    "three": "^0.111.0",
    "@types/three": "^0.103.2"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
@@ -22,4 +24,4 @@
    "@vue/cli-service": "~4.5.0",
    "vue-template-compiler": "^2.6.11"
  }
}
}
public/three/images/aircondition.png
public/three/images/batter.jpg
public/three/images/channel.jpg
public/three/images/distribution/behind.jpg
public/three/images/distribution/fore.jpg
public/three/images/distribution/left.jpg
public/three/images/distribution/right.jpg
public/three/images/distribution/top.jpg
public/three/images/doorControl.jpg
public/three/images/door_left.png
public/three/images/door_right.png
public/three/images/floor.jpg
public/three/images/floor3.jpg
public/three/images/glass.png
public/three/images/message.jpg
public/three/images/rack_door_back.jpg
public/three/images/rack_front_door.jpg
public/three/images/rack_inside.jpg
public/three/images/rectifier/behind.png
public/three/images/rectifier/left.png
public/three/images/rectifier/right.png
public/three/images/rectifier/top.png
public/three/images/server1.jpg
public/three/images/server2.jpg
public/three/images/skybox/BK.jpg
public/three/images/skybox/DN.jpg
public/three/images/skybox/FR.jpg
public/three/images/skybox/LF.jpg
public/three/images/skybox/RT.jpg
public/three/images/skybox/UP.jpg
public/three/images/switchStation/behind.jpg
public/three/images/switchStation/fore.jpg
public/three/images/switchStation/left.jpg
public/three/images/switchStation/top.jpg
public/three/images/tv.jpg
public/three/images/window.png
src/assets/js/three/InitThree.js
New file
@@ -0,0 +1,1418 @@
/*
 * @Description: THREEjs3D机房应用方法封装
 * @Autor: ZengYK
 * @Date: 2021-01-13 09:45:45
 */
import {
  _
} from "core-js";
import "three/examples/js/controls/OrbitControls"
import "three/examples/js/controls/TransformControls"
import "./plugin/DragControls"
import {
  loadBSP
} from './plugin/ThreeBSP'
loadBSP();
import TWEEN from "./plugin/Tween"
var isOne = 0;
var dbclick = 0;
export class InitThree {
  constructor() {
    this.renderer = null; //渲染器
    this.camera = null; //摄像机
    this.scene = null; //场景
    this.controls = null; //鼠标控制器
    this.transformControls = null; //变化控制器
    this.dragControls = null; //拖拽控制器
    this.startState = false; //动画开关
    this.isEdit = false; //编辑状态
    this.TransFormControlsMode = "translate";
    this.p1 = {
      x: 0,
      y: 0,
      z: 0
    }
    this.p2 = {
      x: 300,
      y: 300,
      z: 0
    }
  }
  start() {
    //开始
    var _this = this;
    _this.initScene()
    _this.initCamera()
    _this.initRender()
    _this.initMouseCtrl()
    _this.initHelpGrid()
    _this.initLight()
    //添加3D对象
    _this.objList.forEach(function (v, i) {
      _this.InitAddObject(v)
    })
    _this.animation(true)
  }
  //向动画场景中添加元素
  sceneAdd(nowObjects) {
    var _this = this;
    _this.InitAddObject(nowObjects);
  }
  //向动画场景中移除元素
  sceneRemove(name) {
    var _this = this;
    var removeObj = _this.findObject(name);
    _this.scene.remove(removeObj);
    _this.objects.forEach((item, index) => {
      if (item.name == name) {
        _this.objects.splice(index, 1);
      }
    })
    _this.dragObjects.forEach((item, index) => {
      if (item.name == name) {
        _this.dragObjects.splice(index, 1);
      }
    })
  }
  //向动画场景中更新元素
  updateObject(obj) {
    var _this = this;
    _this.sceneRemove(obj.name);
    _this.sceneAdd(obj);
  }
  /*
  方法:初始化
  fid 画布所属div的Id
  option:参数 {
    antialias:true,//抗锯齿效果为设置有效
    clearCoolr:0xFFFFFF,//刷新色
    showHelpGrid:false,//是否显示网格线
    showAxisHelper:false,//是否显示坐标轴
    showlinkLine:false,//是否添加视角辅助线
    cameraPosition:[0, 50, 200],//初始化相机视角位置
  }
  */
  initmsj3D(_fId, _option, _datajson) {
    this.option = {};
    this.option.antialias = _option.antialias || true;
    this.option.clearCoolr = _option.clearCoolr;
    this.option.showHelpGrid = _option.showHelpGrid || false;
    this.option.showAxisHelper = _option.showAxisHelper || false;
    this.option.showlinkLine = _option.showlinkLine || false;
    this.option.cameraPosition = _option.cameraPosition || [0, 50, 200];
    //对象
    this.fId = _fId;
    this.element = document.getElementById(this.fId);
    this.width = this.element.clientWidth;
    this.height = this.element.clientHeight;
    this.renderer = null; //渲染器
    this.camera = null; //摄像机
    this.scene = null; //场景
    this.SELECTED = null;
    this.objects = [];
    this.dragObjects = []; //拖动对象
    this.mouseClick = new THREE.Vector2();
    this.raycaster = new THREE.Raycaster();
    this.controls = null; //鼠标控制器
    this.objList = _datajson.objects; //对象列表
    this.eventList = _datajson.events; //事件对象列表
  }
  //创建场景
  initScene() {
    var _this = this
    _this.scene = new THREE.Scene()
  }
  //初始化摄像机
  initCamera() {
    var _this = this
    var width = this.width; // 窗口宽度
    var height = this.height; // 窗口高度
    var k = width / height; // 窗口宽高比
    _this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 10000);
    _this.camera.name = 'mainCamera'
    _this.camera.position.set(this.option.cameraPosition[0], this.option.cameraPosition[1], this.option.cameraPosition[2]); // 设置相机位置
    _this.camera.lookAt(new THREE.Vector3(0, 0, 0));
    _this.objects.push(_this.camera)
  }
  //灯光布置
  initLight() {
    /**
     * AmbientLight: 环境光,基础光源,它的颜色会被加载到整个场景和所有对象的当前颜色上。
     * PointLight: 点光源,朝着所有方向都发射光线
     * SpotLight: 聚光灯光源:类型台灯,天花板上的吊灯,手电筒等
     * DirectionalLight: 方向光,又称无限光,从这个发出的光源可以看做是平行光.
     */
    var _this = this;
    var light = new THREE.AmbientLight(0xcccccc);
    light.position.set(0, 0, 0);
    _this.scene.add(light);
    var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); //模拟远处类似太阳的光源
    directionalLight.color.setHSL(0.1, 1, 0.95);
    directionalLight.position.set(0, 200, 0).normalize();
    _this.scene.add(directionalLight);
  }
  //初始化渲染器
  initRender() {
    var _this = this;
    _this.renderer = new THREE.WebGLRenderer({
      antialias: _this.option.antialias,
      alpha: true, //是否可以设置背景色透明。
      logarithmicDepthBuffer: true //模型的重叠部位便不停的闪烁起来。这便是Z-Fighting问题,为解决这个问题,我们可以采用该种方法
    });
    _this.renderer.setPixelRatio(window.devicePixelRatio);
    _this.renderer.setSize(_this.width, _this.height);
    _this.element.appendChild(_this.renderer.domElement)
    if (_this.option.clearCoolr) {
      _this.renderer.setClearColor(_this.option.clearCoolr, 1.0);
    }
    _this.renderer.shadowMap.enabled = true; //
    _this.renderer.shadowMapSoft = true;
    _this.renderer.domElement.addEventListener('mousedown', (e) => {
      _this.onDocumentMouseDown(e)
    }, false);
    _this.renderer.domElement.addEventListener('mouseup', (e) => {
      _this.onDocumentMouseUp(e)
    }, false);
    window.addEventListener('resize', (e) => {
      _this.onWindowResize(e)
    }, false);
  }
  //创建鼠标控制器
  initMouseCtrl() {
    var _this = this;
    _this.controls = new THREE.OrbitControls(_this.camera, _this.renderer.domElement)
    _this.controls.enableDamping = true
    _this.controls.dampingFactor = 0.5
    // 视角最小距离
    _this.controls.minDistance = 100
    // 视角最远距离
    _this.controls.maxDistance = 2200
    // 最大角度
    _this.controls.maxPolarAngle = Math.PI / 2.2
    _this.controls.target = new THREE.Vector3(0, 120, 0) // 设置控制器的旋转原点
    _this.controls.autoRotateSpeed = 0.5;
    _this.controls.autoRotate = true;
  }
  //创建变化控制器
  initTransFormControls(object, type) {
    var _this = this;
    _this.transformControls = new THREE.TransformControls(_this.camera, _this.renderer.domElement);
    _this.transformControls.addEventListener('dragging-changed', function (event) {
      _this.controls.enabled = !event.value
    });
    _this.transformControls.setSize(0.5); // 设置三维坐标轴大小
    _this.transformControls.attach(object);
    if (type == "rotate") {
      _this.transformControls.space = "local";
      _this.transformControls.rotationSnap = 0.25 * Math.PI;
      _this.transformControls.setSize(0.2);
      _this.transformControls.showX = false;
      _this.transformControls.showZ = false;
      _this.transformControls.setMode(type);
    } else if (type == "translate") {
      _this.transformControls.setMode(type);
    }
    _this.controls.enabled = false;
    _this.scene.add(_this.transformControls);
  }
  //设置变化控制器变化方法
  setTransFormControlsMode(type) {
    var _this = this;
    _this.TransFormControlsMode = type;
  }
  //消除变化控制器
  DeleteTransFormControls() {
    var _this = this;
    _this.transformControls.detach();
    _this.controls.enabled = true;
    _this.scene.remove(_this.transformControls);
  };
  //创建控制变化器绑定事件
  initDragControls() {
    if (this.isEdit) {
      return
    }
    var _this = this;
    _this.isEdit = true;
    _this.dragControls = new THREE.DragControls(_this.dragObjects, _this.camera, _this.renderer.domElement);
    // 鼠标略过事件
    _this.dragControls.addEventListener('hoveron', function (event) {
      // 让变换控件对象和选中的对象绑定
      _this.initTransFormControls(event.object, _this.TransFormControlsMode);
    });
    // 鼠标略出事件
    _this.dragControls.addEventListener('hoveroff', function (event) {
      // 移除变换控件
      _this.DeleteTransFormControls()
      _this.scene.children.forEach((item) => {
        if (item.children.length > 0 && item.children[0].type == "TransformControlsGizmo") {
          _this.scene.remove(item);
        }
      });
    });
    // 开始拖拽
    _this.dragControls.addEventListener('dragstart', function (event) {
      _this.controls.enabled = false;
    });
    // 拖拽结束
    _this.dragControls.addEventListener('dragend', function (event) {
      _this.controls.enabled = true;
    });
  }
  //消除控制变化器绑定事件
  DeleteDragControls() {
    var _this = this;
    _this.isEdit = false;
    if (_this.transformControls) {
      _this.transformControls.detach();
      _this.scene.remove(_this.transformControls);
    }
    _this.scene.children.forEach((item) => {
      if (item.children.length > 0 && item.children[0].type == "TransformControlsGizmo") {
        _this.scene.remove(item);
      }
    });
    _this.dragControls.deactivate();
  }
  //添加对象
  addObject(_obj) {
    var _this = this
    _this.objects.push(_obj)
    _this.scene.add(_obj)
  }
  //创建网格线
  initHelpGrid() {
    var _this = this
    if (_this.option.showHelpGrid) {
      var helpGrid = new THREE.GridHelper(1000, 50)
      _this.scene.add(helpGrid)
    }
    if (_this.option.showAxisHelper) {
      var AxisHelper = new THREE.AxisHelper(3000);
      _this.scene.add(AxisHelper)
    }
  }
  //创建视角引导线
  linkLine() {
    var _this = this;
    if (_this.option.showlinkLine) {
      var pX = (_this.p1.x / _this.width) * 2 - 1;
      var pY = -(_this.p1.y / _this.height) * 2 + 1;
      var p = new THREE.Vector3(pX, pY, -1).unproject(_this.camera)
      var geometry = new THREE.Geometry();
      var material = new THREE.LineBasicMaterial({
        color: 0xff0000
      });
      geometry.vertices.push(_this.p1)
      _this.p2.x = p.x + 300
      _this.p2.y = p.y + 300
      _this.p2.z = p.z + 300
      geometry.vertices.push(_this.p2)
      var line = new THREE.Line(geometry, material, THREE.LineSegments)
      line.name = 'xfxian'
      _this.scene.add(line)
    }
  }
  linemove() {
    var _this = this;
    var xf = [..._this.scene.children].find(function (v) {
      return v.name == 'xfxian'
    })
    _this.p1 = _this.p1
    var pX = (400 / _this.width) * 2 - 1;
    var pY = -(200 / _this.height) * 2 + 1;
    var p = new THREE.Vector3(pX, pY, -1)
    var p = new THREE.Vector3(pX, pY, -1).unproject(_this.camera)
    _this.p2.x = p.x
    _this.p2.y = p.y
    _this.p2.z = p.z
    xf.geometry.verticesNeedUpdate = true
  }
  //执行渲染
  render() {
    var _this = this;
    _this.renderer.render(_this.scene, _this.camera);
  }
  //循环渲染界面
  animation(start) {
    if (start) {
      console.log('已经启动持续更新');
      this.startState = true;
    }
    // 停止更新
    if (!this.startState || document.visibilityState != document.visibilityState) {
      return;
    }
    var _this = this;
    if (TWEEN.Tween != null && typeof (TWEEN.Tween) != 'undefined') {
      TWEEN.update();
    }
    requestAnimationFrame(() => {
      _this.animation()
    })
    _this.render();
    if (!isOne) {
      this.linkLine()
      isOne++
    }
    if (_this.option.showlinkLine) {
      _this.linemove()
    }
  }
  //停止循环渲染界面
  stop() {
    this.startState = false;
    console.log('已经停止持续更新');
  }
  timeRender() {
    //调用一次可以渲染三秒
    var timeOut = null;
    //设置为可渲染状态
    this.startState = true;
    //清除上次的延迟器
    if (timeOut) {
      clearTimeout(timeOut);
    }
    timeOut = setTimeout(function () {
      this.startState = false;
    }, 3000);
  }
  //初始化数据对象
  InitAddObject(_obj) {
    var _this = this;
    if (_obj.show == null || typeof (_obj.show) == 'undefined' || _obj.show) {
      var _tempObj = null;
      var _tempObjList = []
      switch (_obj.objType) {
        case 'Skybox':
          _this.CreateSkybox(_obj);
          break;
        case 'cube':
          _tempObj = _this.createCube(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'floor':
          _tempObj = _this.CreateFloor(_obj)
          _this.addObject(_tempObj);
          break;
        case 'wall':
          _tempObjList = _this.CreateWall(_this, _obj);
          _tempObjList.forEach((v, i) => {
            _this.addObject(v)
          })
          break;
        case 'channel':
          _tempObj = _this.createChannelGeometry(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'plane':
          _tempObj = _this.createPlaneGeometry(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'glasses':
          _tempObj = _this.createGlasses(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'emptyCabinet':
          _tempObj = _this.createEmptyCabinet(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'shelves':
          _tempObj = _this.createShelves(_this, _obj);
          _this.addObject(_tempObj);
          break;
        case 'cloneObj':
          _tempObj = _this.cloneObj(_obj.copyfrom, _obj);
          _this.addObject(_tempObj);
          break;
      }
    }
  }
  //创建天空盒
  CreateSkybox(_obj) {
    const urls = _obj.urls
    const skyboxCubeMap = new THREE.CubeTextureLoader().load(urls);
    this.scene.background = skyboxCubeMap;
  }
  //创建地板
  CreateFloor(_obj) {
    var _this = this;
    var _cube = _this.createCube(_this, _obj);
    return _cube;
  }
  //创建墙体
  CreateWall(_this, _obj) {
    if (_this == null) {
      _this = this;
    }
    var cubeList = []
    var _commonThick = _obj.thick || 40; //墙体厚度
    var _commonLength = _obj.length || 100; //墙体厚度
    var _commonHeight = _obj.height || 300; //强体高度
    var _commonSkin = _obj.style.skinColor || 0x98750f;
    //建立墙面
    _obj.wallData.forEach(function (v, i) {
      var wallLength = _commonLength;
      var wallWidth = v.thick || _commonThick;
      var positionX = ((v.startDot.x || 0) + (v.endDot.x || 0)) / 2;
      var positionY = ((v.startDot.y || 0) + (v.endDot.y || 0)) / 2;
      var positionZ = ((v.startDot.z || 0) + (v.endDot.z || 0)) / 2;
      //z相同 表示x方向为长度
      if (v.startDot.z == v.endDot.z) {
        wallLength = Math.abs(v.startDot.x - v.endDot.x);
        wallWidth = v.thick || _commonThick;
      } else if (v.startDot.x == v.endDot.x) {
        wallLength = v.thick || _commonThick;
        wallWidth = Math.abs(v.startDot.z - v.endDot.z);
      }
      var cubeobj = {
        length: wallLength,
        width: wallWidth,
        height: v.height || _commonHeight,
        rotation: v.rotation,
        x: positionX,
        y: positionY,
        z: positionZ,
        uuid: v.uuid,
        name: v.name,
        transparent: v.transparent || false,
        style: {
          skinColor: _commonSkin,
          skin: v.skin
        }
      }
      var _cube = _this.createCube(_this, cubeobj);
      if (_this.hasObj(v.childrens) && v.childrens.length > 0) {
        v.childrens.forEach(function (v1, i1) {
          var _newobj = null;
          _newobj = _this.CreateHole(_this, v1);
          _cube = _this.mergeModel(_this, v1.op, _cube, _newobj);
        })
      }
      cubeList.push(_cube)
    })
    return cubeList
  }
  //挖洞
  CreateHole(_this, _obj) {
    if (_this == null) {
      _this = this;
    }
    var _commonThick = 40; // 墙体厚度
    var _commonLength = 100; // 墙体厚度
    var _commonHeight = 300; // 强体高度
    var _commonSkin = 0x98750f;
    //建立墙面
    var wallLength = _commonLength;
    var wallWidth = _obj.thick || _commonThick;
    var positionX = ((_obj.startDot.x || 0) + (_obj.endDot.x || 0)) / 2;
    var positionY = ((_obj.startDot.y || 0) + (_obj.endDot.y || 0)) / 2;
    var positionZ = ((_obj.startDot.z || 0) + (_obj.endDot.z || 0)) / 2;
    //z相同 表示x方向为长度
    if (_obj.startDot.z == _obj.endDot.z) {
      wallLength = Math.abs(_obj.startDot.x - _obj.endDot.x);
      wallWidth = _obj.thick || _commonThick;
    } else if (_obj.startDot.x == _obj.endDot.x) {
      wallLength = _obj.thick || _commonThick;
      wallWidth = Math.abs(_obj.startDot.z - _obj.endDot.z);
    }
    var cubeobj = {
      length: wallLength,
      width: wallWidth,
      height: _obj.height || _commonHeight,
      rotation: _obj.rotation,
      x: positionX,
      uuid: _obj.uuid,
      name: _obj.name,
      y: positionY,
      z: positionZ,
      transparent: _obj.transparent || false,
      style: {
        skinColor: _commonSkin,
        skin: _obj.skin
      }
    }
    var _cube = _this.createCube(_this, cubeobj);
    return _cube;
  }
  //模型合并 使用ThreeBSP插件mergeOP计算方式 -表示减去 +表示加上
  mergeModel(_this, mergeOP, _fobj, _sobj) {
    if (_this == null) {
      _this = this;
    }
    var fobjBSP = new ThreeBSP(_fobj);
    var sobjBSP = new ThreeBSP(_sobj);
    var resultBSP = null;
    if (mergeOP == '-') {
      resultBSP = fobjBSP.subtract(sobjBSP);
    } else if (mergeOP == '+') {
      var subMesh = new THREE.Mesh(_sobj);
      _sobj.updateMatrix();
      _fobj.geometry.merge(_sobj.geometry, _sobj.matrix);
      return _fobj;
      // resultBSP = fobjBSP.union(sobjBSP);
    } else if (mergeOP == '&') { //交集
      resultBSP = fobjBSP.intersect(sobjBSP);
    } else {
      _this.addObject(_sobj);
      return _fobj;
    }
    var cubeMaterialArray = [];
    for (var i = 0; i < 1; i++) {
      cubeMaterialArray.push(new THREE.MeshLambertMaterial({
        vertexColors: THREE.FaceColors
      }));
    }
    var result = resultBSP.toMesh(cubeMaterialArray);
    result.material.shading = THREE.FlatShading;
    result.geometry.computeFaceNormals();
    result.geometry.computeVertexNormals();
    result.uuid = _fobj.uuid + mergeOP + _sobj.uuid;
    result.name = _fobj.name + mergeOP + _sobj.name;
    result.material.needsUpdate = true;
    result.geometry.buffersNeedUpdate = true;
    result.geometry.uvsNeedUpdate = true;
    var _foreFaceSkin = null;
    for (var i = 0; i < result.geometry.faces.length; i++) {
      var _faceset = false;
      for (var j = 0; j < _fobj.geometry.faces.length; j++) {
        if (result.geometry.faces[i].vertexNormals[0].x === _fobj.geometry.faces[j].vertexNormals[0].x &&
          result.geometry.faces[i].vertexNormals[0].y === _fobj.geometry.faces[j].vertexNormals[0].y &&
          result.geometry.faces[i].vertexNormals[0].z === _fobj.geometry.faces[j].vertexNormals[0].z &&
          result.geometry.faces[i].vertexNormals[1].x === _fobj.geometry.faces[j].vertexNormals[1].x &&
          result.geometry.faces[i].vertexNormals[1].y === _fobj.geometry.faces[j].vertexNormals[1].y &&
          result.geometry.faces[i].vertexNormals[1].z === _fobj.geometry.faces[j].vertexNormals[1].z &&
          result.geometry.faces[i].vertexNormals[2].x === _fobj.geometry.faces[j].vertexNormals[2].x &&
          result.geometry.faces[i].vertexNormals[2].y === _fobj.geometry.faces[j].vertexNormals[2].y &&
          result.geometry.faces[i].vertexNormals[2].z === _fobj.geometry.faces[j].vertexNormals[2].z) {
          result.geometry.faces[i].color.setHex(_fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff);
          _foreFaceSkin = _fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff;
          _faceset = true;
        }
      }
      if (_faceset == false) {
        for (var j = 0; j < _sobj.geometry.faces.length; j++) {
          if (result.geometry.faces[i].vertexNormals[0].x === _sobj.geometry.faces[j].vertexNormals[0].x &&
            result.geometry.faces[i].vertexNormals[0].y === _sobj.geometry.faces[j].vertexNormals[0].y &&
            result.geometry.faces[i].vertexNormals[0].z === _sobj.geometry.faces[j].vertexNormals[0].z &&
            result.geometry.faces[i].vertexNormals[1].x === _sobj.geometry.faces[j].vertexNormals[1].x &&
            result.geometry.faces[i].vertexNormals[1].y === _sobj.geometry.faces[j].vertexNormals[1].y &&
            result.geometry.faces[i].vertexNormals[1].z === _sobj.geometry.faces[j].vertexNormals[1].z &&
            result.geometry.faces[i].vertexNormals[2].x === _sobj.geometry.faces[j].vertexNormals[2].x &&
            result.geometry.faces[i].vertexNormals[2].y === _sobj.geometry.faces[j].vertexNormals[2].y &&
            result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z &&
            result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z) {
            result.geometry.faces[i].color.setHex(_sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff);
            _foreFaceSkin = _sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff;
            _faceset = true;
          }
        }
      }
      if (_faceset == false) {
        result.geometry.faces[i].color.setHex(_foreFaceSkin);
      }
    }
    result.castShadow = true;
    result.receiveShadow = true;
    return result;
  }
  //创建盒子体
  createCube(_this, _obj) {
    if (_this == null) {
      _this = this;
    }
    var _length = _obj.length || 1000; //默认1000
    var _width = _obj.width || _length;
    var _height = _obj.height || 10;
    var _x = _obj.x || 0,
      _y = _obj.y || 0,
      _z = _obj.z || 0;
    var skinColor = _obj.style.skinColor || 0x98750f;
    var cubeGeometry = new THREE.BoxGeometry(_length, _height, _width, 0, 0, 1);
    //六面颜色
    for (var i = 0; i < cubeGeometry.faces.length; i += 2) {
      var hex = skinColor || Math.random() * 0x531844;
      cubeGeometry.faces[i].color.setHex(hex);
      cubeGeometry.faces[i + 1].color.setHex(hex);
    }
    //六面纹理
    var skin_up_obj = {
      vertexColors: THREE.FaceColors
    }
    var skin_down_obj = skin_up_obj,
      skin_fore_obj = skin_up_obj,
      skin_behind_obj = skin_up_obj,
      skin_left_obj = skin_up_obj,
      skin_right_obj = skin_up_obj;
    var skin_opacity = 1;
    var transparent = _obj.transparent || false;
    if (_obj.style != null && typeof (_obj.style) != 'undefined' &&
      _obj.style.skin != null && typeof (_obj.style.skin) != 'undefined') {
      //透明度
      if (_obj.style.skin.opacity != null && typeof (_obj.style.skin.opacity) != 'undefined') {
        skin_opacity = _obj.style.skin.opacity;
      }
      //上
      skin_up_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_up, cubeGeometry, 4, skin_opacity, transparent);
      //下
      skin_down_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_down, cubeGeometry, 6, skin_opacity, transparent);
      //前
      skin_fore_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_fore, cubeGeometry, 0, skin_opacity, transparent);
      //后
      skin_behind_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_behind, cubeGeometry, 2, skin_opacity, transparent);
      //左
      skin_left_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_left, cubeGeometry, 8, skin_opacity, transparent);
      //右
      skin_right_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_right, cubeGeometry, 10, skin_opacity, transparent);
    }
    var cubeMaterialArray = [];
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_fore_obj));
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_behind_obj));
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_up_obj));
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_down_obj));
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_right_obj));
    cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_left_obj));
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterialArray);
    cube.castShadow = true;
    cube.receiveShadow = true;
    cube.uuid = _obj.uuid;
    cube.name = _obj.name;
    cube.position.set(_x, _y, _z);
    if (_obj.rotation != null && typeof (_obj.rotation) != 'undefined' && _obj.rotation.length > 0) {
      _obj.rotation.forEach(function (v, i) {
        switch (v.direction) {
          case 'x':
            cube.rotateX(v.degree);
            break;
          case 'y':
            cube.rotateY(v.degree);
            break;
          case 'z':
            cube.rotateZ(v.degree);
            break;
          case 'arb':
            cube.rotateOnAxis(new THREE.Vector3(v.degree[0], v.degree[1], v.degree[2]), v.degree[3]);
            break;
        }
      })
    }
    return cube;
  }
  //创建皮肤参数对象
  createSkinOptionOnj(_this, flength, fwidth, _obj, _cube, _cubefacenub, opacity, transparent) {
    if (_this.hasObj(_obj)) {
      if (_this.hasObj(_obj.imgurl)) {
        return {
          map: _this.createSkin(flength, fwidth, _obj),
          transparent: transparent,
          opacity: opacity,
        }
      } else {
        if (_this.hasObj(_obj.skinColor)) {
          _cube.faces[_cubefacenub].color.setHex(_obj.skinColor);
          _cube.faces[_cubefacenub + 1].color.setHex(_obj.skinColor);
        }
        return {
          vertexColors: THREE.FaceColors
        }
      }
    } else {
      return {
        vertexColors: THREE.FaceColors
      }
    }
  }
  //创建皮肤
  createSkin(flength, fwidth, _obj) {
    var imgwidth = 128,
      imgheight = 128;
    if (_obj.width != null && typeof (_obj.width) != 'undefined') {
      imgwidth = _obj.width;
    }
    if (_obj.height != null && typeof (_obj.height) != 'undefined') {
      imgheight = _obj.height;
    }
    var texture = new THREE.TextureLoader().load(_obj.imgurl, function (e) {}, function (e) {});
    var _repeat = false;
    if (_obj.repeatx != null && typeof (_obj.repeatx) != 'undefined' && _obj.repeatx == true) {
      texture.wrapS = THREE.RepeatWrapping;
      _repeat = true;
    }
    if (_obj.repeaty != null && typeof (_obj.repeaty) != 'undefined' && _obj.repeaty == true) {
      texture.wrapT = THREE.RepeatWrapping;
      _repeat = true;
    }
    if (_repeat) {
      texture.repeat.set(flength / imgheight, fwidth / imgheight);
    }
    return texture;
  }
  //创建空柜子
  createEmptyCabinet(_this, _obj) {
    /* 参数demo
    {
      show:true,
      name: 'test',
      uuid: 'test',
      rotation: [{ direction: 'y', degree: 0.25*Math.PI}],//旋转
      objType: 'emptyCabinet',
      transparent:true,
      size:{length:50,width:60,height:200, thick:2},
      position: { x: -220, y: 105, z: -150 },
      doors: {
          skins:[ {
              skinColor: 0x333333,
              skin_fore: {
                  imgurl: "../datacenterdemo/res/rack_door_back.jpg",
              },
              skin_behind: {
                  imgurl: "../datacenterdemo/res/rack_front_door.jpg",
              }
          }]
      },
      skin:{
        skinColor: 0xdddddd,
        skin:{
          skinColor: 0xdddddd,
          skin_up: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
          skin_down: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
          skin_fore: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
          skin_behind: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
          skin_left: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
          skin_right: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" },
        }
      }
    }
    */
    var _this = this;
    var cabLength = Number(_obj.length) || 66; //机柜长
    var cabWidth = Number(_obj.width) || 70; //机柜宽
    var cabHeight = Number(_obj.height) || 200; //机柜高
    var cabThick = Number(_obj.thick) || 2; //机柜壁厚
    var cabPx = Number(_obj.x) || 0; //中心原点X值
    var cabPy = Number(_obj.y) || 100; //中心原点Y值
    var cabPz = Number(_obj.z) || 0; //中心原点Z值
    //创建五个面
    //上
    var upobj = {
      show: true,
      uuid: "",
      name: 'upobj',
      objType: 'cube',
      length: cabLength,
      width: cabWidth,
      height: cabThick,
      x: cabPx,
      y: cabPy,
      z: cabPz,
      style: {
        skinColor: _obj.skin.skinColor,
        skin: _obj.skin.skin_up.skin
      }
    }
    var upcube = _this.createCube(_this, upobj);
    //左
    var leftobj = {
      show: true,
      uuid: "",
      name: 'leftobj',
      objType: 'cube',
      length: cabLength,
      width: cabThick,
      height: cabHeight,
      x: 0,
      y: -(cabHeight / 2 - cabThick / 2),
      z: 0 - (cabWidth / 2 - cabThick / 2) - 1,
      style: {
        skinColor: _obj.skin.skinColor,
        skin: _obj.skin.skin_left.skin
      }
    }
    var leftcube = _this.createCube(_this, leftobj);
    var Cabinet = _this.mergeModel(_this, '+', upcube, leftcube);
    //右
    var Rightobj = {
      show: true,
      uuid: "",
      name: 'Rightobj',
      objType: 'cube',
      length: cabLength,
      width: cabThick,
      height: cabHeight,
      x: 0,
      y: -(cabHeight / 2 - cabThick / 2),
      z: (cabWidth / 2 - cabThick / 2) + 1,
      style: {
        skinColor: _obj.skin.skinColor,
        skin: _obj.skin.skin_right.skin
      }
    }
    var Rightcube = _this.createCube(_this, Rightobj);
    Cabinet = _this.mergeModel(_this, '+', Cabinet, Rightcube);
    //后
    var Behidobj = {
      show: true,
      uuid: "",
      name: 'Behidobj',
      objType: 'cube',
      length: cabThick,
      width: cabWidth,
      height: cabHeight,
      x: (cabLength / 2 - cabThick / 2) + 1,
      y: -(cabHeight / 2 - cabThick / 2),
      z: 0,
      style: {
        skinColor: _obj.skin.skinColor,
        skin: _obj.skin.skin_behind.skin
      }
    }
    var Behindcube = _this.createCube(_this, Behidobj);
    Cabinet = _this.mergeModel(_this, '+', Cabinet, Behindcube);
    //下
    var Downobj = {
      show: true,
      uuid: "",
      name: 'Downobj',
      objType: 'cube',
      length: cabLength,
      width: cabWidth,
      height: cabThick,
      x: -1,
      y: -(cabHeight - cabThick) - 1,
      z: 0,
      style: {
        skinColor: _obj.skin.skinColor,
        skin: _obj.skin.skin_down.skin
      }
    }
    var Downcube = _this.createCube(_this, Downobj);
    Cabinet = _this.mergeModel(_this, '+', Cabinet, Downcube);
    var tempobj = new THREE.Object3D();
    tempobj.add(Cabinet);
    tempobj.name = _obj.name;
    tempobj.uuid = _obj.uuid;
    for (const key in Cabinet.position) {
      tempobj.position[key] = Cabinet.position[key]
    }
    Cabinet.name = _obj.shellname;
    Cabinet.position.set(0, cabPy, 0);
    _this.objects.push(Cabinet);
    //门
    if (_obj.doors != null && typeof (_obj.doors) != 'undefined') {
      var doors = _obj.doors;
      var singledoorobj = {
        show: true,
        uuid: "",
        name: _obj.doors.doorname,
        objType: 'cube',
        length: cabThick,
        width: cabWidth,
        height: cabHeight,
        x: -cabLength / 2,
        y: cabPy - cabHeight / 2,
        z: 0,
        transparent: _obj.doors.transparent || false,
        style: {
          skinColor: _obj.doors.skins.skinColor,
          skin: _obj.doors.skins
        }
      }
      var singledoorcube = _this.createCube(_this, singledoorobj);
      _this.objects.push(singledoorcube);
      tempobj.add(singledoorcube);
    }
    if (_obj.rotation != null && typeof (_obj.rotation) != 'undefined' && _obj.rotation.length > 0) {
      _obj.rotation.forEach(function (v, i) {
        switch (v.direction) {
          case 'x':
            tempobj.rotateX(v.degree);
            break;
          case 'y':
            tempobj.rotateY(v.degree);
            break;
          case 'z':
            tempobj.rotateZ(v.degree);
            break;
          case 'arb':
            tempobj.rotateOnAxis(new THREE.Vector3(v.degree[0], v.degree[1], v.degree[2]), v.degree[3]);
            break;
        }
      })
    }
    //创建机柜所属服务器
    if (_this.hasObj(_obj.childrens) && _obj.childrens.length > 0) {
      _obj.childrens.forEach(function (item, m) {
        var newObj = item;
        newObj.length = cabLength;
        newObj.width = cabWidth;
        newObj.height = item.height || 20;
        newObj.x = 0;
        newObj.z = 0;
        newObj.y = item.y;
        tempobj.add(_this.createCube(_this, newObj));
      })
    }
    _this.dragObjects.push(tempobj);
    return tempobj;
  }
  //创建玻璃
  createGlasses(_this, _obj) {
    var _this = this;
    var tmpobj = _this.createPlaneGeometry(_this, _obj);
    _this.addObject(tmpobj);
    _obj.rotation.y = Math.PI + _obj.rotation.y;
    var tmpobj2 = _this.createPlaneGeometry(_this, _obj);
    // _this.addObject(tmpobj2);
    return tmpobj2
  }
  //创建管道
  createChannelGeometry(_this, _obj) {
    var _this = this;
    let pathArr = [];
    if (_obj.path.length > 0) {
      _obj.path.map(item => {
        pathArr.push(new THREE.Vector3(item.x, item.y, item.z))
      })
    } else {
      pathArr = []
    }
    var path = new THREE.CatmullRomCurve3(pathArr);
    let tubularSegments = _obj.tubularSegments || 64;
    let radius = _obj.radius || 2;
    let radiusSegments = _obj.radiusSegments || 18;
    let closed = _obj.closed || false;
    var tubeGeometry = new THREE.TubeGeometry(path, tubularSegments, radius, radiusSegments, closed);
    var textureLoader = new THREE.TextureLoader();
    var texture = textureLoader.load(_obj.imgurl);
    // 设置阵列模式 RepeatWrapping
    texture.wrapS = THREE.RepeatWrapping
    texture.wrapT = THREE.RepeatWrapping
    // 设置x方向的重复数(沿着管道路径方向)
    // 设置y方向的重复数(环绕管道方向)
    texture.repeat.x = 10;
    texture.repeat.y = 4;
    // 设置管道纹理偏移数,便于对中
    texture.offset.y = 0.5;
    var tubeMaterial = new THREE.MeshPhongMaterial({
      map: texture,
      transparent: true,
    });
    var channel = new THREE.Mesh(tubeGeometry, tubeMaterial);
    // 使用加减法可以设置不同的运动方向
    setInterval(() => {
      texture.offset.x += 0.0076
    })
    return channel;
  }
  //创建二维平面-长方形
  createPlaneGeometry(_this, _obj) {
    //options={
    //  width:0,
    //  height:0,
    //  pic:"",
    //  transparent:true,
    //  opacity:1
    //  blending:false,
    //  position: { x:,y:,z:},
    //  rotation: { x:,y:,z:},
    //}
    var options = _obj;
    if (typeof options.pic == "string") { //传入的材质是图片路径,使用 textureloader加载图片作为材质
      var loader = new THREE.TextureLoader();
      loader.setCrossOrigin(this.crossOrigin);
      var texture = loader.load(options.pic, function () {}, undefined, function () {});
    } else {
      var texture = new THREE.CanvasTexture(options.pic)
    }
    var MaterParam = { //材质的参数
      map: texture,
      // overdraw: true,
      side: THREE.FrontSide,
      transparent: options.transparent,
      opacity: options.opacity
    }
    if (options.blending) {
      MaterParam.blending = THREE.AdditiveBlending //使用饱和度叠加渲染
    }
    var plane = new THREE.Mesh(
      new THREE.PlaneGeometry(options.width, options.height, 1, 1),
      new THREE.MeshBasicMaterial(MaterParam)
    );
    plane.position.x = options.position.x;
    plane.position.y = options.position.y;
    plane.position.z = options.position.z;
    plane.rotation.x = options.rotation.x;
    plane.rotation.y = options.rotation.y;
    plane.rotation.z = options.rotation.z;
    return plane;
  }
  //创建货架及货架上商品(电池)
  createShelves(_this, _obj) {
    var _this = this;
    var PLANE_LENGTH = Number(_obj.PLANE_LENGTH) || 66; //货架板面长度
    var PLANE_WIDTH = Number(_obj.PLANE_WIDTH) || 70; //货架板面宽度
    var PLANE_HEIGHT = Number(_obj.PLANE_HEIGHT) || 4; //货架板面高度
    var HOLDER_LENGTH = Number(_obj.HOLDER_LENGTH) || 4; //支架长度
    var HOLDER_WIDTH = Number(_obj.HOLDER_WIDTH) || 4; //支架宽度
    var HOLDER_HEIGHT = Number(_obj.HOLDER_HEIGHT) || 40; //支架高度
    var LAYER_NUM = Number(_obj.LAYER_NUM) + 1 || 3; //货架层数
    var COLUMN_NUM = Number(_obj.COLUMN_NUM) || 2; //货架每层列数
    var px = Number(_obj.x) || 0 //货架中心位置
    var py = Number(_obj.y) || 0 //货架中心位置
    var pz = Number(_obj.z) || 0 //货架中心位置
    var tempobj = new THREE.Object3D();
    // 创建每层货架板
    for (let i = 0; i < LAYER_NUM; i++) {
      tempobj.add(_this.createCube(_this, {
        show: true,
        uuid: "",
        name: 'layers',
        objType: 'cube',
        length: PLANE_LENGTH,
        width: PLANE_WIDTH * COLUMN_NUM + HOLDER_WIDTH,
        height: PLANE_HEIGHT,
        x: px,
        y: py + (HOLDER_HEIGHT + PLANE_HEIGHT) * i + PLANE_HEIGHT / 2 + 10,
        z: pz,
        style: {
          skinColor: _obj.style.skinColor,
          skin: _obj.style.skin
        }
      }))
      if (i < LAYER_NUM - 1) {
        // 创建货架支架
        for (let j = 0; j < (COLUMN_NUM + 1) * 2; j++) {
          if (j < COLUMN_NUM + 1) {
            tempobj.add(_this.createCube(_this, {
              show: true,
              uuid: "",
              name: 'Bracket',
              objType: 'cube',
              length: HOLDER_LENGTH,
              width: HOLDER_WIDTH,
              height: HOLDER_HEIGHT + PLANE_HEIGHT + (10 * (i + 1)),
              x: px + PLANE_LENGTH / 2 - HOLDER_LENGTH / 2,
              y: py + (HOLDER_HEIGHT + PLANE_HEIGHT) * i + PLANE_HEIGHT / 2 + 10 + HOLDER_HEIGHT / 2 - PLANE_HEIGHT * (LAYER_NUM - 1),
              z: pz - (PLANE_WIDTH * COLUMN_NUM) / 2 + PLANE_WIDTH * j,
              style: {
                skinColor: _obj.style.skinColor,
                skin: _obj.style.skin
              }
            }))
          } else {
            tempobj.add(_this.createCube(_this, {
              show: true,
              uuid: "",
              name: 'Bracket',
              objType: 'cube',
              length: HOLDER_LENGTH,
              width: HOLDER_WIDTH,
              height: HOLDER_HEIGHT + PLANE_HEIGHT + (10 * (i + 1)),
              x: px - PLANE_LENGTH / 2 + HOLDER_LENGTH / 2,
              y: py + (HOLDER_HEIGHT + PLANE_HEIGHT) * i + PLANE_HEIGHT / 2 + 10 + HOLDER_HEIGHT / 2 - PLANE_HEIGHT * (LAYER_NUM - 1),
              z: pz - (PLANE_WIDTH * COLUMN_NUM) / 2 + PLANE_WIDTH * (j - COLUMN_NUM - 1),
              style: {
                skinColor: _obj.style.skinColor,
                skin: _obj.style.skin
              }
            }))
          }
        }
      }
    }
    if (_this.hasObj(_obj.childrens) && _obj.childrens.length > 0) {
      _obj.childrens.forEach(function (item, m) {
        if (m < LAYER_NUM * COLUMN_NUM) {
          var layers = Math.ceil((m + 1) / COLUMN_NUM) - 1;
          var index;
          if ((m + 1) > COLUMN_NUM) {
            index = m - COLUMN_NUM * layers;
          } else {
            index = m
          }
          var _newobj = item;
          _newobj.length = item.length || PLANE_LENGTH;
          _newobj.width = item.width || PLANE_WIDTH - HOLDER_WIDTH;
          _newobj.height = item.height || HOLDER_HEIGHT;
          _newobj.x = px;
          _newobj.y = py + (HOLDER_HEIGHT + PLANE_HEIGHT) * layers + PLANE_HEIGHT + 10 + _newobj.height / 2;
          _newobj.z = pz - (PLANE_WIDTH / 2) * (COLUMN_NUM - 1) + PLANE_WIDTH * index
          tempobj.add(_this.createCube(_this, item))
        }
      })
    }
    tempobj.position.set(px, py, pz);
    if (tempobj.children != null && typeof (tempobj.children) != 'undefined' && tempobj.children.length > 0) {
      tempobj.children.forEach((item, index) => {
        item.position.x -= px;
        item.position.y -= py;
        item.position.z -= pz;
      });
    }
    if (_obj.rotation != null && typeof (_obj.rotation) != 'undefined' && _obj.rotation.length > 0) {
      _obj.rotation.forEach(function (v, i) {
        switch (v.direction) {
          case 'x':
            tempobj.rotateX(v.degree);
            break;
          case 'y':
            tempobj.rotateY(v.degree);
            break;
          case 'z':
            tempobj.rotateZ(v.degree);
            break;
          case 'arb':
            tempobj.rotateOnAxis(new THREE.Vector3(v.degree[0], v.degree[1], v.degree[2]), v.degree[3]);
            break;
        }
      })
    }
    tempobj.name = _obj.name;
    _this.dragObjects.push(tempobj);
    return tempobj
  }
  //通用方法===========================================================================================
  //判断对象
  hasObj(_obj) {
    if (_obj != null && typeof (_obj) != 'undefined') {
      return true;
    } else {
      return false;
    }
  }
  //查找对象
  findObject(_objname) {
    var _this = this;
    var findedobj = null;
    try {
      _this.objects.forEach(function (v, i) {
        if (v.name != null && v.name != '') {
          if (v.name == _objname) {
            findedobj = v;
            throw new Error('')
          }
        }
      })
    } catch (e) {}
    return findedobj;
  }
  //复制对象
  cloneObj(_objname, newparam) {
    /*newparam
    {
      show: true,
      uuid:
      copyfrom: 'cabinet1_1',
      name:
      childrenname:[]
      objType: 'cloneObj',
      position:{x:y:z:}//相对复制品的
      scale:{x:1,y:1,z:1}
      rotation: [{ direction: 'y', degree: 0.25*Math.PI}],//旋转     uuid:'',
    }
    */
    var _this = this;
    var fobj = _this.findObject(_objname);
    var newobj = newobj = fobj.clone();
    if (newobj.children != null && newobj.children.length > 1) {
      newobj.children.forEach(function (v, i) {
        v.name = newparam.childrenname[i];
        _this.objects.push(v);
      })
    }
    //位置
    if (_this.hasObj(newparam.position)) {
      newobj.position.x = newparam.position.x;
      newobj.position.y = newparam.position.y;
      newobj.position.z = newparam.position.z;
    }
    //大小
    if (_this.hasObj(newparam.scale)) {
      newobj.scale.x = newparam.scale.x;
      newobj.scale.y = newparam.scale.y;
      newobj.scale.z = newparam.scale.z;
    }
    //角度
    if (_this.hasObj(newparam.rotation)) {
      newparam.rotation.forEach(function (v, i) {
        switch (v.direction) {
          case 'x':
            newobj.rotateX(v.degree);
            break;
          case 'y':
            newobj.rotateY(v.degree);
            break;
          case 'z':
            newobj.rotateZ(v.degree);
            break;
          case 'arb':
            newobj.rotateOnAxis(new THREE.Vector3(v.degree[0], v.degree[1], v.degree[2]), v.degree[3]);
            break;
        }
      })
    }
    newobj.name = newparam.name;
    newobj.uuid = newparam.uuid;
    _this.dragObjects.push(newobj);
    return newobj;
  }
  //设置表皮颜色
  setSkinColor(_objname, _color) {
    var _this = this;
    var _obj = _this.findObject(_objname);
    if (_this.hasObj(_obj.material.emissive)) {
      _obj.material.emissive.setHex(_color);
    } else if (_this.hasObj(_obj.material.materials)) {
      if (_obj.material.materials.length > 0) {
        _obj.material.materials.forEach(function (v, i) {
          v.emissive.setHex(_color);
        })
      }
    }
  }
  //添加图片标识
  addIdentification(_objname, _obj) {
    var _this = this;
    var _fobj = _this.findObject(_objname);
    var loader = new THREE.TextureLoader();
    var texture = loader.load(_obj.imgurl, function () {}, undefined, function () {});
    var spriteMaterial = new THREE.SpriteMaterial({
      map: texture,
      useScreenCoordinates: false
    });
    var sprite = new THREE.Sprite(spriteMaterial);
    sprite.name = _obj.name;
    sprite.position.x = _fobj.position.x + cabPx;
    sprite.position.y = _fobj.position.y + cabPy;
    sprite.position.z = _fobj.position.z + cabPz;
    if (_this.hasObj(_obj.size)) {
      sprite.scale.set(_obj.size.x, _obj.size.y);
    } else {
      sprite.scale.set(1, 1);
    }
    _this.addObject(sprite);
  }
  //添加文字
  makeTextSprite(_objname, parameters) {
    var _this = this;
    var _fobj = _this.findObject(_objname);
    if (parameters === undefined) parameters = {};
    var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial";
    var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18;
    var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4;
    var textColor = parameters.hasOwnProperty("textColor") ? parameters["textColor"] : {
      r: 0,
      g: 0,
      b: 0,
      a: 1.0
    };
    var message = parameters.hasOwnProperty("message") ? parameters["message"] : "helloMsj3D";
    var x = parameters.hasOwnProperty("position") ? parameters["position"].x : 0;
    var y = parameters.hasOwnProperty("position") ? parameters["position"].y : 0;
    var z = parameters.hasOwnProperty("position") ? parameters["position"].z : 0;
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    context.font = "Bold " + fontsize + "px " + fontface;
    var metrics = context.measureText(message);
    var textWidth = metrics.width;
    context.lineWidth = borderThickness;
    context.fillStyle = "rgba(" + textColor.r + ", " + textColor.g + ", " + textColor.b + ", 1.0)";
    context.fillText(message, borderThickness, fontsize + borderThickness);
    var texture = new THREE.Texture(canvas)
    texture.needsUpdate = true;
    var spriteMaterial = new THREE.SpriteMaterial({
      map: texture,
      useScreenCoordinates: false
    });
    var sprite = new THREE.Sprite(spriteMaterial);
    sprite.position.x = _fobj.position.x + x;
    sprite.position.y = _fobj.position.y + y;
    sprite.position.z = _fobj.position.z + z;
    sprite.name = parameters.name;
    sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize);
    _this.addObject(sprite);
  }
  /*
   *事件部分
   */
  //窗口大小变化
  onWindowResize() {
    var _this = this;
    _this.element = document.getElementById(_this.fId);
    _this.width = _this.element.clientWidth;
    _this.height = _this.element.clientHeight;
    _this.camera.aspect = _this.width / _this.height;
    _this.camera.updateProjectionMatrix();
    _this.renderer.setSize(_this.width, _this.height);
    _this.timeRender();
  }
  //鼠标按下事件
  onDocumentMouseDown(event) {
    dbclick++;
    var _this = this;
    setTimeout(function () {
      dbclick = 0
    }, 300);
    event.preventDefault();
    if (dbclick >= 2) {
      let getBoundingClientRect = this.element.getBoundingClientRect()
      //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
      // _this.mouseClick.x = (event.clientX / _this.width) * 2 - 1;
      // _this.mouseClick.y = -(event.clientY / _this.height) * 2 + 1;
      _this.mouseClick.x = ((event.clientX - getBoundingClientRect.left) / this.element.offsetWidth) * 2 - 1; // 标准设备横坐标
      _this.mouseClick.y = -((event.clientY - getBoundingClientRect.top) / this.element.offsetHeight) * 2 + 1; // 标准设备纵坐标
      // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
      _this.raycaster.setFromCamera(_this.mouseClick, _this.camera);
      // 获取raycaster直线和所有模型相交的数组集合
      var intersects = _this.raycaster.intersectObjects(_this.objects, true);
      if (intersects.length > 0) {
        //先通过当前点击位置的坐标和相机计算出raycaster线,然后计算出相交的所有模型,修改模型参数。
        _this.controls.enabled = false;
        _this.SELECTED = intersects[0].object;
        if (_this.eventList != null && _this.eventList.dbclick != null && _this.eventList.dbclick.length > 0) {
          _this.eventList.dbclick.forEach(function (v, i) {
            if ("string" == typeof (v.obj_name)) {
              if (v.obj_name == _this.SELECTED.name) {
                v.obj_event(_this.SELECTED, _this);
              }
            } else if (v.findObject != null || 'function' == typeof (v.findObject)) {
              if (v.findObject(_this.SELECTED.name)) {
                v.obj_event(_this.SELECTED, _this);
              }
            }
          })
        }
        _this.controls.enabled = true;
      }
    }
  }
  //鼠标抬起事件
  onDocumentMouseUp(event) {
    var _this = this;
    event.preventDefault();
    //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
    _this.mouseClick.x = (event.clientX / _this.width) * 2 - 1;
    _this.mouseClick.y = -(event.clientY / _this.height) * 2 + 1;
    // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
    _this.raycaster.setFromCamera(_this.mouseClick, _this.camera);
    // 获取raycaster直线和所有模型相交的数组集合
    var intersects = _this.raycaster.intersectObjects(_this.dragObjects, true);
    if (intersects.length > 0) {
      //先通过当前点击位置的坐标和相机计算出raycaster线,然后计算出相交的所有模型,修改模型参数。
      _this.controls.enabled = false;
      _this.SELECTED = intersects[0].object.parent;
      if (_this.eventList != null && _this.eventList.click != null) {
        _this.eventList.mouseUp.obj_event(_this.SELECTED, _this);
      }
      _this.controls.enabled = true;
    }
  }
}
src/assets/js/three/data.js
New file
@@ -0,0 +1,282 @@
/*
 * @Description: 3D机房初始化数据
 * @Autor: ZengYK
 * @Date: 2021-01-12 09:39:43
 */
const floorB = require('../../../../public/three/images/floor3.jpg');
const aircondition = require("../../../../public/three/images/aircondition.png");
const switchStationBehind = require("../../../../public/three/images/switchStation/behind.jpg");
const switchStationFore = require("../../../../public/three/images/switchStation/fore.jpg");
const switchStationLeft = require("../../../../public/three/images/switchStation/left.jpg");
const switchStationTop = require("../../../../public/three/images/switchStation/top.jpg");
const rectifierBehind = require("../../../../public/three/images/rectifier/behind.png");
const rectifierLeft = require("../../../../public/three/images/rectifier/left.png");
const rectifierRight = require("../../../../public/three/images/rectifier/right.png");
const rectifierTop = require("../../../../public/three/images/rectifier/top.png");
const distributionBehind = require("../../../../public/three/images/distribution/behind.jpg");
const distributionFore = require("../../../../public/three/images/distribution/fore.jpg");
const distributionLeft = require("../../../../public/three/images/distribution/left.jpg");
const distributionRight = require("../../../../public/three/images/distribution/right.jpg");
const distributionTop = require("../../../../public/three/images/distribution/top.jpg");
const channel = require("../../../../public/three/images/channel.jpg");
let Aobjects = {
  objects: [
    //地板
    {
      show: true,
      uuid: "",
      name: 'floor',
      objType: 'floor',
      length: 60000,
      width: 60000,
      height: 1,
      rotation: [{
        direction: 'x',
        degree: 0
      }], //旋转 表示x方向0度
      x: 0,
      y: 0,
      z: 0,
      style: {
        skin: {
          skinColor: 0x8ac9e2,
          skin_up: {
            skinColor: 0x98750f,
            imgurl: floorB,
            repeatx: true,
            repeaty: true,
            width: 1250,
            height: 1250
          },
          skin_down: {
            skinColor: 0x8ac9e2,
            imgurl: floorB,
            repeatx: true,
            repeaty: true,
            width: 1250,
            height: 1250
          },
          skin_fore: {
            skinColor: 0x8ac9e2,
          }
        }
      }
    },
    //管道
    {
      show: true,
      name: 'channel1',
      uuid: "",
      objType: 'channel',
      radius: 3,
      closed: true,
      path: [{
        x: 0,
        y: 40,
        z: 1200
      }, {
        x: 0,
        y: 40,
        z: 500
      }, {
        x: 1000,
        y: 40,
        z: 500
      }],
      imgurl: channel,
    },
    //开闭所
    {
      show: true,
      uuid: "",
      name: 'switchStation',
      objType: 'cube',
      length: 88,
      width: 339,
      height: 200,
      rotation: [{
        direction: 'y',
        degree: 0.5 * Math.PI
      }], //旋转 表示x方向0度
      x: 0,
      y: 100,
      z: 1200,
      style: {
        skinColor: 0xfefefe,
        skin: {
          skin_fore: {
            imgurl: switchStationFore,
            skinColor: 0xfefefe,
          },
          skin_behind: {
            imgurl: switchStationBehind,
            skinColor: 0xfefefe,
          },
          skin_down: {
            imgurl: switchStationTop,
            skinColor: 0xfefefe,
          },
          skin_up: {
            imgurl: switchStationTop,
            skinColor: 0xfefefe,
          },
          skin_left: {
            imgurl: switchStationLeft,
            skinColor: 0xfefefe,
          },
          skin_right: {
            imgurl: switchStationLeft,
            skinColor: 0xfefefe,
          },
        }
      }
    },
    //整流器
    {
      show: true,
      uuid: "",
      name: 'rectifier',
      objType: 'cube',
      length: 177,
      width: 84,
      height: 160,
      rotation: [{
        direction: 'y',
        degree: 0 * Math.PI
      }], //旋转 表示x方向0度
      x: 1000,
      y: 100,
      z: 500,
      style: {
        skinColor: 0xfefefe,
        skin: {
          skin_fore: {
            skinColor: 0xfefefe,
            imgurl: rectifierBehind,
          },
          skin_behind: {
            skinColor: 0xfefefe,
            imgurl: rectifierBehind,
          },
          skin_down: {
            skinColor: 0xfefefe,
          },
          skin_up: {
            skinColor: 0xfefefe,
            imgurl: rectifierTop,
          },
          skin_left: {
            skinColor: 0xfefefe,
            imgurl: rectifierLeft,
          },
          skin_right: {
            skinColor: 0xfefefe,
            imgurl: rectifierRight,
          },
        }
      }
    },
    //配电器
    {
      show: true,
      uuid: "",
      name: 'distribution',
      objType: 'cube',
      length: 90,
      width: 180,
      height: 160,
      rotation: [{
        direction: 'y',
        degree: 0.5 * Math.PI
      }], //旋转 表示x方向0度
      x: 1000,
      y: 100,
      z: 0,
      style: {
        skinColor: 0xfefefe,
        skin: {
          skin_fore: {
            skinColor: 0xfefefe,
            imgurl: distributionFore,
          },
          skin_behind: {
            skinColor: 0xfefefe,
            imgurl: distributionBehind,
          },
          skin_down: {
            skinColor: 0xfefefe,
          },
          skin_up: {
            skinColor: 0xfefefe,
            imgurl: distributionTop,
          },
          skin_left: {
            skinColor: 0xfefefe,
            imgurl: distributionLeft,
          },
          skin_right: {
            skinColor: 0xfefefe,
            imgurl: distributionRight,
          },
        }
      }
    },
    //配电器
    {
      show: true,
      uuid: "",
      name: 'distribution2',
      objType: 'cube',
      length: 90,
      width: 180,
      height: 160,
      rotation: [{
        direction: 'y',
        degree: 0.5 * Math.PI
      }], //旋转 表示x方向0度
      x: 1000,
      y: 100,
      z: -500,
      style: {
        skinColor: 0xfefefe,
        skin: {
          skin_fore: {
            skinColor: 0xfefefe,
            imgurl: distributionFore,
          },
          skin_behind: {
            skinColor: 0xfefefe,
            imgurl: distributionBehind,
          },
          skin_down: {
            skinColor: 0xfefefe,
          },
          skin_up: {
            skinColor: 0xfefefe,
            imgurl: distributionTop,
          },
          skin_left: {
            skinColor: 0xfefefe,
            imgurl: distributionLeft,
          },
          skin_right: {
            skinColor: 0xfefefe,
            imgurl: distributionRight,
          },
        }
      }
    },
  ],
  events: {
    click: {},
    dbclick: [],
    mouseDown: {},
    mouseUp: {},
    mouseMove: {}
  },
}
export {
  Aobjects,
}
src/assets/js/three/plugin/DragControls.js
New file
@@ -0,0 +1,275 @@
/**
 * @author zz85 / https://github.com/zz85
 * @author mrdoob / http://mrdoob.com
 * Running this will allow you to drag three.js objects around the screen.
 */
THREE.DragControls = function (_objects, _camera, _domElement) {
    var _plane = new THREE.Plane();
    var _raycaster = new THREE.Raycaster();
    var _mouse = new THREE.Vector2();
    var _offset = new THREE.Vector3();
    var _intersection = new THREE.Vector3();
    var _worldPosition = new THREE.Vector3();
    var _inverseMatrix = new THREE.Matrix4();
    var _selected = null,
        _hovered = null;
    //
    var scope = this;
    function activate() {
        _domElement.addEventListener('mousemove', onDocumentMouseMove, false);
        _domElement.addEventListener('mousedown', onDocumentMouseDown, false);
        _domElement.addEventListener('mouseup', onDocumentMouseCancel, false);
        _domElement.addEventListener('mouseleave', onDocumentMouseCancel, false);
        _domElement.addEventListener('touchmove', onDocumentTouchMove, false);
        _domElement.addEventListener('touchstart', onDocumentTouchStart, false);
        _domElement.addEventListener('touchend', onDocumentTouchEnd, false);
    }
    function deactivate() {
        _domElement.removeEventListener('mousemove', onDocumentMouseMove, false);
        _domElement.removeEventListener('mousedown', onDocumentMouseDown, false);
        _domElement.removeEventListener('mouseup', onDocumentMouseCancel, false);
        _domElement.removeEventListener('mouseleave', onDocumentMouseCancel, false);
        _domElement.removeEventListener('touchmove', onDocumentTouchMove, false);
        _domElement.removeEventListener('touchstart', onDocumentTouchStart, false);
        _domElement.removeEventListener('touchend', onDocumentTouchEnd, false);
    }
    function dispose() {
        deactivate();
    }
    function onDocumentMouseMove(event) {
        event.preventDefault();
        var rect = _domElement.getBoundingClientRect();
        _mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
        _mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
        _raycaster.setFromCamera(_mouse, _camera);
        if (_selected && scope.enabled) {
            if (_raycaster.ray.intersectPlane(_plane, _intersection)) {
                _selected.position.copy(_intersection.sub(_offset).applyMatrix4(_inverseMatrix));
            }
            scope.dispatchEvent({
                type: 'drag',
                object: _selected
            });
            return;
        }
        _raycaster.setFromCamera(_mouse, _camera);
        var intersects = _raycaster.intersectObjects(_objects, true);
        if (intersects.length > 0) {
            var object = intersects[0].object.parent;
            _plane.setFromNormalAndCoplanarPoint(_camera.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(object.matrixWorld));
            if (_hovered !== object) {
                scope.dispatchEvent({
                    type: 'hoveron',
                    object: object
                });
                _domElement.style.cursor = 'pointer';
                _hovered = object;
            }
        } else {
            if (_hovered !== null) {
                scope.dispatchEvent({
                    type: 'hoveroff',
                    object: _hovered
                });
                _domElement.style.cursor = 'auto';
                _hovered = null;
            }
        }
    }
    function onDocumentMouseDown(event) {
        event.preventDefault();
        _raycaster.setFromCamera(_mouse, _camera);
        var intersects = _raycaster.intersectObjects(_objects, true);
        if (intersects.length > 0) {
            _selected = intersects[0].object.parent;
            if (_raycaster.ray.intersectPlane(_plane, _intersection)) {
                _inverseMatrix.getInverse(_selected.parent.matrixWorld);
                _offset.copy(_intersection).sub(_worldPosition.setFromMatrixPosition(_selected.matrixWorld));
            }
            _domElement.style.cursor = 'move';
            scope.dispatchEvent({
                type: 'dragstart',
                object: _selected
            });
        }
    }
    function onDocumentMouseCancel(event) {
        event.preventDefault();
        if (_selected) {
            scope.dispatchEvent({
                type: 'dragend',
                object: _selected
            });
            _selected = null;
        }
        _domElement.style.cursor = _hovered ? 'pointer' : 'auto';
    }
    function onDocumentTouchMove(event) {
        event.preventDefault();
        event = event.changedTouches[0];
        var rect = _domElement.getBoundingClientRect();
        _mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
        _mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
        _raycaster.setFromCamera(_mouse, _camera);
        if (_selected && scope.enabled) {
            if (_raycaster.ray.intersectPlane(_plane, _intersection)) {
                _selected.position.copy(_intersection.sub(_offset).applyMatrix4(_inverseMatrix));
            }
            scope.dispatchEvent({
                type: 'drag',
                object: _selected
            });
            return;
        }
    }
    function onDocumentTouchStart(event) {
        event.preventDefault();
        event = event.changedTouches[0];
        var rect = _domElement.getBoundingClientRect();
        _mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
        _mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
        _raycaster.setFromCamera(_mouse, _camera);
        var intersects = _raycaster.intersectObjects(_objects, true);
        if (intersects.length > 0) {
            _selected = intersects[0].object.parent;
            _plane.setFromNormalAndCoplanarPoint(_camera.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(_selected.matrixWorld));
            if (_raycaster.ray.intersectPlane(_plane, _intersection)) {
                _inverseMatrix.getInverse(_selected.parent.matrixWorld);
                _offset.copy(_intersection).sub(_worldPosition.setFromMatrixPosition(_selected.matrixWorld));
            }
            _domElement.style.cursor = 'move';
            scope.dispatchEvent({
                type: 'dragstart',
                object: _selected
            });
        }
    }
    function onDocumentTouchEnd(event) {
        event.preventDefault();
        if (_selected) {
            scope.dispatchEvent({
                type: 'dragend',
                object: _selected
            });
            _selected = null;
        }
        _domElement.style.cursor = 'auto';
    }
    activate();
    // API
    this.enabled = true;
    this.activate = activate;
    this.deactivate = deactivate;
    this.dispose = dispose;
};
THREE.DragControls.prototype = Object.create(THREE.EventDispatcher.prototype);
THREE.DragControls.prototype.constructor = THREE.DragControls;
src/assets/js/three/plugin/ThreeBSP.js
New file
@@ -0,0 +1,717 @@
// Generated by CoffeeScript 1.12.7
import * as THREE from 'three';
function loadBSP() {
  (function () {
    var BACK, COPLANAR, EPSILON, FRONT, SPANNING, Timelimit, returning,
      bind = function (fn, me) {
        return function () {
          return fn.apply(me, arguments);
        };
      },
      slice = [].slice,
      extend = function (child, parent) {
        for (var key in parent) {
          if (hasProp.call(parent, key)) child[key] = parent[key];
        }
        function ctor() {
          this.constructor = child;
        }
        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
        child.__super__ = parent.prototype;
        return child;
      },
      hasProp = {}.hasOwnProperty;
    EPSILON = 1e-5;
    COPLANAR = 0;
    FRONT = 1;
    BACK = 2;
    SPANNING = 3;
    returning = function (value, fn) {
      fn();
      return value;
    };
    Timelimit = (function () {
      function Timelimit(timeout, progress) {
        this.timeout = timeout;
        this.progress = progress;
        this.doTask = bind(this.doTask, this);
        this.finish = bind(this.finish, this);
        this.start = bind(this.start, this);
        this.check = bind(this.check, this);
        "NOTHING";
      }
      Timelimit.prototype.check = function () {
        var elapsed;
        if (this.started == null) {
          return;
        }
        return returning((elapsed = Date.now() - this.started), (function (_this) {
          return function () {
            var ref, ref1, ref2;
            if ((ref = elapsed >= _this.timeout) != null ? ref : 2e308) {
              throw new Error("Timeout reached: " + elapsed + "/" + _this.timeout + ", " + ((ref1 = _this.tasks) != null ? ref1 : 0) + " tasks unfinished " + ((ref2 = _this.done) != null ? ref2 : 0) + " finished.");
            }
          };
        })(this));
      };
      Timelimit.prototype.start = function () {
        if (this.started == null) {
          this.started = Date.now();
        }
        if (this.tasks == null) {
          this.tasks = 0;
        }
        if (this.total == null) {
          this.total = 0;
        }
        this.total += 1;
        this.tasks += 1;
        return this.check();
      };
      Timelimit.prototype.finish = function () {
        var elapsed;
        if ((this.tasks != null) && this.tasks < 1) {
          throw new Error("Finished more tasks than started");
        }
        this.tasks -= 1;
        elapsed = this.check();
        if (this.done == null) {
          this.done = 0;
        }
        this.done += 1;
        if (this.progress != null) {
          this.progress(this.done, this.total);
        }
        if (this.tasks === 0) {
          "Finished " + this.done + " tasks in " + elapsed + "/" + this.timeout + " ms";
          return this.started = this.done = this.total = void 0;
        }
      };
      Timelimit.prototype.doTask = function (block) {
        var result;
        this.start();
        result = block();
        this.finish();
        return result;
      };
      return Timelimit;
    })();
    window.ThreeBSP = (function () {
      function ThreeBSP(treeIsh, matrix1, options) {
        var base, ref, ref1, ref2, ref3;
        this.matrix = matrix1;
        this.options = options != null ? options : {};
        this.intersect = bind(this.intersect, this);
        this.union = bind(this.union, this);
        this.subtract = bind(this.subtract, this);
        this.toGeometry = bind(this.toGeometry, this);
        this.toMesh = bind(this.toMesh, this);
        this.toTree = bind(this.toTree, this);
        this.withTimer = bind(this.withTimer, this);
        if ((this.matrix != null) && !(this.matrix instanceof THREE.Matrix4)) {
          this.options = this.matrix;
          this.matrix = void 0;
        }
        if (this.options == null) {
          this.options = {};
        }
        if (this.matrix == null) {
          this.matrix = new THREE.Matrix4();
        }
        if ((base = this.options).timer == null) {
          base.timer = new Timelimit((ref = (ref1 = this.options.timer) != null ? ref1.timeout : void 0) != null ? ref : this.options.timeout, (ref2 = (ref3 = this.options.timer) != null ? ref3.progress : void 0) != null ? ref2 : this.options.progress);
        }
        this.tree = this.toTree(treeIsh);
      }
      ThreeBSP.prototype.withTimer = function (new_timer, block) {
        var old_timer;
        old_timer = this.options.timer;
        try {
          this.options.timer = new_timer;
          return block();
        } finally {
          this.options.timer = old_timer;
        }
      };
      ThreeBSP.prototype.toTree = function (treeIsh) {
        var face, fn1, geometry, i, k, len, polygons, ref;
        if (treeIsh instanceof ThreeBSP.Node) {
          return treeIsh;
        }
        polygons = [];
        geometry = treeIsh instanceof THREE.Geometry ? treeIsh : treeIsh instanceof THREE.Mesh ? (treeIsh.updateMatrix(), this.matrix = treeIsh.matrix.clone(), treeIsh.geometry) : void 0;
        ref = geometry.faces;
        fn1 = (function (_this) {
          return function (face, i) {
            var faceVertexUvs, idx, l, len1, polygon, ref1, ref2, vIndex, vName, vertex;
            faceVertexUvs = (ref1 = geometry.faceVertexUvs) != null ? ref1[0][i] : void 0;
            if (faceVertexUvs == null) {
              faceVertexUvs = [new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()];
            }
            polygon = new ThreeBSP.Polygon();
            ref2 = ['a', 'b', 'c', 'd'];
            for (vIndex = l = 0, len1 = ref2.length; l < len1; vIndex = ++l) {
              vName = ref2[vIndex];
              if ((idx = face[vName]) != null) {
                vertex = geometry.vertices[idx];
                vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], new THREE.Vector2(faceVertexUvs[vIndex].x, faceVertexUvs[vIndex].y));
                vertex.applyMatrix4(_this.matrix);
                polygon.vertices.push(vertex);
              }
            }
            return polygons.push(polygon.calculateProperties());
          };
        })(this);
        for (i = k = 0, len = ref.length; k < len; i = ++k) {
          face = ref[i];
          fn1(face, i);
        }
        return new ThreeBSP.Node(polygons, this.options);
      };
      ThreeBSP.prototype.toMesh = function (material) {
        if (material == null) {
          material = new THREE.MeshNormalMaterial();
        }
        return this.options.timer.doTask((function (_this) {
          return function () {
            var geometry, mesh;
            geometry = _this.toGeometry();
            return returning((mesh = new THREE.Mesh(geometry, material)), function () {
              mesh.position.setFromMatrixPosition(_this.matrix);
              return mesh.rotation.setFromRotationMatrix(_this.matrix);
            });
          };
        })(this));
      };
      ThreeBSP.prototype.toGeometry = function () {
        return this.options.timer.doTask((function (_this) {
          return function () {
            var geometry, matrix;
            matrix = new THREE.Matrix4().getInverse(_this.matrix);
            return returning((geometry = new THREE.Geometry()), function () {
              var k, len, polygon, ref, results;
              ref = _this.tree.allPolygons();
              results = [];
              for (k = 0, len = ref.length; k < len; k++) {
                polygon = ref[k];
                results.push(_this.options.timer.doTask(function () {
                  var face, idx, l, polyVerts, ref1, results1, v, vertUvs, verts;
                  polyVerts = (function () {
                    var l, len1, ref1, results1;
                    ref1 = polygon.vertices;
                    results1 = [];
                    for (l = 0, len1 = ref1.length; l < len1; l++) {
                      v = ref1[l];
                      results1.push(v.clone().applyMatrix4(matrix));
                    }
                    return results1;
                  })();
                  results1 = [];
                  for (idx = l = 2, ref1 = polyVerts.length; 2 <= ref1 ? l < ref1 : l > ref1; idx = 2 <= ref1 ? ++l : --l) {
                    verts = [polyVerts[0], polyVerts[idx - 1], polyVerts[idx]];
                    vertUvs = (function () {
                      var len1, m, ref2, ref3, results2;
                      results2 = [];
                      for (m = 0, len1 = verts.length; m < len1; m++) {
                        v = verts[m];
                        results2.push(new THREE.Vector2((ref2 = v.uv) != null ? ref2.x : void 0, (ref3 = v.uv) != null ? ref3.y : void 0));
                      }
                      return results2;
                    })();
                    face = (function (func, args, ctor) {
                      ctor.prototype = func.prototype;
                      var child = new ctor,
                        result = func.apply(child, args);
                      return Object(result) === result ? result : child;
                    })(THREE.Face3, slice.call((function () {
                      var len1, m, results2;
                      results2 = [];
                      for (m = 0, len1 = verts.length; m < len1; m++) {
                        v = verts[m];
                        results2.push(geometry.vertices.push(v) - 1);
                      }
                      return results2;
                    })()).concat([polygon.normal.clone()]), function () {});
                    geometry.faces.push(face);
                    results1.push(geometry.faceVertexUvs[0].push(vertUvs));
                  }
                  return results1;
                }));
              }
              return results;
            });
          };
        })(this));
      };
      ThreeBSP.prototype.subtract = function (other) {
        return this.options.timer.doTask((function (_this) {
          return function () {
            return other.withTimer(_this.options.timer, function () {
              var ref, them, us;
              ref = [_this.tree.clone(), other.tree.clone()], us = ref[0], them = ref[1];
              us.invert().clipTo(them);
              them.clipTo(us).invert().clipTo(us).invert();
              return new ThreeBSP(us.build(them.allPolygons()).invert(), _this.matrix, _this.options);
            });
          };
        })(this));
      };
      ThreeBSP.prototype.union = function (other) {
        return this.options.timer.doTask((function (_this) {
          return function () {
            return other.withTimer(_this.options.timer, function () {
              var ref, them, us;
              ref = [_this.tree.clone(), other.tree.clone()], us = ref[0], them = ref[1];
              us.clipTo(them);
              them.clipTo(us).invert().clipTo(us).invert();
              return new ThreeBSP(us.build(them.allPolygons()), _this.matrix, _this.options);
            });
          };
        })(this));
      };
      ThreeBSP.prototype.intersect = function (other) {
        return this.options.timer.doTask((function (_this) {
          return function () {
            return other.withTimer(_this.options.timer, function () {
              var ref, them, us;
              ref = [_this.tree.clone(), other.tree.clone()], us = ref[0], them = ref[1];
              them.clipTo(us.invert()).invert().clipTo(us.clipTo(them));
              return new ThreeBSP(us.build(them.allPolygons()).invert(), _this.matrix, _this.options);
            });
          };
        })(this));
      };
      return ThreeBSP;
    })();
    ThreeBSP.Vertex = (function (superClass) {
      extend(Vertex, superClass);
      function Vertex(x, y, z, normal, uv) {
        this.normal = normal != null ? normal : new THREE.Vector3();
        this.uv = uv != null ? uv : new THREE.Vector2();
        this.interpolate = bind(this.interpolate, this);
        this.lerp = bind(this.lerp, this);
        Vertex.__super__.constructor.call(this, x, y, z);
      }
      Vertex.prototype.clone = function () {
        return new ThreeBSP.Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone());
      };
      Vertex.prototype.lerp = function (v, alpha) {
        return returning(Vertex.__super__.lerp.apply(this, arguments), (function (_this) {
          return function () {
            _this.uv.add(v.uv.clone().sub(_this.uv).multiplyScalar(alpha));
            return _this.normal.lerp(v, alpha);
          };
        })(this));
      };
      Vertex.prototype.interpolate = function () {
        var args, ref;
        args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
        return (ref = this.clone()).lerp.apply(ref, args);
      };
      return Vertex;
    })(THREE.Vector3);
    ThreeBSP.Polygon = (function () {
      function Polygon(vertices, normal, w) {
        this.vertices = vertices != null ? vertices : [];
        this.normal = normal;
        this.w = w;
        this.subdivide = bind(this.subdivide, this);
        this.tessellate = bind(this.tessellate, this);
        this.classifySide = bind(this.classifySide, this);
        this.classifyVertex = bind(this.classifyVertex, this);
        this.invert = bind(this.invert, this);
        this.clone = bind(this.clone, this);
        this.calculateProperties = bind(this.calculateProperties, this);
        if (this.vertices.length) {
          this.calculateProperties();
        }
      }
      Polygon.prototype.calculateProperties = function () {
        return returning(this, (function (_this) {
          return function () {
            var a, b, c, ref;
            ref = _this.vertices, a = ref[0], b = ref[1], c = ref[2];
            _this.normal = b.clone().sub(a).cross(c.clone().sub(a)).normalize();
            return _this.w = _this.normal.clone().dot(a);
          };
        })(this));
      };
      Polygon.prototype.clone = function () {
        var v;
        return new ThreeBSP.Polygon((function () {
          var k, len, ref, results;
          ref = this.vertices;
          results = [];
          for (k = 0, len = ref.length; k < len; k++) {
            v = ref[k];
            results.push(v.clone());
          }
          return results;
        }).call(this), this.normal.clone(), this.w);
      };
      Polygon.prototype.invert = function () {
        return returning(this, (function (_this) {
          return function () {
            _this.normal.multiplyScalar(-1);
            _this.w *= -1;
            return _this.vertices.reverse();
          };
        })(this));
      };
      Polygon.prototype.classifyVertex = function (vertex) {
        var side;
        side = this.normal.dot(vertex) - this.w;
        switch (false) {
          case !(side < -EPSILON):
            return BACK;
          case !(side > EPSILON):
            return FRONT;
          default:
            return COPLANAR;
        }
      };
      Polygon.prototype.classifySide = function (polygon) {
        var back, front, k, len, ref, ref1, tally, v;
        ref = [0, 0], front = ref[0], back = ref[1];
        tally = (function (_this) {
          return function (v) {
            switch (_this.classifyVertex(v)) {
              case FRONT:
                return front += 1;
              case BACK:
                return back += 1;
            }
          };
        })(this);
        ref1 = polygon.vertices;
        for (k = 0, len = ref1.length; k < len; k++) {
          v = ref1[k];
          tally(v);
        }
        if (front > 0 && back === 0) {
          return FRONT;
        }
        if (front === 0 && back > 0) {
          return BACK;
        }
        if ((front === back && back === 0)) {
          return COPLANAR;
        }
        return SPANNING;
      };
      Polygon.prototype.tessellate = function (poly) {
        var b, count, f, i, j, k, len, polys, ref, ref1, ref2, t, ti, tj, v, vi, vj;
        ref = {
          f: [],
          b: [],
          count: poly.vertices.length
        }, f = ref.f, b = ref.b, count = ref.count;
        if (this.classifySide(poly) !== SPANNING) {
          return [poly];
        }
        ref1 = poly.vertices;
        for (i = k = 0, len = ref1.length; k < len; i = ++k) {
          vi = ref1[i];
          vj = poly.vertices[(j = (i + 1) % count)];
          ref2 = (function () {
            var l, len1, ref2, results;
            ref2 = [vi, vj];
            results = [];
            for (l = 0, len1 = ref2.length; l < len1; l++) {
              v = ref2[l];
              results.push(this.classifyVertex(v));
            }
            return results;
          }).call(this), ti = ref2[0], tj = ref2[1];
          if (ti !== BACK) {
            f.push(vi);
          }
          if (ti !== FRONT) {
            b.push(vi);
          }
          if ((ti | tj) === SPANNING) {
            t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().sub(vi));
            v = vi.interpolate(vj, t);
            f.push(v);
            b.push(v);
          }
        }
        return returning((polys = []), (function (_this) {
          return function () {
            if (f.length >= 3) {
              polys.push(new ThreeBSP.Polygon(f));
            }
            if (b.length >= 3) {
              return polys.push(new ThreeBSP.Polygon(b));
            }
          };
        })(this));
      };
      Polygon.prototype.subdivide = function (polygon, coplanar_front, coplanar_back, front, back) {
        var k, len, poly, ref, results, side;
        ref = this.tessellate(polygon);
        results = [];
        for (k = 0, len = ref.length; k < len; k++) {
          poly = ref[k];
          side = this.classifySide(poly);
          switch (side) {
            case FRONT:
              results.push(front.push(poly));
              break;
            case BACK:
              results.push(back.push(poly));
              break;
            case COPLANAR:
              if (this.normal.dot(poly.normal) > 0) {
                results.push(coplanar_front.push(poly));
              } else {
                results.push(coplanar_back.push(poly));
              }
              break;
            default:
              throw new Error("BUG: Polygon of classification " + side + " in subdivision");
          }
        }
        return results;
      };
      return Polygon;
    })();
    ThreeBSP.Node = (function () {
      Node.prototype.clone = function () {
        var node;
        return returning((node = new ThreeBSP.Node(this.options)), (function (_this) {
          return function () {
            var ref;
            node.divider = (ref = _this.divider) != null ? ref.clone() : void 0;
            node.polygons = _this.options.timer.doTask(function () {
              var k, len, p, ref1, results;
              ref1 = _this.polygons;
              results = [];
              for (k = 0, len = ref1.length; k < len; k++) {
                p = ref1[k];
                results.push(p.clone());
              }
              return results;
            });
            node.front = _this.options.timer.doTask(function () {
              var ref1;
              return (ref1 = _this.front) != null ? ref1.clone() : void 0;
            });
            return node.back = _this.options.timer.doTask(function () {
              var ref1;
              return (ref1 = _this.back) != null ? ref1.clone() : void 0;
            });
          };
        })(this));
      };
      function Node(polygons, options) {
        this.options = options != null ? options : {};
        this.clipTo = bind(this.clipTo, this);
        this.clipPolygons = bind(this.clipPolygons, this);
        this.invert = bind(this.invert, this);
        this.allPolygons = bind(this.allPolygons, this);
        this.isConvex = bind(this.isConvex, this);
        this.build = bind(this.build, this);
        this.clone = bind(this.clone, this);
        if ((polygons != null) && !(polygons instanceof Array)) {
          this.options = polygons;
          polygons = void 0;
        }
        this.polygons = [];
        this.options.timer.doTask((function (_this) {
          return function () {
            if ((polygons != null) && polygons.length) {
              return _this.build(polygons);
            }
          };
        })(this));
      }
      Node.prototype.build = function (polygons) {
        return returning(this, (function (_this) {
          return function () {
            var polys, results, side, sides;
            sides = {
              front: [],
              back: []
            };
            if (_this.divider == null) {
              _this.divider = polygons[0].clone();
            }
            _this.options.timer.doTask(function () {
              var k, len, poly, results;
              results = [];
              for (k = 0, len = polygons.length; k < len; k++) {
                poly = polygons[k];
                results.push(_this.options.timer.doTask(function () {
                  return _this.divider.subdivide(poly, _this.polygons, _this.polygons, sides.front, sides.back);
                }));
              }
              return results;
            });
            results = [];
            for (side in sides) {
              if (!hasProp.call(sides, side)) continue;
              polys = sides[side];
              if (polys.length) {
                if (_this[side] == null) {
                  _this[side] = new ThreeBSP.Node(_this.options);
                }
                results.push(_this[side].build(polys));
              } else {
                results.push(void 0);
              }
            }
            return results;
          };
        })(this));
      };
      Node.prototype.isConvex = function (polys) {
        var inner, k, l, len, len1, outer;
        for (k = 0, len = polys.length; k < len; k++) {
          inner = polys[k];
          for (l = 0, len1 = polys.length; l < len1; l++) {
            outer = polys[l];
            if (inner !== outer && outer.classifySide(inner) !== BACK) {
              return false;
            }
          }
        }
        return true;
      };
      Node.prototype.allPolygons = function () {
        return this.options.timer.doTask((function (_this) {
          return function () {
            var ref, ref1;
            return _this.polygons.slice().concat(((ref1 = _this.front) != null ? ref1.allPolygons() : void 0) || []).concat(((ref = _this.back) != null ? ref.allPolygons() : void 0) || []);
          };
        })(this));
      };
      Node.prototype.invert = function () {
        return returning(this, (function (_this) {
          return function () {
            return _this.options.timer.doTask(function () {
              var flipper, k, l, len, len1, poly, ref, ref1, ref2;
              ref = _this.polygons;
              for (k = 0, len = ref.length; k < len; k++) {
                poly = ref[k];
                _this.options.timer.doTask(function () {
                  return poly.invert();
                });
              }
              ref1 = [_this.divider, _this.front, _this.back];
              for (l = 0, len1 = ref1.length; l < len1; l++) {
                flipper = ref1[l];
                _this.options.timer.doTask(function () {
                  return flipper != null ? flipper.invert() : void 0;
                });
              }
              return ref2 = [_this.back, _this.front], _this.front = ref2[0], _this.back = ref2[1], ref2;
            });
          };
        })(this));
      };
      Node.prototype.clipPolygons = function (polygons) {
        return this.options.timer.doTask((function (_this) {
          return function () {
            var back, front, k, len, poly;
            if (!_this.divider) {
              return polygons.slice();
            }
            front = [];
            back = [];
            for (k = 0, len = polygons.length; k < len; k++) {
              poly = polygons[k];
              _this.options.timer.doTask(function () {
                return _this.divider.subdivide(poly, front, back, front, back);
              });
            }
            if (_this.front) {
              front = _this.front.clipPolygons(front);
            }
            if (_this.back) {
              back = _this.back.clipPolygons(back);
            }
            if (_this.back) {
              return front.concat(back);
            } else {
              return front;
            }
          };
        })(this));
      };
      Node.prototype.clipTo = function (node) {
        return returning(this, (function (_this) {
          return function () {
            return _this.options.timer.doTask(function () {
              var ref, ref1;
              _this.polygons = node.clipPolygons(_this.polygons);
              if ((ref = _this.front) != null) {
                ref.clipTo(node);
              }
              return (ref1 = _this.back) != null ? ref1.clipTo(node) : void 0;
            });
          };
        })(this));
      };
      return Node;
    })();
  }).call(this);
}
export {
  loadBSP
}
src/assets/js/three/plugin/Tween.js
New file
@@ -0,0 +1,895 @@
/**
 * Tween.js - Licensed under the MIT license
 * https://github.com/tweenjs/tween.js
 * ----------------------------------------------
 *
 * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
 * Thank you all, you're awesome!
 */
var TWEEN = TWEEN || (function () {
    var _tweens = [];
    return {
        getAll: function () {
            return _tweens;
        },
        removeAll: function () {
            _tweens = [];
        },
        add: function (tween) {
            _tweens.push(tween);
        },
        remove: function (tween) {
            var i = _tweens.indexOf(tween);
            if (i !== -1) {
                _tweens.splice(i, 1);
            }
        },
        update: function (time, preserve) {
            if (_tweens.length === 0) {
                return false;
            }
            var i = 0;
            time = time !== undefined ? time : TWEEN.now();
            while (i < _tweens.length) {
                if (_tweens[i].update(time) || preserve) {
                    i++;
                } else {
                    _tweens.splice(i, 1);
                }
            }
            return true;
        }
    };
})();
// Include a performance.now polyfill.
// In node.js, use process.hrtime.
if (typeof (window) === 'undefined' && typeof (process) !== 'undefined') {
    TWEEN.now = function () {
        var time = process.hrtime();
        // Convert [seconds, nanoseconds] to milliseconds.
        return time[0] * 1000 + time[1] / 1000000;
    };
}
// In a browser, use window.performance.now if it is available.
else if (typeof (window) !== 'undefined' &&
    window.performance !== undefined &&
    window.performance.now !== undefined) {
    // This must be bound, because directly assigning this function
    // leads to an invocation exception in Chrome.
    TWEEN.now = window.performance.now.bind(window.performance);
}
// Use Date.now if it is available.
else if (Date.now !== undefined) {
    TWEEN.now = Date.now;
}
// Otherwise, use 'new Date().getTime()'.
else {
    TWEEN.now = function () {
        return new Date().getTime();
    };
}
function assign(target, source) {
    var keys = Object.keys(source);
    var length = keys.length;
    for (var i = 0; i < length; i += 1) {
        target[keys[i]] = source[keys[i]];
    }
    return target;
}
TWEEN.Tween = function (object) {
    this._object = object;
    this._valuesStart = {};
    this._valuesEnd = {};
    this._valuesStartRepeat = {};
    this._duration = 1000;
    this._repeat = 0;
    this._repeatDelayTime = undefined;
    this._yoyo = false;
    this._isPlaying = false;
    this._reversed = false;
    this._delayTime = 0;
    this._startTime = null;
    this._easingFunction = TWEEN.Easing.Linear.None;
    this._interpolationFunction = TWEEN.Interpolation.Linear;
    this._chainedTweens = [];
    this._onStartCallback = null;
    this._onStartCallbackFired = false;
    this._onUpdateCallback = null;
    this._onCompleteCallback = null;
    this._onStopCallback = null;
};
TWEEN.Tween.prototype = assign(Object.create(Object.prototype), {
    to: function to(properties, duration) {
        this._valuesEnd = properties;
        if (duration !== undefined) {
            this._duration = duration;
        }
        return this;
    },
    start: function start(time) {
        TWEEN.add(this);
        this._isPlaying = true;
        this._onStartCallbackFired = false;
        this._startTime = time !== undefined ? time : TWEEN.now();
        this._startTime += this._delayTime;
        for (var property in this._valuesEnd) {
            // Check if an Array was provided as property value
            if (this._valuesEnd[property] instanceof Array) {
                if (this._valuesEnd[property].length === 0) {
                    continue;
                }
                // Create a local copy of the Array with the start value at the front
                this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]);
            }
            // If `to()` specifies a property that doesn't exist in the source object,
            // we should not set that property in the object
            if (this._object[property] === undefined) {
                continue;
            }
            // Save the starting value.
            this._valuesStart[property] = this._object[property];
            if ((this._valuesStart[property] instanceof Array) === false) {
                this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
            }
            this._valuesStartRepeat[property] = this._valuesStart[property] || 0;
        }
        return this;
    },
    stop: function stop() {
        if (!this._isPlaying) {
            return this;
        }
        TWEEN.remove(this);
        this._isPlaying = false;
        if (this._onStopCallback !== null) {
            this._onStopCallback.call(this._object, this._object);
        }
        this.stopChainedTweens();
        return this;
    },
    end: function end() {
        this.update(this._startTime + this._duration);
        return this;
    },
    stopChainedTweens: function stopChainedTweens() {
        for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
            this._chainedTweens[i].stop();
        }
    },
    delay: function delay(amount) {
        this._delayTime = amount;
        return this;
    },
    repeat: function repeat(times) {
        this._repeat = times;
        return this;
    },
    repeatDelay: function repeatDelay(amount) {
        this._repeatDelayTime = amount;
        return this;
    },
    yoyo: function yoyo(yoyo) {
        this._yoyo = yoyo;
        return this;
    },
    easing: function easing(easing) {
        this._easingFunction = easing;
        return this;
    },
    interpolation: function interpolation(interpolation) {
        this._interpolationFunction = interpolation;
        return this;
    },
    chain: function chain() {
        this._chainedTweens = arguments;
        return this;
    },
    onStart: function onStart(callback) {
        this._onStartCallback = callback;
        return this;
    },
    onUpdate: function onUpdate(callback) {
        this._onUpdateCallback = callback;
        return this;
    },
    onComplete: function onComplete(callback) {
        this._onCompleteCallback = callback;
        return this;
    },
    onStop: function onStop(callback) {
        this._onStopCallback = callback;
        return this;
    },
    update: function update(time) {
        var property;
        var elapsed;
        var value;
        if (time < this._startTime) {
            return true;
        }
        if (this._onStartCallbackFired === false) {
            if (this._onStartCallback !== null) {
                this._onStartCallback.call(this._object, this._object);
            }
            this._onStartCallbackFired = true;
        }
        elapsed = (time - this._startTime) / this._duration;
        elapsed = elapsed > 1 ? 1 : elapsed;
        value = this._easingFunction(elapsed);
        for (property in this._valuesEnd) {
            // Don't update properties that do not exist in the source object
            if (this._valuesStart[property] === undefined) {
                continue;
            }
            var start = this._valuesStart[property] || 0;
            var end = this._valuesEnd[property];
            if (end instanceof Array) {
                this._object[property] = this._interpolationFunction(end, value);
            } else {
                // Parses relative end values with start as base (e.g.: +10, -3)
                if (typeof (end) === 'string') {
                    if (end.charAt(0) === '+' || end.charAt(0) === '-') {
                        end = start + parseFloat(end);
                    } else {
                        end = parseFloat(end);
                    }
                }
                // Protect against non numeric properties.
                if (typeof (end) === 'number') {
                    this._object[property] = start + (end - start) * value;
                }
            }
        }
        if (this._onUpdateCallback !== null) {
            this._onUpdateCallback.call(this._object, value);
        }
        if (elapsed === 1) {
            if (this._repeat > 0) {
                if (isFinite(this._repeat)) {
                    this._repeat--;
                }
                // Reassign starting values, restart by making startTime = now
                for (property in this._valuesStartRepeat) {
                    if (typeof (this._valuesEnd[property]) === 'string') {
                        this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]);
                    }
                    if (this._yoyo) {
                        var tmp = this._valuesStartRepeat[property];
                        this._valuesStartRepeat[property] = this._valuesEnd[property];
                        this._valuesEnd[property] = tmp;
                    }
                    this._valuesStart[property] = this._valuesStartRepeat[property];
                }
                if (this._yoyo) {
                    this._reversed = !this._reversed;
                }
                if (this._repeatDelayTime !== undefined) {
                    this._startTime = time + this._repeatDelayTime;
                } else {
                    this._startTime = time + this._delayTime;
                }
                return true;
            } else {
                if (this._onCompleteCallback !== null) {
                    this._onCompleteCallback.call(this._object, this._object);
                }
                for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
                    // Make the chained tweens start exactly at the time they should,
                    // even if the `update()` method was called way past the duration of the tween
                    this._chainedTweens[i].start(this._startTime + this._duration);
                }
                return false;
            }
        }
        return true;
    }
});
TWEEN.Easing = {
    Linear: {
        None: function (k) {
            return k;
        }
    },
    Quadratic: {
        In: function (k) {
            return k * k;
        },
        Out: function (k) {
            return k * (2 - k);
        },
        InOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k;
            }
            return -0.5 * (--k * (k - 2) - 1);
        }
    },
    Cubic: {
        In: function (k) {
            return k * k * k;
        },
        Out: function (k) {
            return --k * k * k + 1;
        },
        InOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k + 2);
        }
    },
    Quartic: {
        In: function (k) {
            return k * k * k * k;
        },
        Out: function (k) {
            return 1 - (--k * k * k * k);
        },
        InOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k;
            }
            return -0.5 * ((k -= 2) * k * k * k - 2);
        }
    },
    Quintic: {
        In: function (k) {
            return k * k * k * k * k;
        },
        Out: function (k) {
            return --k * k * k * k * k + 1;
        },
        InOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k * k * k + 2);
        }
    },
    Sinusoidal: {
        In: function (k) {
            return 1 - Math.cos(k * Math.PI / 2);
        },
        Out: function (k) {
            return Math.sin(k * Math.PI / 2);
        },
        InOut: function (k) {
            return 0.5 * (1 - Math.cos(Math.PI * k));
        }
    },
    Exponential: {
        In: function (k) {
            return k === 0 ? 0 : Math.pow(1024, k - 1);
        },
        Out: function (k) {
            return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
        },
        InOut: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if ((k *= 2) < 1) {
                return 0.5 * Math.pow(1024, k - 1);
            }
            return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
        }
    },
    Circular: {
        In: function (k) {
            return 1 - Math.sqrt(1 - k * k);
        },
        Out: function (k) {
            return Math.sqrt(1 - (--k * k));
        },
        InOut: function (k) {
            if ((k *= 2) < 1) {
                return -0.5 * (Math.sqrt(1 - k * k) - 1);
            }
            return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
        }
    },
    Elastic: {
        In: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
        },
        Out: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
        },
        InOut: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            k *= 2;
            if (k < 1) {
                return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
            }
            return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
        }
    },
    Back: {
        In: function (k) {
            var s = 1.70158;
            return k * k * ((s + 1) * k - s);
        },
        Out: function (k) {
            var s = 1.70158;
            return --k * k * ((s + 1) * k + s) + 1;
        },
        InOut: function (k) {
            var s = 1.70158 * 1.525;
            if ((k *= 2) < 1) {
                return 0.5 * (k * k * ((s + 1) * k - s));
            }
            return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
        }
    },
    Bounce: {
        In: function (k) {
            return 1 - TWEEN.Easing.Bounce.Out(1 - k);
        },
        Out: function (k) {
            if (k < (1 / 2.75)) {
                return 7.5625 * k * k;
            } else if (k < (2 / 2.75)) {
                return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
            } else if (k < (2.5 / 2.75)) {
                return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
            } else {
                return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
            }
        },
        InOut: function (k) {
            if (k < 0.5) {
                return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
            }
            return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
        }
    }
};
TWEEN.Interpolation = {
    Linear: function (v, k) {
        var m = v.length - 1;
        var f = m * k;
        var i = Math.floor(f);
        var fn = TWEEN.Interpolation.Utils.Linear;
        if (k < 0) {
            return fn(v[0], v[1], f);
        }
        if (k > 1) {
            return fn(v[m], v[m - 1], m - f);
        }
        return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
    },
    Bezier: function (v, k) {
        var b = 0;
        var n = v.length - 1;
        var pw = Math.pow;
        var bn = TWEEN.Interpolation.Utils.Bernstein;
        for (var i = 0; i <= n; i++) {
            b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
        }
        return b;
    },
    CatmullRom: function (v, k) {
        var m = v.length - 1;
        var f = m * k;
        var i = Math.floor(f);
        var fn = TWEEN.Interpolation.Utils.CatmullRom;
        if (v[0] === v[m]) {
            if (k < 0) {
                i = Math.floor(f = m * (1 + k));
            }
            return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
        } else {
            if (k < 0) {
                return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
            }
            if (k > 1) {
                return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
            }
            return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
        }
    },
    Utils: {
        Linear: function (p0, p1, t) {
            return (p1 - p0) * t + p0;
        },
        Bernstein: function (n, i) {
            var fc = TWEEN.Interpolation.Utils.Factorial;
            return fc(n) / fc(i) / fc(n - i);
        },
        Factorial: (function () {
            var a = [1];
            return function (n) {
                var s = 1;
                if (a[n]) {
                    return a[n];
                }
                for (var i = n; i > 1; i--) {
                    s *= i;
                }
                a[n] = s;
                return s;
            };
        })(),
        CatmullRom: function (p0, p1, p2, p3, t) {
            var v0 = (p2 - p0) * 0.5;
            var v1 = (p3 - p1) * 0.5;
            var t2 = t * t;
            var t3 = t * t2;
            return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
        }
    }
};
// UMD (Universal Module Definition)
(function (root) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define([], function () {
            return TWEEN;
        });
    } else if (typeof module !== 'undefined' && typeof exports === 'object') {
        // Node.js
        module.exports = TWEEN;
    } else if (root !== undefined) {
        // Global variable
        root.TWEEN = TWEEN;
    }
})(this);
src/components/PageMenu.vue
@@ -38,6 +38,12 @@
                            src: "topoGraph",
                        },
                        {
                            label: "3D机房",
                            icon: "el-icon-s-platform",
                            name: "room3D",
                            src: "room3D",
                        },
                        {
                            label: "UPS状态监控",
                            icon: "el-icon-s-platform",
                            name: "UPSStateMonitor",
src/main.js
@@ -3,6 +3,9 @@
import router from './router'
import store from './store'
import * as THREE from 'three'
window.THREE = THREE
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './assets/css/basic.css'
src/pages/room.vue
New file
@@ -0,0 +1,146 @@
<template>
    <div class="contentBox threeRoom">
        <div id="remap"></div>
    </div>
</template>
<script>
    import * as THREE from 'three'
    import TWEEN from "@/assets/js/three/plugin/Tween"
    import {
        InitThree
    } from "@/assets/js/three/InitThree";
    import {
        Aobjects,
    } from "@/assets/js/three/data";
    let threeBuild;
    export default {
        data() {
            return {
                initOption: {
                    cameraPosition: [0, 800, -1500], //初始化相机视角位置
                    showAxisHelper: true,
                },
            };
        },
        mounted() {
            this.$nextTick(() => {
                this.initThreeEvent();
                threeBuild = new InitThree();
                threeBuild.initmsj3D("remap", this.initOption, Aobjects);
                threeBuild.start();
            });
        },
        methods: {
            //初始化three机房相关点击事件
            initThreeEvent() {
                let _this = this;
                Aobjects.events.mouseUp = { //单机选中机柜或货架
                    obj_event: function (_obj) {}
                }
                Aobjects.events.dbclick = [{
                        findObject: function (_objname) { //查找机柜门的对象
                            if (_objname.indexOf("cabinet") >= 0 && _objname.indexOf("door") >= 0) {
                                return true;
                            } else {
                                return false;
                            }
                        },
                        obj_uuid: "",
                        obj_event: function (_obj) {
                            _this.opcabinetdoor(_obj);
                        }
                    },
                    {
                        findObject: function (_objname) { //查找符合服务器的对象
                            if (_objname.indexOf("cabinetServe") >= 0) {
                                return true;
                            } else {
                                return false;
                            }
                        },
                        obj_uuid: "",
                        obj_event: function (_obj) {
                            _this.ejectServe(_obj);
                        }
                    },
                    {
                        findObject: function (_objname) { //查找符合货架电池的对象
                            if (_objname.indexOf("shelvesBatter") >= 0) {
                                return true;
                            } else {
                                return false;
                            }
                        },
                        obj_uuid: "",
                        obj_event: function (_obj) {
                            _this.batterInfo(_obj);
                        }
                    }
                ]
            },
            //打开机柜门
            opcabinetdoor(_obj) {
                var doorstate = "close";
                var tempobj = null;
                if (_obj.doorState != null && typeof (_obj.doorState) != 'undefined') {
                    doorstate = _obj.doorState;
                    tempobj = _obj.parent;
                } else {
                    var _objparent = _obj.parent;
                    tempobj = new THREE.Object3D();
                    tempobj.position.set(_obj.position.x, _obj.position.y, _obj.position.z + _obj.geometry.parameters.depth / 2);
                    _obj.position.set(0, 0, -_obj.geometry.parameters.depth / 2);
                    tempobj.add(_obj);
                    _objparent.add(tempobj);
                }
                _obj.doorState = (doorstate == "close" ? "open" : "close");
                if (doorstate == "close") {
                    new TWEEN.Tween(tempobj.rotation).to({
                        y: 0.5 * Math.PI
                    }, 1500).easing(TWEEN.Easing.Elastic.Out).start();
                } else {
                    new TWEEN.Tween(tempobj.rotation).to({
                        y: 0 * 2 * Math.PI
                    }, 300).start();
                }
            },
            //弹出服务器
            ejectServe(_obj) {
                var cardstate = "in";
                if (_obj.cardstate != null && typeof (_obj.cardstate) != 'undefined') {
                    cardstate = _obj.cardstate;
                } else {
                    _obj.cardstate = "out";
                }
                _obj.cardstate = (cardstate == "in" ? "out" : "in");
                new TWEEN.Tween(_obj.position).to({
                    x: (cardstate == "in" ? _obj.position.x - 30 : _obj.position.x + 30),
                }, 500).easing(TWEEN.Easing.Elastic.Out).start();
            },
            //点击电池
            batterInfo(_obj) {
                alert("您双击了" + _obj.name + "电池!");
            }
        },
        destroyed() {
            threeBuild.stop();
        },
    };
</script>
<style scoped>
    .threeRoom {
        width: 100%;
        height: 100%;
        position: relative;
        padding: 20px;
    }
    #remap {
        width: 100%;
        height: 100%;
        overflow: hidden;
        transition: 0.3s;
    }
</style>
src/router/routes.js
@@ -17,6 +17,11 @@
        name: 'topoGraph',
        meta: {},
        component: (resolve) => require(['@/pages/home/topoGraph.vue'], resolve),
    }, { //3D机房
        path: 'room3D',
        name: 'room3D',
        meta: {},
        component: (resolve) => require(['@/pages/room.vue'], resolve),
    }, { //UPS状态监控
        path: 'UPSStateMonitor',
        name: 'UPSStateMonitor',