igs-view 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -2918,7 +2918,7 @@ TransformControlsPlane.prototype.isTransformControlsPlane = true;
2918
2918
  /*! exports provided: name, version, main, types, scripts, dependencies, devDependencies, author, license, description, default */
2919
2919
  /***/ (function(module) {
2920
2920
 
2921
- module.exports = JSON.parse("{\"name\":\"igs-view\",\"version\":\"1.0.7\",\"main\":\"./dist/main.js\",\"types\":\"./types/Main.d.ts\",\"scripts\":{\"dev\":\"webpack-dev-server --watch --open --config webpack.dev.js --host 127.0.0.1\",\"build\":\"webpack --config webpack.prod.js && npm run declare\",\"declare\":\"tsc -d --declarationDir types --emitDeclarationOnly\"},\"dependencies\":{\"@types/three\":\"^0.139.0\",\"three\":\"^0.139.2\"},\"devDependencies\":{\"@types/glob\":\"^9.0.0\",\"@types/node\":\"20.8.0\",\"ts-loader\":\"^4.0.0\",\"typescript\":\"^4.5.1\",\"webpack\":\"^4.1.0\",\"webpack-cli\":\"^3.1.1\",\"webpack-dev-server\":\"^3.1.0\",\"webpack-merge\":\"^4.2.2\",\"worker-loader\":\"^3.0.8\"},\"author\":\"\",\"license\":\"ISC\",\"description\":\"\"}");
2921
+ module.exports = JSON.parse("{\"name\":\"igs-view\",\"version\":\"1.0.9\",\"main\":\"./dist/main.js\",\"types\":\"./types/Main.d.ts\",\"scripts\":{\"dev\":\"webpack-dev-server --watch --open --config webpack.dev.js --host 127.0.0.1\",\"build\":\"webpack --config webpack.prod.js && npm run declare\",\"declare\":\"tsc -d --declarationDir types --emitDeclarationOnly\"},\"dependencies\":{\"@types/three\":\"^0.139.0\",\"three\":\"^0.139.2\"},\"devDependencies\":{\"@types/glob\":\"^9.0.0\",\"@types/node\":\"20.8.0\",\"ts-loader\":\"^4.0.0\",\"typescript\":\"^4.5.1\",\"webpack\":\"^4.1.0\",\"webpack-cli\":\"^3.1.1\",\"webpack-dev-server\":\"^3.1.0\",\"webpack-merge\":\"^4.2.2\",\"worker-loader\":\"^3.0.8\"},\"author\":\"\",\"license\":\"ISC\",\"description\":\"\"}");
2922
2922
 
2923
2923
  /***/ }),
2924
2924
 
@@ -3146,51 +3146,114 @@ class Main extends three__WEBPACK_IMPORTED_MODULE_0__["EventDispatcher"] {
3146
3146
  verticalView() {
3147
3147
  if (!this.igsGroup.children.length)
3148
3148
  return null;
3149
- if (this.igsGroup.rotation.x == 0 && this.igsGroup.rotation.y == 0) {
3150
- let canvas = document.createElement("canvas");
3151
- let originX = (this.pading - this.box.min.x) * this.scale;
3152
- let originY = (this.pading - this.box.min.y) * this.scale;
3153
- let vec = this.box.getSize(new three__WEBPACK_IMPORTED_MODULE_0__["Vector3"]);
3154
- canvas.width = (vec.x + this.pading * 2) * this.scale;
3155
- canvas.height = (vec.y + this.pading * 2) * this.scale;
3156
- let ctx = canvas.getContext("2d");
3157
- ctx.fillStyle = "#ffffff";
3158
- ctx.fillRect(0, 0, canvas.width, canvas.height);
3159
- ctx.setTransform(this.scale, 0, 0, this.scale, originX, originY);
3160
- this.map.sort((a, b) => a.height - b.height);
3161
- let max = this.map[this.map.length - 1].height;
3162
- // console.log(this.map)
3163
- this.map.forEach(({ height, points }, index) => {
3164
- let grey = (max - height) / max * 200;
3165
- ctx.fillStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;
3166
- ctx.strokeStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;
3167
- ctx.lineWidth = 1 / this.scale;
3168
- ctx.lineCap = "round";
3169
- ctx.lineJoin = "round";
3170
- ctx.beginPath();
3171
- for (let i = 0; i < points.length; i += 2) {
3172
- if (i == 0) {
3173
- ctx.moveTo(points[i], points[i + 1]);
3174
- }
3175
- else {
3176
- ctx.lineTo(points[i], points[i + 1]);
3177
- }
3178
- }
3179
- ctx.closePath();
3180
- ctx.fill();
3181
- ctx.stroke();
3182
- });
3183
- // document.body.appendChild(canvas);
3184
- return {
3185
- x: originX,
3186
- y: originY,
3187
- scale: this.scale,
3188
- base64: canvas.toDataURL("image/jpeg", 0.8)
3189
- };
3190
- }
3191
- else {
3192
- //带旋转
3193
- }
3149
+ // this.igsGroup.position.set(-97,200,-800)
3150
+ // this. igsGroup.updateMatrix();
3151
+ // if (this.igsGroup.rotation.x == 0 && this.igsGroup.rotation.y == 0) {
3152
+ // let canvas = document.createElement("canvas")
3153
+ // let originX = (this.pading - this.box.min.x) * this.scale;
3154
+ // let originY = (this.pading - this.box.min.y) * this.scale;
3155
+ // let vec = this.box.getSize(new Vector3);
3156
+ // canvas.width = (vec.x + this.pading * 2) * this.scale;
3157
+ // canvas.height = (vec.y + this.pading * 2) * this.scale;
3158
+ // let ctx = canvas.getContext("2d")
3159
+ // ctx.fillStyle = "#ffffff"
3160
+ // ctx.fillRect(0, 0, canvas.width, canvas.height)
3161
+ // ctx.setTransform(this.scale, 0, 0, this.scale, originX, originY)
3162
+ // this.map.sort((a, b) => a.height - b.height);
3163
+ // let max = this.map[this.map.length - 1].height;
3164
+ // // console.log(this.map)
3165
+ // this.map.forEach(({ height, points }, index) => {
3166
+ // let grey = (max - height) / max * 200
3167
+ // ctx.fillStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;
3168
+ // ctx.strokeStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;
3169
+ // ctx.lineWidth = 1 / this.scale
3170
+ // ctx.lineCap = "round";
3171
+ // ctx.lineJoin = "round"
3172
+ // ctx.beginPath()
3173
+ // for (let i = 0; i < points.length; i += 2) {
3174
+ // if (i == 0) {
3175
+ // ctx.moveTo(points[i], points[i + 1])
3176
+ // } else {
3177
+ // ctx.lineTo(points[i], points[i + 1])
3178
+ // }
3179
+ // }
3180
+ // ctx.closePath();
3181
+ // ctx.fill();
3182
+ // ctx.stroke();
3183
+ // })
3184
+ // // document.body.appendChild(canvas);
3185
+ // return {
3186
+ // rotateX: 0,
3187
+ // rotateY: 0,
3188
+ // x: originX,
3189
+ // y: originY,
3190
+ // scale: this.scale,
3191
+ // base64: canvas.toDataURL("image/jpeg", 0.8)
3192
+ // }
3193
+ // } else {
3194
+ //带旋转
3195
+ let igsGroup = this.igsGroup.clone();
3196
+ // igsGroup.scale.set(-1, 1, 1)
3197
+ // igsGroup.position.set(-97,200,-800)
3198
+ // igsGroup.updateMatrix();
3199
+ let box = new three__WEBPACK_IMPORTED_MODULE_0__["Box3"];
3200
+ igsGroup.children.forEach((m) => {
3201
+ let geo = m.geometry.clone();
3202
+ geo.applyMatrix4(this.igsGroup.matrix);
3203
+ geo.computeBoundingBox();
3204
+ box.union(geo.boundingBox);
3205
+ });
3206
+ const size = box.getSize(new three__WEBPACK_IMPORTED_MODULE_0__["Vector3"]());
3207
+ // console.log(size)
3208
+ const center = box.getCenter(new three__WEBPACK_IMPORTED_MODULE_0__["Vector3"]());
3209
+ // 2. 创建离屏渲染场景
3210
+ const scene = new three__WEBPACK_IMPORTED_MODULE_0__["Scene"]();
3211
+ scene.background = new three__WEBPACK_IMPORTED_MODULE_0__["Color"](0xffffff); // 白色背景
3212
+ scene.add(igsGroup);
3213
+ var pll = new three__WEBPACK_IMPORTED_MODULE_0__["DirectionalLight"](0xffffff, 0.3);
3214
+ pll.position.set(5, -10, 10);
3215
+ scene.add(pll);
3216
+ var pll = new three__WEBPACK_IMPORTED_MODULE_0__["DirectionalLight"](0xffffff, 0.3);
3217
+ pll.position.set(0, 10, 0);
3218
+ scene.add(pll);
3219
+ scene.add(new three__WEBPACK_IMPORTED_MODULE_0__["AmbientLight"](0xeeeeee, 0.05));
3220
+ // 3. 配置正交相机(俯视图)
3221
+ const viewWidth = size.x + this.pading * 2;
3222
+ const viewHeight = size.y + this.pading * 2;
3223
+ // console.log(size,center,viewWidth,viewHeight)
3224
+ const camera = new three__WEBPACK_IMPORTED_MODULE_0__["OrthographicCamera"](-viewWidth / 2, viewWidth / 2, viewHeight / 2, -viewHeight / 2,
3225
+ // viewWidth / 2, // left (正值) ← 关键:+X映射到左
3226
+ // -viewWidth / 2, // right (负值) ← 关键:-X映射到右
3227
+ // -viewHeight / 2, // top (负值) ← 关键:-Y映射到上
3228
+ // viewHeight / 2, // bottom (正值) ← 关键:+Y映射到下
3229
+ 0.1, 1000);
3230
+ camera.up = new three__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0);
3231
+ // 相机放在 Z 轴正上方(向下看)
3232
+ camera.position.set(center.x, center.y, center.z + size.z / 2 + 50);
3233
+ camera.lookAt(center.x, center.y, center.z);
3234
+ // 5. 渲染到 canvas
3235
+ const renderer = new three__WEBPACK_IMPORTED_MODULE_0__["WebGLRenderer"]({
3236
+ antialias: true,
3237
+ preserveDrawingBuffer: true // 允许导出图片
3238
+ });
3239
+ // 设置合适的像素尺寸(可调整)
3240
+ const pixelRatio = 2; // 用于提高清晰度
3241
+ renderer.setSize(viewWidth * pixelRatio, viewHeight * pixelRatio);
3242
+ renderer.setPixelRatio(window.devicePixelRatio);
3243
+ // 渲染
3244
+ renderer.render(scene, camera);
3245
+ // document.body.appendChild(renderer.domElement);
3246
+ // 6. 返回渲染结果(canvas 元素)
3247
+ return {
3248
+ rotateX: this.igsGroup.rotation.x,
3249
+ rotateY: this.igsGroup.rotation.y,
3250
+ rotateZ: this.igsGroup.rotation.z,
3251
+ x: this.pading - box.min.x,
3252
+ y: this.pading - box.min.y,
3253
+ scale: 1,
3254
+ base64: renderer.domElement.toDataURL("image/jpeg", 0.8)
3255
+ };
3256
+ // }
3194
3257
  }
3195
3258
  addMouseEvent() {
3196
3259
  this.raycaster = new three__WEBPACK_IMPORTED_MODULE_0__["Raycaster"]();
@@ -3260,8 +3323,8 @@ class Main extends three__WEBPACK_IMPORTED_MODULE_0__["EventDispatcher"] {
3260
3323
  this.scene.add(this.transformControls);
3261
3324
  // 选中父类为需要控制的物体
3262
3325
  this.transformControls.attach(this.igsGroup);
3263
- this.transformControls.mode = 'rotate';
3264
- this.transformControls.showZ = false;
3326
+ this.transformControls.mode = "rotate";
3327
+ this.transformControls.showZ = true;
3265
3328
  this.transformControls.showX = this.transformControls.showY = true;
3266
3329
  // 如果指针(鼠标/触摸)为活动状态则触发该事件。
3267
3330
  this.transformControls.addEventListener('mouseDown', () => {
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///./node_modules/.pnpm/three@0.139.2/node_modules/three/examples/jsm/controls/OrbitControls.js","webpack:///./node_modules/.pnpm/three@0.139.2/node_modules/three/examples/jsm/controls/TransformControls.js","webpack:///./src/Main.ts","webpack:///external \"three\""],"names":[],"mappings":"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AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,EAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AA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","file":"main.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"three\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"three\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"three\")) : factory(root[\"three\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(window, function(__WEBPACK_EXTERNAL_MODULE_three__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/Main.ts\");\n","import {\n\tEventDispatcher,\n\tMOUSE,\n\tQuaternion,\n\tSpherical,\n\tTOUCH,\n\tVector2,\n\tVector3\n} from 'three';\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one-finger move\n// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move\n\nconst _changeEvent = { type: 'change' };\nconst _startEvent = { type: 'start' };\nconst _endEvent = { type: 'end' };\n\nclass OrbitControls extends EventDispatcher {\n\n\tconstructor( object, domElement ) {\n\n\t\tsuper();\n\n\t\tif ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter \"domElement\" is now mandatory.' );\n\t\tif ( domElement === document ) console.error( 'THREE.OrbitControls: \"document\" should not be used as the target \"domElement\". Please use \"renderer.domElement\" instead.' );\n\n\t\tthis.object = object;\n\t\tthis.domElement = domElement;\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.05;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.panSpeed = 1.0;\n\t\tthis.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n\t\t// Touch fingers\n\t\tthis.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t// the target DOM element for key events\n\t\tthis._domElementKeyEvents = null;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.getDistance = function () {\n\n\t\t\treturn this.object.position.distanceTo( this.target );\n\n\t\t};\n\n\t\tthis.listenToKeyEvents = function ( domElement ) {\n\n\t\t\tdomElement.addEventListener( 'keydown', onKeyDown );\n\t\t\tthis._domElementKeyEvents = domElement;\n\n\t\t};\n\n\t\tthis.saveState = function () {\n\n\t\t\tscope.target0.copy( scope.target );\n\t\t\tscope.position0.copy( scope.object.position );\n\t\t\tscope.zoom0 = scope.object.zoom;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function () {\n\n\t\t\tconst offset = new Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tconst quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\n\t\t\tconst quatInverse = quat.clone().invert();\n\n\t\t\tconst lastPosition = new Vector3();\n\t\t\tconst lastQuaternion = new Quaternion();\n\n\t\t\tconst twoPI = 2 * Math.PI;\n\n\t\t\treturn function update() {\n\n\t\t\t\tconst position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tif ( scope.enableDamping ) {\n\n\t\t\t\t\tspherical.theta += sphericalDelta.theta * scope.dampingFactor;\n\t\t\t\t\tspherical.phi += sphericalDelta.phi * scope.dampingFactor;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t}\n\n\t\t\t\t// restrict theta to be between desired limits\n\n\t\t\t\tlet min = scope.minAzimuthAngle;\n\t\t\t\tlet max = scope.maxAzimuthAngle;\n\n\t\t\t\tif ( isFinite( min ) && isFinite( max ) ) {\n\n\t\t\t\t\tif ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;\n\n\t\t\t\t\tif ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;\n\n\t\t\t\t\tif ( min <= max ) {\n\n\t\t\t\t\t\tspherical.theta = Math.max( min, Math.min( max, spherical.theta ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tspherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?\n\t\t\t\t\t\t\tMath.max( min, spherical.theta ) :\n\t\t\t\t\t\t\tMath.min( max, spherical.theta );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tscope.target.addScaledVector( panOffset, scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\t}\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t\tpanOffset.multiplyScalar( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function () {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu );\n\n\t\t\tscope.domElement.removeEventListener( 'pointerdown', onPointerDown );\n\t\t\tscope.domElement.removeEventListener( 'pointercancel', onPointerCancel );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel );\n\n\t\t\tscope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t\tscope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\n\t\t\tif ( scope._domElementKeyEvents !== null ) {\n\n\t\t\t\tscope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );\n\n\t\t\t}\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tconst scope = this;\n\n\t\tconst STATE = {\n\t\t\tNONE: - 1,\n\t\t\tROTATE: 0,\n\t\t\tDOLLY: 1,\n\t\t\tPAN: 2,\n\t\t\tTOUCH_ROTATE: 3,\n\t\t\tTOUCH_PAN: 4,\n\t\t\tTOUCH_DOLLY_PAN: 5,\n\t\t\tTOUCH_DOLLY_ROTATE: 6\n\t\t};\n\n\t\tlet state = STATE.NONE;\n\n\t\tconst EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tconst spherical = new Spherical();\n\t\tconst sphericalDelta = new Spherical();\n\n\t\tlet scale = 1;\n\t\tconst panOffset = new Vector3();\n\t\tlet zoomChanged = false;\n\n\t\tconst rotateStart = new Vector2();\n\t\tconst rotateEnd = new Vector2();\n\t\tconst rotateDelta = new Vector2();\n\n\t\tconst panStart = new Vector2();\n\t\tconst panEnd = new Vector2();\n\t\tconst panDelta = new Vector2();\n\n\t\tconst dollyStart = new Vector2();\n\t\tconst dollyEnd = new Vector2();\n\t\tconst dollyDelta = new Vector2();\n\n\t\tconst pointers = [];\n\t\tconst pointerPositions = {};\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tconst panLeft = function () {\n\n\t\t\tconst v = new Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tconst panUp = function () {\n\n\t\t\tconst v = new Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tif ( scope.screenSpacePanning === true ) {\n\n\t\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 );\n\t\t\t\t\tv.crossVectors( scope.object.up, v );\n\n\t\t\t\t}\n\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tconst pan = function () {\n\n\t\t\tconst offset = new Vector3();\n\n\t\t\treturn function pan( deltaX, deltaY ) {\n\n\t\t\t\tconst element = scope.domElement;\n\n\t\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tconst position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tlet targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we use only clientHeight here so aspect ratio does not distort speed\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n\t\t\tconst element = scope.domElement;\n\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\tlet needsUpdate = false;\n\n\t\t\tswitch ( event.code ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t// prevent the browser from scrolling on cursor keys\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tscope.update();\n\n\t\t\t}\n\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate() {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\trotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );\n\t\t\t\tconst y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );\n\n\t\t\t\trotateStart.set( x, y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartPan() {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\tpanStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );\n\t\t\t\tconst y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );\n\n\t\t\t\tpanStart.set( x, y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly() {\n\n\t\t\tconst dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX;\n\t\t\tconst dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY;\n\n\t\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartDollyPan() {\n\n\t\t\tif ( scope.enableZoom ) handleTouchStartDolly();\n\n\t\t\tif ( scope.enablePan ) handleTouchStartPan();\n\n\t\t}\n\n\t\tfunction handleTouchStartDollyRotate() {\n\n\t\t\tif ( scope.enableZoom ) handleTouchStartDolly();\n\n\t\t\tif ( scope.enableRotate ) handleTouchStartRotate();\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\tif ( pointers.length == 1 ) {\n\n\t\t\t\trotateEnd.set( event.pageX, event.pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\t\trotateEnd.set( x, y );\n\n\t\t\t}\n\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n\t\t\tconst element = scope.domElement;\n\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\tpanEnd.set( event.pageX, event.pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\t\tpanEnd.set( x, y );\n\n\t\t\t}\n\n\t\t\tpanDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\tconst dx = event.pageX - position.x;\n\t\t\tconst dy = event.pageY - position.y;\n\n\t\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );\n\n\t\t\tdollyOut( dollyDelta.y );\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDollyPan( event ) {\n\n\t\t\tif ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n\t\t\tif ( scope.enablePan ) handleTouchMovePan( event );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDollyRotate( event ) {\n\n\t\t\tif ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n\t\t\tif ( scope.enableRotate ) handleTouchMoveRotate( event );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onPointerDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tif ( pointers.length === 0 ) {\n\n\t\t\t\tscope.domElement.setPointerCapture( event.pointerId );\n\n\t\t\t\tscope.domElement.addEventListener( 'pointermove', onPointerMove );\n\t\t\t\tscope.domElement.addEventListener( 'pointerup', onPointerUp );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\taddPointer( event );\n\n\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\tonTouchStart( event );\n\n\t\t\t} else {\n\n\t\t\t\tonMouseDown( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onPointerMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\tonTouchMove( event );\n\n\t\t\t} else {\n\n\t\t\t\tonMouseMove( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onPointerUp( event ) {\n\n\t\t removePointer( event );\n\n\t\t if ( pointers.length === 0 ) {\n\n\t\t scope.domElement.releasePointerCapture( event.pointerId );\n\n\t\t scope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t scope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\t\t }\n\n\t\t scope.dispatchEvent( _endEvent );\n\n\t\t state = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onPointerCancel( event ) {\n\n\t\t\tremovePointer( event );\n\n\t\t}\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tlet mouseAction;\n\n\t\t\tswitch ( event.button ) {\n\n\t\t\t\tcase 0:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.LEFT;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 1:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.MIDDLE;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.RIGHT;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tmouseAction = - 1;\n\n\t\t\t}\n\n\t\t\tswitch ( mouseAction ) {\n\n\t\t\t\tcase MOUSE.DOLLY:\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MOUSE.ROTATE:\n\n\t\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\t\t\tstate = STATE.PAN;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MOUSE.PAN:\n\n\t\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\t\t\tstate = STATE.PAN;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( state ) {\n\n\t\t\t\tcase STATE.ROTATE:\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.DOLLY:\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.PAN:\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( _endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\ttrackPointer( event );\n\n\t\t\tswitch ( pointers.length ) {\n\n\t\t\t\tcase 1:\n\n\t\t\t\t\tswitch ( scope.touches.ONE ) {\n\n\t\t\t\t\t\tcase TOUCH.ROTATE:\n\n\t\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartRotate();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TOUCH.PAN:\n\n\t\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartPan();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\n\n\t\t\t\t\tswitch ( scope.touches.TWO ) {\n\n\t\t\t\t\t\tcase TOUCH.DOLLY_PAN:\n\n\t\t\t\t\t\t\tif ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartDollyPan();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_DOLLY_PAN;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TOUCH.DOLLY_ROTATE:\n\n\t\t\t\t\t\t\tif ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartDollyRotate();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_DOLLY_ROTATE;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\ttrackPointer( event );\n\n\t\t\tswitch ( state ) {\n\n\t\t\t\tcase STATE.TOUCH_ROTATE:\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_PAN:\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_DOLLY_PAN:\n\n\t\t\t\t\tif ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchMoveDollyPan( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_DOLLY_ROTATE:\n\n\t\t\t\t\tif ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchMoveDollyRotate( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\tfunction addPointer( event ) {\n\n\t\t\tpointers.push( event );\n\n\t\t}\n\n\t\tfunction removePointer( event ) {\n\n\t\t\tdelete pointerPositions[ event.pointerId ];\n\n\t\t\tfor ( let i = 0; i < pointers.length; i ++ ) {\n\n\t\t\t\tif ( pointers[ i ].pointerId == event.pointerId ) {\n\n\t\t\t\t\tpointers.splice( i, 1 );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction trackPointer( event ) {\n\n\t\t\tlet position = pointerPositions[ event.pointerId ];\n\n\t\t\tif ( position === undefined ) {\n\n\t\t\t\tposition = new Vector2();\n\t\t\t\tpointerPositions[ event.pointerId ] = position;\n\n\t\t\t}\n\n\t\t\tposition.set( event.pageX, event.pageY );\n\n\t\t}\n\n\t\tfunction getSecondPointerPosition( event ) {\n\n\t\t\tconst pointer = ( event.pointerId === pointers[ 0 ].pointerId ) ? pointers[ 1 ] : pointers[ 0 ];\n\n\t\t\treturn pointerPositions[ pointer.pointerId ];\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu );\n\n\t\tscope.domElement.addEventListener( 'pointerdown', onPointerDown );\n\t\tscope.domElement.addEventListener( 'pointercancel', onPointerCancel );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t}\n\n}\n\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n// This is very similar to OrbitControls, another set of touch behavior\n//\n// Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate\n// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n// Pan - left mouse, or arrow keys / touch: one-finger move\n\nclass MapControls extends OrbitControls {\n\n\tconstructor( object, domElement ) {\n\n\t\tsuper( object, domElement );\n\n\t\tthis.screenSpacePanning = false; // pan orthogonal to world-space direction camera.up\n\n\t\tthis.mouseButtons.LEFT = MOUSE.PAN;\n\t\tthis.mouseButtons.RIGHT = MOUSE.ROTATE;\n\n\t\tthis.touches.ONE = TOUCH.PAN;\n\t\tthis.touches.TWO = TOUCH.DOLLY_ROTATE;\n\n\t}\n\n}\n\nexport { OrbitControls, MapControls };\n","import {\n\tBoxGeometry,\n\tBufferGeometry,\n\tCylinderGeometry,\n\tDoubleSide,\n\tEuler,\n\tFloat32BufferAttribute,\n\tLine,\n\tLineBasicMaterial,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tOctahedronGeometry,\n\tPlaneGeometry,\n\tQuaternion,\n\tRaycaster,\n\tSphereGeometry,\n\tTorusGeometry,\n\tVector3\n} from 'three';\n\nconst _raycaster = new Raycaster();\n\nconst _tempVector = new Vector3();\nconst _tempVector2 = new Vector3();\nconst _tempQuaternion = new Quaternion();\nconst _unit = {\n\tX: new Vector3( 1, 0, 0 ),\n\tY: new Vector3( 0, 1, 0 ),\n\tZ: new Vector3( 0, 0, 1 )\n};\n\nconst _changeEvent = { type: 'change' };\nconst _mouseDownEvent = { type: 'mouseDown' };\nconst _mouseUpEvent = { type: 'mouseUp', mode: null };\nconst _objectChangeEvent = { type: 'objectChange' };\n\nclass TransformControls extends Object3D {\n\n\tconstructor( camera, domElement ) {\n\n\t\tsuper();\n\n\t\tif ( domElement === undefined ) {\n\n\t\t\tconsole.warn( 'THREE.TransformControls: The second parameter \"domElement\" is now mandatory.' );\n\t\t\tdomElement = document;\n\n\t\t}\n\n\t\tthis.visible = false;\n\t\tthis.domElement = domElement;\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t\tconst _gizmo = new TransformControlsGizmo();\n\t\tthis._gizmo = _gizmo;\n\t\tthis.add( _gizmo );\n\n\t\tconst _plane = new TransformControlsPlane();\n\t\tthis._plane = _plane;\n\t\tthis.add( _plane );\n\n\t\tconst scope = this;\n\n\t\t// Defined getter, setter and store for a property\n\t\tfunction defineProperty( propName, defaultValue ) {\n\n\t\t\tlet propValue = defaultValue;\n\n\t\t\tObject.defineProperty( scope, propName, {\n\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn propValue !== undefined ? propValue : defaultValue;\n\n\t\t\t\t},\n\n\t\t\t\tset: function ( value ) {\n\n\t\t\t\t\tif ( propValue !== value ) {\n\n\t\t\t\t\t\tpropValue = value;\n\t\t\t\t\t\t_plane[ propName ] = value;\n\t\t\t\t\t\t_gizmo[ propName ] = value;\n\n\t\t\t\t\t\tscope.dispatchEvent( { type: propName + '-changed', value: value } );\n\t\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tscope[ propName ] = defaultValue;\n\t\t\t_plane[ propName ] = defaultValue;\n\t\t\t_gizmo[ propName ] = defaultValue;\n\n\t\t}\n\n\t\t// Define properties with getters/setter\n\t\t// Setting the defined property will automatically trigger change event\n\t\t// Defined properties are passed down to gizmo and plane\n\n\t\tdefineProperty( 'camera', camera );\n\t\tdefineProperty( 'object', undefined );\n\t\tdefineProperty( 'enabled', true );\n\t\tdefineProperty( 'axis', null );\n\t\tdefineProperty( 'mode', 'translate' );\n\t\tdefineProperty( 'translationSnap', null );\n\t\tdefineProperty( 'rotationSnap', null );\n\t\tdefineProperty( 'scaleSnap', null );\n\t\tdefineProperty( 'space', 'world' );\n\t\tdefineProperty( 'size', 1 );\n\t\tdefineProperty( 'dragging', false );\n\t\tdefineProperty( 'showX', true );\n\t\tdefineProperty( 'showY', true );\n\t\tdefineProperty( 'showZ', true );\n\n\t\t// Reusable utility variables\n\n\t\tconst worldPosition = new Vector3();\n\t\tconst worldPositionStart = new Vector3();\n\t\tconst worldQuaternion = new Quaternion();\n\t\tconst worldQuaternionStart = new Quaternion();\n\t\tconst cameraPosition = new Vector3();\n\t\tconst cameraQuaternion = new Quaternion();\n\t\tconst pointStart = new Vector3();\n\t\tconst pointEnd = new Vector3();\n\t\tconst rotationAxis = new Vector3();\n\t\tconst rotationAngle = 0;\n\t\tconst eye = new Vector3();\n\n\t\t// TODO: remove properties unused in plane and gizmo\n\n\t\tdefineProperty( 'worldPosition', worldPosition );\n\t\tdefineProperty( 'worldPositionStart', worldPositionStart );\n\t\tdefineProperty( 'worldQuaternion', worldQuaternion );\n\t\tdefineProperty( 'worldQuaternionStart', worldQuaternionStart );\n\t\tdefineProperty( 'cameraPosition', cameraPosition );\n\t\tdefineProperty( 'cameraQuaternion', cameraQuaternion );\n\t\tdefineProperty( 'pointStart', pointStart );\n\t\tdefineProperty( 'pointEnd', pointEnd );\n\t\tdefineProperty( 'rotationAxis', rotationAxis );\n\t\tdefineProperty( 'rotationAngle', rotationAngle );\n\t\tdefineProperty( 'eye', eye );\n\n\t\tthis._offset = new Vector3();\n\t\tthis._startNorm = new Vector3();\n\t\tthis._endNorm = new Vector3();\n\t\tthis._cameraScale = new Vector3();\n\n\t\tthis._parentPosition = new Vector3();\n\t\tthis._parentQuaternion = new Quaternion();\n\t\tthis._parentQuaternionInv = new Quaternion();\n\t\tthis._parentScale = new Vector3();\n\n\t\tthis._worldScaleStart = new Vector3();\n\t\tthis._worldQuaternionInv = new Quaternion();\n\t\tthis._worldScale = new Vector3();\n\n\t\tthis._positionStart = new Vector3();\n\t\tthis._quaternionStart = new Quaternion();\n\t\tthis._scaleStart = new Vector3();\n\n\t\tthis._getPointer = getPointer.bind( this );\n\t\tthis._onPointerDown = onPointerDown.bind( this );\n\t\tthis._onPointerHover = onPointerHover.bind( this );\n\t\tthis._onPointerMove = onPointerMove.bind( this );\n\t\tthis._onPointerUp = onPointerUp.bind( this );\n\n\t\tthis.domElement.addEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.addEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.addEventListener( 'pointerup', this._onPointerUp );\n\n\t}\n\n\t// updateMatrixWorld updates key transformation variables\n\tupdateMatrixWorld() {\n\n\t\tif ( this.object !== undefined ) {\n\n\t\t\tthis.object.updateMatrixWorld();\n\n\t\t\tif ( this.object.parent === null ) {\n\n\t\t\t\tconsole.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );\n\n\t\t\t} else {\n\n\t\t\t\tthis.object.parent.matrixWorld.decompose( this._parentPosition, this._parentQuaternion, this._parentScale );\n\n\t\t\t}\n\n\t\t\tthis.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );\n\n\t\t\tthis._parentQuaternionInv.copy( this._parentQuaternion ).invert();\n\t\t\tthis._worldQuaternionInv.copy( this.worldQuaternion ).invert();\n\n\t\t}\n\n\t\tthis.camera.updateMatrixWorld();\n\t\tthis.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );\n\n\t\tthis.eye.copy( this.cameraPosition ).sub( this.worldPosition ).normalize();\n\n\t\tsuper.updateMatrixWorld( this );\n\n\t}\n\n\tpointerHover( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true ) return;\n\n\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );\n\n\t\tif ( intersect ) {\n\n\t\t\tthis.axis = intersect.object.name;\n\n\t\t} else {\n\n\t\t\tthis.axis = null;\n\n\t\t}\n\n\t}\n\n\tpointerDown( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;\n\n\t\tif ( this.axis !== null ) {\n\n\t\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\t\tif ( planeIntersect ) {\n\n\t\t\t\tthis.object.updateMatrixWorld();\n\t\t\t\tthis.object.parent.updateMatrixWorld();\n\n\t\t\t\tthis._positionStart.copy( this.object.position );\n\t\t\t\tthis._quaternionStart.copy( this.object.quaternion );\n\t\t\t\tthis._scaleStart.copy( this.object.scale );\n\n\t\t\t\tthis.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );\n\n\t\t\t\tthis.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\t\t}\n\n\t\t\tthis.dragging = true;\n\t\t\t_mouseDownEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseDownEvent );\n\n\t\t}\n\n\t}\n\n\tpointerMove( pointer ) {\n\n\t\tconst axis = this.axis;\n\t\tconst mode = this.mode;\n\t\tconst object = this.object;\n\t\tlet space = this.space;\n\n\t\tif ( mode === 'scale' ) {\n\n\t\t\tspace = 'local';\n\n\t\t} else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) {\n\n\t\t\tspace = 'world';\n\n\t\t}\n\n\t\tif ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;\n\n\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\tif ( ! planeIntersect ) return;\n\n\t\tthis.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\tif ( mode === 'translate' ) {\n\n\t\t\t// Apply translate\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t}\n\n\t\t\tif ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;\n\t\t\tif ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;\n\t\t\tif ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );\n\n\t\t\t} else {\n\n\t\t\t\tthis._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale );\n\n\t\t\t}\n\n\t\t\tobject.position.copy( this._offset ).add( this._positionStart );\n\n\t\t\t// Apply translation snap\n\n\t\t\tif ( this.translationSnap ) {\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\tobject.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.position.applyQuaternion( this._quaternionStart );\n\n\t\t\t\t}\n\n\t\t\t\tif ( space === 'world' ) {\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( mode === 'scale' ) {\n\n\t\t\tif ( axis.search( 'XYZ' ) !== - 1 ) {\n\n\t\t\t\tlet d = this.pointEnd.length() / this.pointStart.length();\n\n\t\t\t\tif ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;\n\n\t\t\t\t_tempVector2.set( d, d, d );\n\n\t\t\t} else {\n\n\t\t\t\t_tempVector.copy( this.pointStart );\n\t\t\t\t_tempVector2.copy( this.pointEnd );\n\n\t\t\t\t_tempVector.applyQuaternion( this._worldQuaternionInv );\n\t\t\t\t_tempVector2.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t\t_tempVector2.divide( _tempVector );\n\n\t\t\t\tif ( axis.search( 'X' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.x = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.y = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.z = 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Apply scale\n\n\t\t\tobject.scale.copy( this._scaleStart ).multiply( _tempVector2 );\n\n\t\t\tif ( this.scaleSnap ) {\n\n\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( mode === 'rotate' ) {\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tconst ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );\n\n\t\t\tif ( axis === 'E' ) {\n\n\t\t\t\tthis.rotationAxis.copy( this.eye );\n\t\t\t\tthis.rotationAngle = this.pointEnd.angleTo( this.pointStart );\n\n\t\t\t\tthis._startNorm.copy( this.pointStart ).normalize();\n\t\t\t\tthis._endNorm.copy( this.pointEnd ).normalize();\n\n\t\t\t\tthis.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );\n\n\t\t\t} else if ( axis === 'XYZE' ) {\n\n\t\t\t\tthis.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();\n\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;\n\n\t\t\t} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {\n\n\t\t\t\tthis.rotationAxis.copy( _unit[ axis ] );\n\n\t\t\t\t_tempVector.copy( _unit[ axis ] );\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;\n\n\t\t\t}\n\n\t\t\t// Apply rotation snap\n\n\t\t\tif ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap;\n\n\t\t\t// Apply rotate\n\t\t\tif ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {\n\n\t\t\t\tobject.quaternion.copy( this._quaternionStart );\n\t\t\t\tobject.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\tthis.rotationAxis.applyQuaternion( this._parentQuaternionInv );\n\t\t\t\tobject.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) );\n\t\t\t\tobject.quaternion.multiply( this._quaternionStart ).normalize();\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.dispatchEvent( _changeEvent );\n\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t}\n\n\tpointerUp( pointer ) {\n\n\t\tif ( pointer.button !== 0 ) return;\n\n\t\tif ( this.dragging && ( this.axis !== null ) ) {\n\n\t\t\t_mouseUpEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseUpEvent );\n\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tthis.axis = null;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.domElement.removeEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\tthis.traverse( function ( child ) {\n\n\t\t\tif ( child.geometry ) child.geometry.dispose();\n\t\t\tif ( child.material ) child.material.dispose();\n\n\t\t} );\n\n\t}\n\n\t// Set current object\n\tattach( object ) {\n\n\t\tthis.object = object;\n\t\tthis.visible = true;\n\n\t\treturn this;\n\n\t}\n\n\t// Detatch from object\n\tdetach() {\n\n\t\tthis.object = undefined;\n\t\tthis.visible = false;\n\t\tthis.axis = null;\n\n\t\treturn this;\n\n\t}\n\n\treset() {\n\n\t\tif ( ! this.enabled ) return;\n\n\t\tif ( this.dragging ) {\n\n\t\t\tthis.object.position.copy( this._positionStart );\n\t\t\tthis.object.quaternion.copy( this._quaternionStart );\n\t\t\tthis.object.scale.copy( this._scaleStart );\n\n\t\t\tthis.dispatchEvent( _changeEvent );\n\t\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t\t\tthis.pointStart.copy( this.pointEnd );\n\n\t\t}\n\n\t}\n\n\tgetRaycaster() {\n\n\t\treturn _raycaster;\n\n\t}\n\n\t// TODO: deprecate\n\n\tgetMode() {\n\n\t\treturn this.mode;\n\n\t}\n\n\tsetMode( mode ) {\n\n\t\tthis.mode = mode;\n\n\t}\n\n\tsetTranslationSnap( translationSnap ) {\n\n\t\tthis.translationSnap = translationSnap;\n\n\t}\n\n\tsetRotationSnap( rotationSnap ) {\n\n\t\tthis.rotationSnap = rotationSnap;\n\n\t}\n\n\tsetScaleSnap( scaleSnap ) {\n\n\t\tthis.scaleSnap = scaleSnap;\n\n\t}\n\n\tsetSize( size ) {\n\n\t\tthis.size = size;\n\n\t}\n\n\tsetSpace( space ) {\n\n\t\tthis.space = space;\n\n\t}\n\n\tupdate() {\n\n\t\tconsole.warn( 'THREE.TransformControls: update function has no more functionality and therefore has been deprecated.' );\n\n\t}\n\n}\n\nTransformControls.prototype.isTransformControls = true;\n\n// mouse / touch event handlers\n\nfunction getPointer( event ) {\n\n\tif ( this.domElement.ownerDocument.pointerLockElement ) {\n\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tbutton: event.button\n\t\t};\n\n\t} else {\n\n\t\tconst rect = this.domElement.getBoundingClientRect();\n\n\t\treturn {\n\t\t\tx: ( event.clientX - rect.left ) / rect.width * 2 - 1,\n\t\t\ty: - ( event.clientY - rect.top ) / rect.height * 2 + 1,\n\t\t\tbutton: event.button\n\t\t};\n\n\t}\n\n}\n\nfunction onPointerHover( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tswitch ( event.pointerType ) {\n\n\t\tcase 'mouse':\n\t\tcase 'pen':\n\t\t\tthis.pointerHover( this._getPointer( event ) );\n\t\t\tbreak;\n\n\t}\n\n}\n\nfunction onPointerDown( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tif ( ! document.pointerLockElement ) {\n\n\t\tthis.domElement.setPointerCapture( event.pointerId );\n\n\t}\n\n\tthis.domElement.addEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerHover( this._getPointer( event ) );\n\tthis.pointerDown( this._getPointer( event ) );\n\n}\n\nfunction onPointerMove( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.pointerMove( this._getPointer( event ) );\n\n}\n\nfunction onPointerUp( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.domElement.releasePointerCapture( event.pointerId );\n\n\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerUp( this._getPointer( event ) );\n\n}\n\nfunction intersectObjectWithRay( object, raycaster, includeInvisible ) {\n\n\tconst allIntersections = raycaster.intersectObject( object, true );\n\n\tfor ( let i = 0; i < allIntersections.length; i ++ ) {\n\n\t\tif ( allIntersections[ i ].object.visible || includeInvisible ) {\n\n\t\t\treturn allIntersections[ i ];\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\n//\n\n// Reusable utility variables\n\nconst _tempEuler = new Euler();\nconst _alignVector = new Vector3( 0, 1, 0 );\nconst _zeroVector = new Vector3( 0, 0, 0 );\nconst _lookAtMatrix = new Matrix4();\nconst _tempQuaternion2 = new Quaternion();\nconst _identityQuaternion = new Quaternion();\nconst _dirVector = new Vector3();\nconst _tempMatrix = new Matrix4();\n\nconst _unitX = new Vector3( 1, 0, 0 );\nconst _unitY = new Vector3( 0, 1, 0 );\nconst _unitZ = new Vector3( 0, 0, 1 );\n\nconst _v1 = new Vector3();\nconst _v2 = new Vector3();\nconst _v3 = new Vector3();\n\nclass TransformControlsGizmo extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.type = 'TransformControlsGizmo';\n\n\t\t// shared materials\n\n\t\tconst gizmoMaterial = new MeshBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\tconst gizmoLineMaterial = new LineBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\t// Make unique material for each axis/color\n\n\t\tconst matInvisible = gizmoMaterial.clone();\n\t\tmatInvisible.opacity = 0.15;\n\n\t\tconst matHelper = gizmoLineMaterial.clone();\n\t\tmatHelper.opacity = 0.5;\n\n\t\tconst matRed = gizmoMaterial.clone();\n\t\tmatRed.color.setHex( 0xff0000 );\n\n\t\tconst matGreen = gizmoMaterial.clone();\n\t\tmatGreen.color.setHex( 0x00ff00 );\n\n\t\tconst matBlue = gizmoMaterial.clone();\n\t\tmatBlue.color.setHex( 0x0000ff );\n\n\t\tconst matRedTransparent = gizmoMaterial.clone();\n\t\tmatRedTransparent.color.setHex( 0xff0000 );\n\t\tmatRedTransparent.opacity = 0.5;\n\n\t\tconst matGreenTransparent = gizmoMaterial.clone();\n\t\tmatGreenTransparent.color.setHex( 0x00ff00 );\n\t\tmatGreenTransparent.opacity = 0.5;\n\n\t\tconst matBlueTransparent = gizmoMaterial.clone();\n\t\tmatBlueTransparent.color.setHex( 0x0000ff );\n\t\tmatBlueTransparent.opacity = 0.5;\n\n\t\tconst matWhiteTransparent = gizmoMaterial.clone();\n\t\tmatWhiteTransparent.opacity = 0.25;\n\n\t\tconst matYellowTransparent = gizmoMaterial.clone();\n\t\tmatYellowTransparent.color.setHex( 0xffff00 );\n\t\tmatYellowTransparent.opacity = 0.25;\n\n\t\tconst matYellow = gizmoMaterial.clone();\n\t\tmatYellow.color.setHex( 0xffff00 );\n\n\t\tconst matGray = gizmoMaterial.clone();\n\t\tmatGray.color.setHex( 0x787878 );\n\n\t\t// reusable geometry\n\n\t\tconst arrowGeometry = new CylinderGeometry( 0, 0.04, 0.1, 12 );\n\t\tarrowGeometry.translate( 0, 0.05, 0 );\n\n\t\tconst scaleHandleGeometry = new BoxGeometry( 0.08, 0.08, 0.08 );\n\t\tscaleHandleGeometry.translate( 0, 0.04, 0 );\n\n\t\tconst lineGeometry = new BufferGeometry();\n\t\tlineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0,\t1, 0, 0 ], 3 ) );\n\n\t\tconst lineGeometry2 = new CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );\n\t\tlineGeometry2.translate( 0, 0.25, 0 );\n\n\t\tfunction CircleGeometry( radius, arc ) {\n\n\t\t\tconst geometry = new TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );\n\t\t\tgeometry.rotateY( Math.PI / 2 );\n\t\t\tgeometry.rotateX( Math.PI / 2 );\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position\n\n\t\tfunction TranslateHelperGeometry() {\n\n\t\t\tconst geometry = new BufferGeometry();\n\n\t\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Gizmo definitions - custom hierarchy definitions for setupGizmo() function\n\n\t\tconst gizmoTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, - 0.5, 0 ], [ Math.PI, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), null, [ Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent.clone() ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.2, 0 ), matInvisible ) ]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperTranslate = {\n\t\t\tSTART: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tEND: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tDELTA: [\n\t\t\t\t[ new Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 1 ), matGray ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matRed ) ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matGreen ), null, [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matBlue ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.75, 1 ), matYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperRotate = {\n\t\t\tAXIS: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( new SphereGeometry( 0.25, 10, 8 ), matInvisible ) ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.75, 0.1, 2, 24 ), matInvisible ) ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, - 0.5, 0 ], [ 0, 0, Math.PI ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.1, 0.1, 0.1 ), matWhiteTransparent.clone() ) ],\n\t\t\t]\n\t\t};\n\n\t\tconst pickerScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]],\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]],\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 0 ]],\n\t\t\t]\n\t\t};\n\n\t\tconst helperScale = {\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\t// Creates an Object3D with gizmos described in custom hierarchy definition.\n\n\t\tfunction setupGizmo( gizmoMap ) {\n\n\t\t\tconst gizmo = new Object3D();\n\n\t\t\tfor ( const name in gizmoMap ) {\n\n\t\t\t\tfor ( let i = gizmoMap[ name ].length; i --; ) {\n\n\t\t\t\t\tconst object = gizmoMap[ name ][ i ][ 0 ].clone();\n\t\t\t\t\tconst position = gizmoMap[ name ][ i ][ 1 ];\n\t\t\t\t\tconst rotation = gizmoMap[ name ][ i ][ 2 ];\n\t\t\t\t\tconst scale = gizmoMap[ name ][ i ][ 3 ];\n\t\t\t\t\tconst tag = gizmoMap[ name ][ i ][ 4 ];\n\n\t\t\t\t\t// name and tag properties are essential for picking and updating logic.\n\t\t\t\t\tobject.name = name;\n\t\t\t\t\tobject.tag = tag;\n\n\t\t\t\t\tif ( position ) {\n\n\t\t\t\t\t\tobject.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( rotation ) {\n\n\t\t\t\t\t\tobject.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( scale ) {\n\n\t\t\t\t\t\tobject.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.updateMatrix();\n\n\t\t\t\t\tconst tempGeometry = object.geometry.clone();\n\t\t\t\t\ttempGeometry.applyMatrix4( object.matrix );\n\t\t\t\t\tobject.geometry = tempGeometry;\n\t\t\t\t\tobject.renderOrder = Infinity;\n\n\t\t\t\t\tobject.position.set( 0, 0, 0 );\n\t\t\t\t\tobject.rotation.set( 0, 0, 0 );\n\t\t\t\t\tobject.scale.set( 1, 1, 1 );\n\n\t\t\t\t\tgizmo.add( object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn gizmo;\n\n\t\t}\n\n\t\t// Gizmo creation\n\n\t\tthis.gizmo = {};\n\t\tthis.picker = {};\n\t\tthis.helper = {};\n\n\t\tthis.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) );\n\t\tthis.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) );\n\t\tthis.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) );\n\t\tthis.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) );\n\t\tthis.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) );\n\t\tthis.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );\n\t\tthis.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );\n\t\tthis.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );\n\t\tthis.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) );\n\n\t\t// Pickers should be hidden always\n\n\t\tthis.picker[ 'translate' ].visible = false;\n\t\tthis.picker[ 'rotate' ].visible = false;\n\t\tthis.picker[ 'scale' ].visible = false;\n\n\t}\n\n\t// updateMatrixWorld will update transformations and appearance of individual handles\n\n\tupdateMatrixWorld( force ) {\n\n\t\tconst space = ( this.mode === 'scale' ) ? 'local' : this.space; // scale always oriented to local rotation\n\n\t\tconst quaternion = ( space === 'local' ) ? this.worldQuaternion : _identityQuaternion;\n\n\t\t// Show only gizmos for current transform mode\n\n\t\tthis.gizmo[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.gizmo[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.gizmo[ 'scale' ].visible = this.mode === 'scale';\n\n\t\tthis.helper[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.helper[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.helper[ 'scale' ].visible = this.mode === 'scale';\n\n\n\t\tlet handles = [];\n\t\thandles = handles.concat( this.picker[ this.mode ].children );\n\t\thandles = handles.concat( this.gizmo[ this.mode ].children );\n\t\thandles = handles.concat( this.helper[ this.mode ].children );\n\n\t\tfor ( let i = 0; i < handles.length; i ++ ) {\n\n\t\t\tconst handle = handles[ i ];\n\n\t\t\t// hide aligned to camera\n\n\t\t\thandle.visible = true;\n\t\t\thandle.rotation.set( 0, 0, 0 );\n\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\tlet factor;\n\n\t\t\tif ( this.camera.isOrthographicCamera ) {\n\n\t\t\t\tfactor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;\n\n\t\t\t} else {\n\n\t\t\t\tfactor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );\n\n\t\t\t}\n\n\t\t\thandle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 );\n\n\t\t\t// TODO: simplify helpers and consider decoupling from gizmo\n\n\t\t\tif ( handle.tag === 'helper' ) {\n\n\t\t\t\thandle.visible = false;\n\n\t\t\t\tif ( handle.name === 'AXIS' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.visible = !! this.axis;\n\n\t\t\t\t\tif ( this.axis === 'X' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Y' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Z' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'XYZE' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\t_alignVector.copy( this.rotationAxis );\n\t\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );\n\t\t\t\t\t\thandle.quaternion.multiply( _tempQuaternion );\n\t\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'E' ) {\n\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\n\t\t\t\t} else if ( handle.name === 'START' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'END' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPosition );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'DELTA' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.quaternion.copy( this.worldQuaternionStart );\n\t\t\t\t\t_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );\n\t\t\t\t\thandle.scale.copy( _tempVector );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\t\t\tif ( this.dragging ) {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis ) {\n\n\t\t\t\t\t\thandle.visible = this.axis.search( handle.name ) !== - 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// If updating helper, skip rest of the loop\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// Align handles to current local or world rotation\n\n\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\tif ( this.mode === 'translate' || this.mode === 'scale' ) {\n\n\t\t\t\t// Hide translate and scale axis facing the camera\n\n\t\t\t\tconst AXIS_HIDE_TRESHOLD = 0.99;\n\t\t\t\tconst PLANE_HIDE_TRESHOLD = 0.2;\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XY' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'YZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.mode === 'rotate' ) {\n\n\t\t\t\t// Align handles to current local or world rotation\n\n\t\t\t\t_tempQuaternion2.copy( quaternion );\n\t\t\t\t_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );\n\n\t\t\t\tif ( handle.name.search( 'E' ) !== - 1 ) {\n\n\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Hide disabled axes\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || ( this.showX && this.showY && this.showZ ) );\n\n\t\t\t// highlight selected axis\n\n\t\t\thandle.material._color = handle.material._color || handle.material.color.clone();\n\t\t\thandle.material._opacity = handle.material._opacity || handle.material.opacity;\n\n\t\t\thandle.material.color.copy( handle.material._color );\n\t\t\thandle.material.opacity = handle.material._opacity;\n\n\t\t\tif ( this.enabled && this.axis ) {\n\n\t\t\t\tif ( handle.name === this.axis ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t} else if ( this.axis.split( '' ).some( function ( a ) {\n\n\t\t\t\t\treturn handle.name === a;\n\n\t\t\t\t} ) ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nTransformControlsGizmo.prototype.isTransformControlsGizmo = true;\n\n//\n\nclass TransformControlsPlane extends Mesh {\n\n\tconstructor() {\n\n\t\tsuper(\n\t\t\tnew PlaneGeometry( 100000, 100000, 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { visible: false, wireframe: true, side: DoubleSide, transparent: true, opacity: 0.1, toneMapped: false } )\n\t\t);\n\n\t\tthis.type = 'TransformControlsPlane';\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tlet space = this.space;\n\n\t\tthis.position.copy( this.worldPosition );\n\n\t\tif ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation\n\n\t\t_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\n\t\t// Align the plane for current transform mode, axis and space.\n\n\t\t_alignVector.copy( _v2 );\n\n\t\tswitch ( this.mode ) {\n\n\t\t\tcase 'translate':\n\t\t\tcase 'scale':\n\t\t\t\tswitch ( this.axis ) {\n\n\t\t\t\t\tcase 'X':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v1 );\n\t\t\t\t\t\t_dirVector.copy( _v1 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Y':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v2 );\n\t\t\t\t\t\t_dirVector.copy( _v2 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v3 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XY':\n\t\t\t\t\t\t_dirVector.copy( _v3 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'YZ':\n\t\t\t\t\t\t_dirVector.copy( _v1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XZ':\n\t\t\t\t\t\t_alignVector.copy( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v2 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XYZ':\n\t\t\t\t\tcase 'E':\n\t\t\t\t\t\t_dirVector.set( 0, 0, 0 );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 'rotate':\n\t\t\tdefault:\n\t\t\t\t// special case for rotate\n\t\t\t\t_dirVector.set( 0, 0, 0 );\n\n\t\t}\n\n\t\tif ( _dirVector.length() === 0 ) {\n\n\t\t\t// If in rotate mode, make the plane parallel to camera\n\t\t\tthis.quaternion.copy( this.cameraQuaternion );\n\n\t\t} else {\n\n\t\t\t_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( _tempMatrix );\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nTransformControlsPlane.prototype.isTransformControlsPlane = true;\n\nexport { TransformControls, TransformControlsGizmo, TransformControlsPlane };\n","import { AmbientLight, AxesHelper, Box3, BufferAttribute, BufferGeometry, Color, DirectionalLight, EventDispatcher, Group, Mesh, MeshBasicMaterial, MeshStandardMaterial, Object3D, OrthographicCamera, PerspectiveCamera, Raycaster, Scene, Triangle, Vector2, Vector3, WebGLRenderer } from \"three\";\r\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';\r\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls';\r\nexport enum OutEventTypes {\r\n /**\r\n * 模型选中,事件参数会返回模型名\r\n */\r\n MODEL_SELECTED = 'onModelSelected',\r\n /**\r\n * 取消选中\r\n */\r\n UNSELECT = 'onUnselect',\r\n /**\r\n * 模型位移旋转缩放时派发,事件参数会返回模型名、具体操作、数值\r\n */\r\n // MODEL_TRANSFORM = 'onModelTransform',\r\n}\r\nObject3D.DefaultUp = new Vector3(0, 0, 1)\r\nexport class Main extends EventDispatcher {\r\n version() {\r\n const pkg = require(\"../package.json\");\r\n return pkg.version;\r\n }\r\n private scene: Scene;\r\n private camera: PerspectiveCamera | OrthographicCamera;\r\n private renderer: WebGLRenderer\r\n private requestID: number;\r\n private orbit: OrbitControls;\r\n private igsGroup: Group;\r\n constructor(private container: HTMLDivElement, private option?: { isOrthographicCamera?: boolean }) {\r\n super();\r\n console.log(\r\n \"%cigs-view version:\" + this.version(),\r\n \"text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:3em\"\r\n )\r\n let width = container.clientWidth;\r\n let height = container.clientHeight;\r\n let renderer = this.renderer = new WebGLRenderer({ alpha: true, antialias: true, logarithmicDepthBuffer: true })\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.autoClear = true;\r\n renderer.localClippingEnabled = true;\r\n // renderer.setClearColor(0xf6f6f6);\r\n renderer.setSize(width, height);\r\n container.appendChild(renderer.domElement)\r\n let scene = this.scene = new Scene();\r\n this.igsGroup = new Group()\r\n scene.add(this.igsGroup)\r\n let camera: PerspectiveCamera | OrthographicCamera;\r\n if (option?.isOrthographicCamera) {\r\n const left = -width / 2 / 1;\r\n const right = width / 2 / 1;\r\n const top = height / 2 / 1;\r\n const bottom = -height / 2 / 1;\r\n camera = this.camera = new OrthographicCamera(\r\n left,\r\n right,\r\n top,\r\n bottom\r\n );\r\n camera.position.set(0, 0, 1000);\r\n const orbit = this.orbit = new OrbitControls(camera, renderer.domElement);\r\n orbit.enableRotate = false;\r\n } else {\r\n camera = this.camera = new PerspectiveCamera(\r\n 30,\r\n width / height,\r\n 0.0001,\r\n 100000\r\n );\r\n camera.position.set(1000, 1000, 1000);\r\n //相机控件\r\n const orbit = this.orbit = new OrbitControls(camera, renderer.domElement);\r\n orbit.maxDistance = 10000;\r\n // orbit.enableDamping = true;\r\n // orbit.dampingFactor = 0.005;\r\n }\r\n // var gridHelper = new GridHelper(100, 100, 0x888888, 0x888888);\r\n // gridHelper.rotation.x = Math.PI / 2;\r\n // scene.add(gridHelper);\r\n var axesHelper = new AxesHelper(100);\r\n scene.add(axesHelper);\r\n axesHelper.position.z = 0.001\r\n let self = this;\r\n loop();\r\n function loop() {\r\n renderer.render(scene, camera)\r\n // self.orbit?.update()\r\n self.requestID = requestAnimationFrame(loop)\r\n }\r\n\r\n //测试下分割\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(5, -10, 10)\r\n scene.add(pll)\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(0, 10, 0)\r\n scene.add(pll)\r\n scene.add(new AmbientLight(0xeeeeee, 0.05))\r\n\r\n //\r\n let resize = this.resize = () => {\r\n if (!this.renderer) return;\r\n const w = container.clientWidth;\r\n const h = container.clientHeight;\r\n // this.resize(w, h);\r\n this.renderer?.setSize(w, h);\r\n if (option?.isOrthographicCamera) {\r\n let orthographicCamera = camera as OrthographicCamera\r\n let zoom = 1//orthographicCamera.zoom;\r\n // console.log(zoom)\r\n const left = -w / 2 / zoom;\r\n const right = w / 2 / zoom;\r\n const top = h / 2 / zoom;\r\n const bottom = -h / 2 / zoom;\r\n orthographicCamera.left = left;\r\n orthographicCamera.right = right;\r\n orthographicCamera.top = top;\r\n orthographicCamera.bottom = bottom;\r\n // console.log(zoom)\r\n } else {\r\n (camera as PerspectiveCamera).aspect = w / h;\r\n }\r\n camera.updateProjectionMatrix();\r\n }\r\n window.addEventListener('resize', resize);\r\n this.addMouseEvent();\r\n }\r\n /**\r\n * 显示容器发生变化时调用\r\n */\r\n resize: () => void;\r\n private defaultMeshMaterial = new MeshStandardMaterial({ side: 0, clipIntersection: true });\r\n private defaultMeshMaterial_selected = new MeshBasicMaterial({ side: 0, clipIntersection: true, color: new Color(0xff0000) });\r\n private entities: IEntity[];\r\n async loadIgs(src: string) {\r\n let json: any = await fetch(src)\r\n .then((res) => res.text())\r\n .then((res) => JSON.parse(res))\r\n const Entities: IEntity[] = json.Data.Metadata.Entities\r\n this.parseIgs(Entities)\r\n }\r\n private map: { points: number[], height: number }[] = [];\r\n private box: Box3 = new Box3;\r\n parseIgs(entities: IEntity[]) {\r\n this.box.makeEmpty();\r\n this.map.length = 0;\r\n this.entities = entities;\r\n entities.forEach(({ Triangles, Vertices, Id }) => {\r\n // console.log(Triangles, Vertices)\r\n // ========== 创建BufferGeometry ==========\r\n const geometry = new BufferGeometry();\r\n\r\n // 顶点位置数组\r\n const positions = new Float32Array(Vertices.length * 3);\r\n Vertices.forEach((vert, i) => {\r\n positions[i * 3] = vert.X;\r\n positions[i * 3 + 1] = vert.Y;\r\n positions[i * 3 + 2] = vert.Z;\r\n });\r\n // 三角形索引数组\r\n const indices = [];\r\n Triangles.forEach(({ VertexIndex1, VertexIndex2, VertexIndex3 }) => {\r\n indices.push(VertexIndex1, VertexIndex2, VertexIndex3);\r\n let p1 = [\r\n positions[VertexIndex1 * 3],\r\n positions[VertexIndex1 * 3 + 1],\r\n positions[VertexIndex1 * 3 + 2]\r\n ]\r\n let p2 = [\r\n positions[VertexIndex2 * 3],\r\n positions[VertexIndex2 * 3 + 1],\r\n positions[VertexIndex2 * 3 + 2]\r\n ]\r\n let p3 = [\r\n positions[VertexIndex3 * 3],\r\n positions[VertexIndex3 * 3 + 1],\r\n positions[VertexIndex3 * 3 + 2]\r\n ]\r\n //如果面与z轴平行,跳过\r\n const triangle = new Triangle(\r\n new Vector3(...p1),\r\n new Vector3(...p2),\r\n new Vector3(...p3)\r\n );\r\n const tolerance = 0.0001;\r\n if (Math.abs(triangle.getNormal(new Vector3).z) < tolerance) {\r\n return\r\n }\r\n this.map.push({\r\n height: (p1[2] + p2[2] + p3[2]) / 3,\r\n points: [\r\n p1[0], p1[1],\r\n p2[0], p2[1],\r\n p3[0], p3[1],\r\n ]\r\n })\r\n });\r\n\r\n // 设置几何体属性\r\n geometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n geometry.setIndex(indices);\r\n\r\n // 计算法线(用于光照)\r\n geometry.computeVertexNormals();\r\n\r\n geometry.computeBoundingBox()\r\n this.box.union(geometry.boundingBox)\r\n // ========== 创建网格 ==========\r\n const mesh = new Mesh(geometry, this.defaultMeshMaterial);\r\n mesh.uuid = Id + \"\"\r\n this.igsGroup.add(mesh);\r\n })\r\n }\r\n clearIgs() {\r\n this.igsGroup.clear();\r\n }\r\n private pading = 10;\r\n private scale = 10;\r\n private rotateX: number = 0;\r\n private rotateY: number = 0;\r\n verticalView() {\r\n if (!this.igsGroup.children.length) return null;\r\n if (this.igsGroup.rotation.x == 0 && this.igsGroup.rotation.y == 0) {\r\n let canvas = document.createElement(\"canvas\")\r\n let originX = (this.pading - this.box.min.x) * this.scale;\r\n let originY = (this.pading - this.box.min.y) * this.scale;\r\n let vec = this.box.getSize(new Vector3);\r\n canvas.width = (vec.x + this.pading * 2) * this.scale;\r\n canvas.height = (vec.y + this.pading * 2) * this.scale;\r\n let ctx = canvas.getContext(\"2d\")\r\n ctx.fillStyle = \"#ffffff\"\r\n ctx.fillRect(0, 0, canvas.width, canvas.height)\r\n ctx.setTransform(this.scale, 0, 0, this.scale, originX, originY)\r\n this.map.sort((a, b) => a.height - b.height);\r\n let max = this.map[this.map.length - 1].height;\r\n // console.log(this.map)\r\n this.map.forEach(({ height, points }, index) => {\r\n let grey = (max - height) / max * 200\r\n ctx.fillStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;\r\n ctx.strokeStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;\r\n ctx.lineWidth = 1 / this.scale\r\n ctx.lineCap = \"round\";\r\n ctx.lineJoin = \"round\"\r\n ctx.beginPath()\r\n for (let i = 0; i < points.length; i += 2) {\r\n if (i == 0) {\r\n ctx.moveTo(points[i], points[i + 1])\r\n } else {\r\n ctx.lineTo(points[i], points[i + 1])\r\n }\r\n }\r\n ctx.closePath();\r\n ctx.fill();\r\n ctx.stroke();\r\n })\r\n // document.body.appendChild(canvas);\r\n return {\r\n x: originX,\r\n y: originY,\r\n scale: this.scale,\r\n base64: canvas.toDataURL(\"image/jpeg\", 0.8)\r\n }\r\n } else {\r\n //带旋转\r\n }\r\n }\r\n private raycaster: Raycaster;\r\n private onUpPosition = new Vector2(-1, -1); //\t用于判断点击事件位置\r\n private onDownPosition = new Vector2(-1, -1); //\t同上\r\n private selected: Mesh;\r\n private addMouseEvent() {\r\n this.raycaster = new Raycaster();\r\n const { container } = this;\r\n container.addEventListener('pointerdown', (event: PointerEvent) => {\r\n this.onDownPosition.x = event.offsetX;\r\n this.onDownPosition.y = event.offsetY;\r\n });\r\n // container.addEventListener('pointermove', (event: PointerEvent) => {\r\n // this.hittest(event)\r\n // });\r\n container.addEventListener('pointerup', (event: PointerEvent) => {\r\n this.onUpPosition.x = event.offsetX;\r\n this.onUpPosition.y = event.offsetY;\r\n //\t单击有效(点击的位置已经不同,就直接返回了)\r\n if (this.onDownPosition.distanceTo(this.onUpPosition) > 20) {\r\n return;\r\n }\r\n const clientWidth = this.container.clientWidth;\r\n const clientHeight = this.container.clientHeight;\r\n const { camera, raycaster } = this\r\n\r\n // console.log(clientWidth,clientHeight)\r\n let models: Mesh[] = this.igsGroup.children.slice() as Mesh[]\r\n let x = (event.offsetX / clientWidth) * 2 - 1;\r\n let y = -(event.offsetY / clientHeight) * 2 + 1;\r\n raycaster.setFromCamera(new Vector3(x, y, 0.5), camera);\r\n //只需要距离最近的那个就行\r\n let picks = this.raycaster.intersectObjects(models, true);\r\n if (picks[0]?.object) {\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = picks[0].object as Mesh\r\n this.selected.material = this.defaultMeshMaterial_selected;\r\n //派发个事件出去,TODO,选中了,数据带上uuid\r\n this.dispatchEvent({\r\n type: OutEventTypes.MODEL_SELECTED,\r\n // id: this.selected.id,\r\n uuid: this.selected.uuid,\r\n });\r\n } else {\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = null;\r\n this.dispatchEvent({ type: OutEventTypes.UNSELECT });\r\n }\r\n });\r\n\r\n }\r\n selectedByUuid(uuid: string) {\r\n let mesh = this.igsGroup.children.find((m: Mesh) => {\r\n return m.uuid == uuid\r\n }) as Mesh\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = mesh\r\n this.selected.material = this.defaultMeshMaterial_selected;\r\n }\r\n private transformControls: TransformControls\r\n /**\r\n * @description: 添加变换控制器\r\n * @return {*}\r\n * @author: shanbian\r\n */\r\n addTransformControls() {\r\n // 添加变换控制器\r\n this.transformControls = new TransformControls(\r\n this.camera,\r\n this.renderer.domElement\r\n );\r\n this.scene.add(this.transformControls);\r\n // 选中父类为需要控制的物体\r\n this.transformControls.attach(this.igsGroup);\r\n this.transformControls.mode = 'rotate';\r\n this.transformControls.showZ = false;\r\n this.transformControls.showX = this.transformControls.showY = true;\r\n // 如果指针(鼠标/触摸)为活动状态则触发该事件。\r\n this.transformControls.addEventListener('mouseDown', () => {\r\n this.orbit.enabled = false;\r\n });\r\n // 如果指针(鼠标/触摸)不再为活动状态则触发该事件。\r\n this.transformControls.addEventListener('mouseUp', () => {\r\n this.orbit.enabled = true;\r\n });\r\n // 如果被控制的3D对象发生改变则触发该事件。\r\n this.transformControls.addEventListener('objectChange', () => {\r\n // // 更新Box3Helper\r\n // if (this.modelsSystem.getSelectedModelInfo()) {\r\n // const { uuid } = this.modelsSystem.getSelectedModelInfo();\r\n // this.modelsSystem.updateBox3Helper(uuid);\r\n // }\r\n // 渲染界面\r\n });\r\n // 通过按键控制 transformControls的mode\r\n document.addEventListener('keydown', (event) => {\r\n if (event.repeat) {\r\n return false;\r\n }\r\n // console.log(event);\r\n // if (event.key === 'e') {\r\n // this.transformControls.mode = 'scale';\r\n // return false;\r\n // }\r\n\r\n // if (event.key === 'r') {\r\n // this.transformControls.mode = 'rotate';\r\n // this.transformControls.showZ = true;\r\n // this.transformControls.showX = this.transformControls.showY = false;\r\n // return false;\r\n // }\r\n\r\n // if (event.key === 't') {\r\n // this.transformControls.mode = 'translate';\r\n // this.transformControls.showZ = false;\r\n // this.transformControls.showX = this.transformControls.showY = true;\r\n // return false;\r\n // }\r\n });\r\n }\r\n removeTransformControls() {\r\n this.scene.remove(this.transformControls);\r\n // 选中父类为需要控制的物体\r\n this.transformControls.detach();\r\n }\r\n}\r\n\r\n\r\ninterface IEntity {\r\n Triangles: {\r\n \"VertexIndex1\": number,\r\n \"VertexIndex2\": number,\r\n \"VertexIndex3\": number\r\n }[],\r\n Vertices: {\r\n \"X\": number,\r\n \"Y\": number,\r\n \"Z\": number\r\n }[],\r\n Id: number\r\n}","module.exports = __WEBPACK_EXTERNAL_MODULE_three__;"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///./node_modules/.pnpm/three@0.139.2/node_modules/three/examples/jsm/controls/OrbitControls.js","webpack:///./node_modules/.pnpm/three@0.139.2/node_modules/three/examples/jsm/controls/TransformControls.js","webpack:///./src/Main.ts","webpack:///external \"three\""],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;QCVA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;;AClFA;AAAA;AAAA;AAAA;AAAA;AAQe;;AAEf;AACA;AACA;AACA;AACA;AACA;;AAEA,sBAAsB;AACtB,qBAAqB;AACrB,mBAAmB;;AAEnB,4BAA4B,qDAAe;;AAE3C;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,6CAA6C;;AAE7C;AACA;;AAEA;AACA,oBAAoB,6CAAO;;AAE3B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,yBAAyB;AACzB,+BAA+B;;AAE/B;AACA;AACA,oCAAoC;AACpC,kCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,sDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,iCAAiC;AACjC,yBAAyB;;AAEzB;AACA;AACA;AACA,6BAA6B;;AAE7B;AACA,eAAe;;AAEf;AACA,uBAAuB,OAAO,2CAAK,iBAAiB,2CAAK,eAAe,2CAAK;;AAE7E;AACA,kBAAkB,MAAM,2CAAK,cAAc,2CAAK;;AAEhD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,sBAAsB,6CAAO;;AAE7B;AACA,oBAAoB,gDAAU,sCAAsC,6CAAO;AAC3E;;AAEA,4BAA4B,6CAAO;AACnC,8BAA8B,gDAAU;;AAExC;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,yCAAyC;;AAEzC,yCAAyC;;AAEzC;;AAEA;;AAEA,MAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA,2BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,wBAAwB,+CAAS;AACjC,6BAA6B,+CAAS;;AAEtC;AACA,wBAAwB,6CAAO;AAC/B;;AAEA,0BAA0B,6CAAO;AACjC,wBAAwB,6CAAO;AAC/B,0BAA0B,6CAAO;;AAEjC,uBAAuB,6CAAO;AAC9B,qBAAqB,6CAAO;AAC5B,uBAAuB,6CAAO;;AAE9B,yBAAyB,6CAAO;AAChC,uBAAuB,6CAAO;AAC9B,yBAAyB,6CAAO;;AAEhC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAiB,6CAAO;;AAExB;;AAEA,6CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA,iBAAiB,6CAAO;;AAExB;;AAEA;;AAEA;;AAEA,KAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH,qCAAqC;AACrC;;AAEA,sBAAsB,6CAAO;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,KAAK;;AAEL;AACA;AACA;;AAEA,KAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;AACA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;AACA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oEAAoE;;AAEpE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oEAAoE;;AAEpE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,SAAS,2CAAK;;AAEd;;AAEA;;AAEA;;AAEA;;AAEA,SAAS,2CAAK;;AAEd;;AAEA;;AAEA;;AAEA;;AAEA,MAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,SAAS,2CAAK;;AAEd;;AAEA;;AAEA;;AAEA;;AAEA,MAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,WAAW,2CAAK;;AAEhB;;AAEA;;AAEA;;AAEA;;AAEA,WAAW,2CAAK;;AAEhB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,WAAW,2CAAK;;AAEhB;;AAEA;;AAEA;;AAEA;;AAEA,WAAW,2CAAK;;AAEhB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAmB,qBAAqB;;AAExC;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAmB,6CAAO;AAC1B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA,6DAA6D,iBAAiB;;AAE9E;;AAEA;;AAEA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAkC;;AAElC,2BAA2B,2CAAK;AAChC,4BAA4B,2CAAK;;AAEjC,qBAAqB,2CAAK;AAC1B,qBAAqB,2CAAK;;AAE1B;;AAEA;;AAEsC;;;;;;;;;;;;;ACnuCtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBe;;AAEf,uBAAuB,+CAAS;;AAEhC,wBAAwB,6CAAO;AAC/B,yBAAyB,6CAAO;AAChC,4BAA4B,gDAAU;AACtC;AACA,QAAQ,6CAAO;AACf,QAAQ,6CAAO;AACf,QAAQ,6CAAO;AACf;;AAEA,sBAAsB;AACtB,yBAAyB;AACzB,uBAAuB;AACvB,4BAA4B;;AAE5B,gCAAgC,8CAAQ;;AAExC;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,6CAA6C;;AAE7C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,4BAA4B,4CAA4C;AACxE;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,4BAA4B,6CAAO;AACnC,iCAAiC,6CAAO;AACxC,8BAA8B,gDAAU;AACxC,mCAAmC,gDAAU;AAC7C,6BAA6B,6CAAO;AACpC,+BAA+B,gDAAU;AACzC,yBAAyB,6CAAO;AAChC,uBAAuB,6CAAO;AAC9B,2BAA2B,6CAAO;AAClC;AACA,kBAAkB,6CAAO;;AAEzB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,6CAAO;AAC5B,wBAAwB,6CAAO;AAC/B,sBAAsB,6CAAO;AAC7B,0BAA0B,6CAAO;;AAEjC,6BAA6B,6CAAO;AACpC,+BAA+B,gDAAU;AACzC,kCAAkC,gDAAU;AAC5C,0BAA0B,6CAAO;;AAEjC,8BAA8B,6CAAO;AACrC,iCAAiC,gDAAU;AAC3C,yBAAyB,6CAAO;;AAEhC,4BAA4B,6CAAO;AACnC,8BAA8B,gDAAU;AACxC,yBAAyB,6CAAO;;AAEhC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAI;;AAEJ;AACA;;AAEA,IAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,EAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AA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","file":"main.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"three\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"three\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"three\")) : factory(root[\"three\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(window, function(__WEBPACK_EXTERNAL_MODULE_three__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/Main.ts\");\n","import {\n\tEventDispatcher,\n\tMOUSE,\n\tQuaternion,\n\tSpherical,\n\tTOUCH,\n\tVector2,\n\tVector3\n} from 'three';\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one-finger move\n// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move\n\nconst _changeEvent = { type: 'change' };\nconst _startEvent = { type: 'start' };\nconst _endEvent = { type: 'end' };\n\nclass OrbitControls extends EventDispatcher {\n\n\tconstructor( object, domElement ) {\n\n\t\tsuper();\n\n\t\tif ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter \"domElement\" is now mandatory.' );\n\t\tif ( domElement === document ) console.error( 'THREE.OrbitControls: \"document\" should not be used as the target \"domElement\". Please use \"renderer.domElement\" instead.' );\n\n\t\tthis.object = object;\n\t\tthis.domElement = domElement;\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.05;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.panSpeed = 1.0;\n\t\tthis.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 'ArrowLeft', UP: 'ArrowUp', RIGHT: 'ArrowRight', BOTTOM: 'ArrowDown' };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n\t\t// Touch fingers\n\t\tthis.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t// the target DOM element for key events\n\t\tthis._domElementKeyEvents = null;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.getDistance = function () {\n\n\t\t\treturn this.object.position.distanceTo( this.target );\n\n\t\t};\n\n\t\tthis.listenToKeyEvents = function ( domElement ) {\n\n\t\t\tdomElement.addEventListener( 'keydown', onKeyDown );\n\t\t\tthis._domElementKeyEvents = domElement;\n\n\t\t};\n\n\t\tthis.saveState = function () {\n\n\t\t\tscope.target0.copy( scope.target );\n\t\t\tscope.position0.copy( scope.object.position );\n\t\t\tscope.zoom0 = scope.object.zoom;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function () {\n\n\t\t\tconst offset = new Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tconst quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\n\t\t\tconst quatInverse = quat.clone().invert();\n\n\t\t\tconst lastPosition = new Vector3();\n\t\t\tconst lastQuaternion = new Quaternion();\n\n\t\t\tconst twoPI = 2 * Math.PI;\n\n\t\t\treturn function update() {\n\n\t\t\t\tconst position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tif ( scope.enableDamping ) {\n\n\t\t\t\t\tspherical.theta += sphericalDelta.theta * scope.dampingFactor;\n\t\t\t\t\tspherical.phi += sphericalDelta.phi * scope.dampingFactor;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t}\n\n\t\t\t\t// restrict theta to be between desired limits\n\n\t\t\t\tlet min = scope.minAzimuthAngle;\n\t\t\t\tlet max = scope.maxAzimuthAngle;\n\n\t\t\t\tif ( isFinite( min ) && isFinite( max ) ) {\n\n\t\t\t\t\tif ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;\n\n\t\t\t\t\tif ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;\n\n\t\t\t\t\tif ( min <= max ) {\n\n\t\t\t\t\t\tspherical.theta = Math.max( min, Math.min( max, spherical.theta ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tspherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?\n\t\t\t\t\t\t\tMath.max( min, spherical.theta ) :\n\t\t\t\t\t\t\tMath.min( max, spherical.theta );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tscope.target.addScaledVector( panOffset, scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\t}\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t\tpanOffset.multiplyScalar( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function () {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu );\n\n\t\t\tscope.domElement.removeEventListener( 'pointerdown', onPointerDown );\n\t\t\tscope.domElement.removeEventListener( 'pointercancel', onPointerCancel );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel );\n\n\t\t\tscope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t\tscope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\n\t\t\tif ( scope._domElementKeyEvents !== null ) {\n\n\t\t\t\tscope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );\n\n\t\t\t}\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tconst scope = this;\n\n\t\tconst STATE = {\n\t\t\tNONE: - 1,\n\t\t\tROTATE: 0,\n\t\t\tDOLLY: 1,\n\t\t\tPAN: 2,\n\t\t\tTOUCH_ROTATE: 3,\n\t\t\tTOUCH_PAN: 4,\n\t\t\tTOUCH_DOLLY_PAN: 5,\n\t\t\tTOUCH_DOLLY_ROTATE: 6\n\t\t};\n\n\t\tlet state = STATE.NONE;\n\n\t\tconst EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tconst spherical = new Spherical();\n\t\tconst sphericalDelta = new Spherical();\n\n\t\tlet scale = 1;\n\t\tconst panOffset = new Vector3();\n\t\tlet zoomChanged = false;\n\n\t\tconst rotateStart = new Vector2();\n\t\tconst rotateEnd = new Vector2();\n\t\tconst rotateDelta = new Vector2();\n\n\t\tconst panStart = new Vector2();\n\t\tconst panEnd = new Vector2();\n\t\tconst panDelta = new Vector2();\n\n\t\tconst dollyStart = new Vector2();\n\t\tconst dollyEnd = new Vector2();\n\t\tconst dollyDelta = new Vector2();\n\n\t\tconst pointers = [];\n\t\tconst pointerPositions = {};\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tconst panLeft = function () {\n\n\t\t\tconst v = new Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tconst panUp = function () {\n\n\t\t\tconst v = new Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tif ( scope.screenSpacePanning === true ) {\n\n\t\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 );\n\t\t\t\t\tv.crossVectors( scope.object.up, v );\n\n\t\t\t\t}\n\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tconst pan = function () {\n\n\t\t\tconst offset = new Vector3();\n\n\t\t\treturn function pan( deltaX, deltaY ) {\n\n\t\t\t\tconst element = scope.domElement;\n\n\t\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tconst position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tlet targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we use only clientHeight here so aspect ratio does not distort speed\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n\t\t\tconst element = scope.domElement;\n\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\tlet needsUpdate = false;\n\n\t\t\tswitch ( event.code ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t// prevent the browser from scrolling on cursor keys\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tscope.update();\n\n\t\t\t}\n\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate() {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\trotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );\n\t\t\t\tconst y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );\n\n\t\t\t\trotateStart.set( x, y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartPan() {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\tpanStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );\n\t\t\t\tconst y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );\n\n\t\t\t\tpanStart.set( x, y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly() {\n\n\t\t\tconst dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX;\n\t\t\tconst dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY;\n\n\t\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartDollyPan() {\n\n\t\t\tif ( scope.enableZoom ) handleTouchStartDolly();\n\n\t\t\tif ( scope.enablePan ) handleTouchStartPan();\n\n\t\t}\n\n\t\tfunction handleTouchStartDollyRotate() {\n\n\t\t\tif ( scope.enableZoom ) handleTouchStartDolly();\n\n\t\t\tif ( scope.enableRotate ) handleTouchStartRotate();\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\tif ( pointers.length == 1 ) {\n\n\t\t\t\trotateEnd.set( event.pageX, event.pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\t\trotateEnd.set( x, y );\n\n\t\t\t}\n\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n\t\t\tconst element = scope.domElement;\n\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\tif ( pointers.length === 1 ) {\n\n\t\t\t\tpanEnd.set( event.pageX, event.pageY );\n\n\t\t\t} else {\n\n\t\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\t\tconst x = 0.5 * ( event.pageX + position.x );\n\t\t\t\tconst y = 0.5 * ( event.pageY + position.y );\n\n\t\t\t\tpanEnd.set( x, y );\n\n\t\t\t}\n\n\t\t\tpanDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\tconst position = getSecondPointerPosition( event );\n\n\t\t\tconst dx = event.pageX - position.x;\n\t\t\tconst dy = event.pageY - position.y;\n\n\t\t\tconst distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );\n\n\t\t\tdollyOut( dollyDelta.y );\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDollyPan( event ) {\n\n\t\t\tif ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n\t\t\tif ( scope.enablePan ) handleTouchMovePan( event );\n\n\t\t}\n\n\t\tfunction handleTouchMoveDollyRotate( event ) {\n\n\t\t\tif ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n\t\t\tif ( scope.enableRotate ) handleTouchMoveRotate( event );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onPointerDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tif ( pointers.length === 0 ) {\n\n\t\t\t\tscope.domElement.setPointerCapture( event.pointerId );\n\n\t\t\t\tscope.domElement.addEventListener( 'pointermove', onPointerMove );\n\t\t\t\tscope.domElement.addEventListener( 'pointerup', onPointerUp );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\taddPointer( event );\n\n\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\tonTouchStart( event );\n\n\t\t\t} else {\n\n\t\t\t\tonMouseDown( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onPointerMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\tonTouchMove( event );\n\n\t\t\t} else {\n\n\t\t\t\tonMouseMove( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onPointerUp( event ) {\n\n\t\t removePointer( event );\n\n\t\t if ( pointers.length === 0 ) {\n\n\t\t scope.domElement.releasePointerCapture( event.pointerId );\n\n\t\t scope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t scope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\t\t }\n\n\t\t scope.dispatchEvent( _endEvent );\n\n\t\t state = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onPointerCancel( event ) {\n\n\t\t\tremovePointer( event );\n\n\t\t}\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tlet mouseAction;\n\n\t\t\tswitch ( event.button ) {\n\n\t\t\t\tcase 0:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.LEFT;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 1:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.MIDDLE;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\n\n\t\t\t\t\tmouseAction = scope.mouseButtons.RIGHT;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tmouseAction = - 1;\n\n\t\t\t}\n\n\t\t\tswitch ( mouseAction ) {\n\n\t\t\t\tcase MOUSE.DOLLY:\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MOUSE.ROTATE:\n\n\t\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\t\t\tstate = STATE.PAN;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MOUSE.PAN:\n\n\t\t\t\t\tif ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\t\t\tstate = STATE.PAN;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( state ) {\n\n\t\t\t\tcase STATE.ROTATE:\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.DOLLY:\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.PAN:\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( _endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\ttrackPointer( event );\n\n\t\t\tswitch ( pointers.length ) {\n\n\t\t\t\tcase 1:\n\n\t\t\t\t\tswitch ( scope.touches.ONE ) {\n\n\t\t\t\t\t\tcase TOUCH.ROTATE:\n\n\t\t\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartRotate();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TOUCH.PAN:\n\n\t\t\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartPan();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\n\n\t\t\t\t\tswitch ( scope.touches.TWO ) {\n\n\t\t\t\t\t\tcase TOUCH.DOLLY_PAN:\n\n\t\t\t\t\t\t\tif ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartDollyPan();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_DOLLY_PAN;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TOUCH.DOLLY_ROTATE:\n\n\t\t\t\t\t\t\tif ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n\t\t\t\t\t\t\thandleTouchStartDollyRotate();\n\n\t\t\t\t\t\t\tstate = STATE.TOUCH_DOLLY_ROTATE;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\ttrackPointer( event );\n\n\t\t\tswitch ( state ) {\n\n\t\t\t\tcase STATE.TOUCH_ROTATE:\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_PAN:\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_DOLLY_PAN:\n\n\t\t\t\t\tif ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchMoveDollyPan( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase STATE.TOUCH_DOLLY_ROTATE:\n\n\t\t\t\t\tif ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchMoveDollyRotate( event );\n\n\t\t\t\t\tscope.update();\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\tfunction addPointer( event ) {\n\n\t\t\tpointers.push( event );\n\n\t\t}\n\n\t\tfunction removePointer( event ) {\n\n\t\t\tdelete pointerPositions[ event.pointerId ];\n\n\t\t\tfor ( let i = 0; i < pointers.length; i ++ ) {\n\n\t\t\t\tif ( pointers[ i ].pointerId == event.pointerId ) {\n\n\t\t\t\t\tpointers.splice( i, 1 );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction trackPointer( event ) {\n\n\t\t\tlet position = pointerPositions[ event.pointerId ];\n\n\t\t\tif ( position === undefined ) {\n\n\t\t\t\tposition = new Vector2();\n\t\t\t\tpointerPositions[ event.pointerId ] = position;\n\n\t\t\t}\n\n\t\t\tposition.set( event.pageX, event.pageY );\n\n\t\t}\n\n\t\tfunction getSecondPointerPosition( event ) {\n\n\t\t\tconst pointer = ( event.pointerId === pointers[ 0 ].pointerId ) ? pointers[ 1 ] : pointers[ 0 ];\n\n\t\t\treturn pointerPositions[ pointer.pointerId ];\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu );\n\n\t\tscope.domElement.addEventListener( 'pointerdown', onPointerDown );\n\t\tscope.domElement.addEventListener( 'pointercancel', onPointerCancel );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t}\n\n}\n\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n// This is very similar to OrbitControls, another set of touch behavior\n//\n// Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate\n// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n// Pan - left mouse, or arrow keys / touch: one-finger move\n\nclass MapControls extends OrbitControls {\n\n\tconstructor( object, domElement ) {\n\n\t\tsuper( object, domElement );\n\n\t\tthis.screenSpacePanning = false; // pan orthogonal to world-space direction camera.up\n\n\t\tthis.mouseButtons.LEFT = MOUSE.PAN;\n\t\tthis.mouseButtons.RIGHT = MOUSE.ROTATE;\n\n\t\tthis.touches.ONE = TOUCH.PAN;\n\t\tthis.touches.TWO = TOUCH.DOLLY_ROTATE;\n\n\t}\n\n}\n\nexport { OrbitControls, MapControls };\n","import {\n\tBoxGeometry,\n\tBufferGeometry,\n\tCylinderGeometry,\n\tDoubleSide,\n\tEuler,\n\tFloat32BufferAttribute,\n\tLine,\n\tLineBasicMaterial,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tOctahedronGeometry,\n\tPlaneGeometry,\n\tQuaternion,\n\tRaycaster,\n\tSphereGeometry,\n\tTorusGeometry,\n\tVector3\n} from 'three';\n\nconst _raycaster = new Raycaster();\n\nconst _tempVector = new Vector3();\nconst _tempVector2 = new Vector3();\nconst _tempQuaternion = new Quaternion();\nconst _unit = {\n\tX: new Vector3( 1, 0, 0 ),\n\tY: new Vector3( 0, 1, 0 ),\n\tZ: new Vector3( 0, 0, 1 )\n};\n\nconst _changeEvent = { type: 'change' };\nconst _mouseDownEvent = { type: 'mouseDown' };\nconst _mouseUpEvent = { type: 'mouseUp', mode: null };\nconst _objectChangeEvent = { type: 'objectChange' };\n\nclass TransformControls extends Object3D {\n\n\tconstructor( camera, domElement ) {\n\n\t\tsuper();\n\n\t\tif ( domElement === undefined ) {\n\n\t\t\tconsole.warn( 'THREE.TransformControls: The second parameter \"domElement\" is now mandatory.' );\n\t\t\tdomElement = document;\n\n\t\t}\n\n\t\tthis.visible = false;\n\t\tthis.domElement = domElement;\n\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\n\t\tconst _gizmo = new TransformControlsGizmo();\n\t\tthis._gizmo = _gizmo;\n\t\tthis.add( _gizmo );\n\n\t\tconst _plane = new TransformControlsPlane();\n\t\tthis._plane = _plane;\n\t\tthis.add( _plane );\n\n\t\tconst scope = this;\n\n\t\t// Defined getter, setter and store for a property\n\t\tfunction defineProperty( propName, defaultValue ) {\n\n\t\t\tlet propValue = defaultValue;\n\n\t\t\tObject.defineProperty( scope, propName, {\n\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn propValue !== undefined ? propValue : defaultValue;\n\n\t\t\t\t},\n\n\t\t\t\tset: function ( value ) {\n\n\t\t\t\t\tif ( propValue !== value ) {\n\n\t\t\t\t\t\tpropValue = value;\n\t\t\t\t\t\t_plane[ propName ] = value;\n\t\t\t\t\t\t_gizmo[ propName ] = value;\n\n\t\t\t\t\t\tscope.dispatchEvent( { type: propName + '-changed', value: value } );\n\t\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tscope[ propName ] = defaultValue;\n\t\t\t_plane[ propName ] = defaultValue;\n\t\t\t_gizmo[ propName ] = defaultValue;\n\n\t\t}\n\n\t\t// Define properties with getters/setter\n\t\t// Setting the defined property will automatically trigger change event\n\t\t// Defined properties are passed down to gizmo and plane\n\n\t\tdefineProperty( 'camera', camera );\n\t\tdefineProperty( 'object', undefined );\n\t\tdefineProperty( 'enabled', true );\n\t\tdefineProperty( 'axis', null );\n\t\tdefineProperty( 'mode', 'translate' );\n\t\tdefineProperty( 'translationSnap', null );\n\t\tdefineProperty( 'rotationSnap', null );\n\t\tdefineProperty( 'scaleSnap', null );\n\t\tdefineProperty( 'space', 'world' );\n\t\tdefineProperty( 'size', 1 );\n\t\tdefineProperty( 'dragging', false );\n\t\tdefineProperty( 'showX', true );\n\t\tdefineProperty( 'showY', true );\n\t\tdefineProperty( 'showZ', true );\n\n\t\t// Reusable utility variables\n\n\t\tconst worldPosition = new Vector3();\n\t\tconst worldPositionStart = new Vector3();\n\t\tconst worldQuaternion = new Quaternion();\n\t\tconst worldQuaternionStart = new Quaternion();\n\t\tconst cameraPosition = new Vector3();\n\t\tconst cameraQuaternion = new Quaternion();\n\t\tconst pointStart = new Vector3();\n\t\tconst pointEnd = new Vector3();\n\t\tconst rotationAxis = new Vector3();\n\t\tconst rotationAngle = 0;\n\t\tconst eye = new Vector3();\n\n\t\t// TODO: remove properties unused in plane and gizmo\n\n\t\tdefineProperty( 'worldPosition', worldPosition );\n\t\tdefineProperty( 'worldPositionStart', worldPositionStart );\n\t\tdefineProperty( 'worldQuaternion', worldQuaternion );\n\t\tdefineProperty( 'worldQuaternionStart', worldQuaternionStart );\n\t\tdefineProperty( 'cameraPosition', cameraPosition );\n\t\tdefineProperty( 'cameraQuaternion', cameraQuaternion );\n\t\tdefineProperty( 'pointStart', pointStart );\n\t\tdefineProperty( 'pointEnd', pointEnd );\n\t\tdefineProperty( 'rotationAxis', rotationAxis );\n\t\tdefineProperty( 'rotationAngle', rotationAngle );\n\t\tdefineProperty( 'eye', eye );\n\n\t\tthis._offset = new Vector3();\n\t\tthis._startNorm = new Vector3();\n\t\tthis._endNorm = new Vector3();\n\t\tthis._cameraScale = new Vector3();\n\n\t\tthis._parentPosition = new Vector3();\n\t\tthis._parentQuaternion = new Quaternion();\n\t\tthis._parentQuaternionInv = new Quaternion();\n\t\tthis._parentScale = new Vector3();\n\n\t\tthis._worldScaleStart = new Vector3();\n\t\tthis._worldQuaternionInv = new Quaternion();\n\t\tthis._worldScale = new Vector3();\n\n\t\tthis._positionStart = new Vector3();\n\t\tthis._quaternionStart = new Quaternion();\n\t\tthis._scaleStart = new Vector3();\n\n\t\tthis._getPointer = getPointer.bind( this );\n\t\tthis._onPointerDown = onPointerDown.bind( this );\n\t\tthis._onPointerHover = onPointerHover.bind( this );\n\t\tthis._onPointerMove = onPointerMove.bind( this );\n\t\tthis._onPointerUp = onPointerUp.bind( this );\n\n\t\tthis.domElement.addEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.addEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.addEventListener( 'pointerup', this._onPointerUp );\n\n\t}\n\n\t// updateMatrixWorld updates key transformation variables\n\tupdateMatrixWorld() {\n\n\t\tif ( this.object !== undefined ) {\n\n\t\t\tthis.object.updateMatrixWorld();\n\n\t\t\tif ( this.object.parent === null ) {\n\n\t\t\t\tconsole.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );\n\n\t\t\t} else {\n\n\t\t\t\tthis.object.parent.matrixWorld.decompose( this._parentPosition, this._parentQuaternion, this._parentScale );\n\n\t\t\t}\n\n\t\t\tthis.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );\n\n\t\t\tthis._parentQuaternionInv.copy( this._parentQuaternion ).invert();\n\t\t\tthis._worldQuaternionInv.copy( this.worldQuaternion ).invert();\n\n\t\t}\n\n\t\tthis.camera.updateMatrixWorld();\n\t\tthis.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );\n\n\t\tthis.eye.copy( this.cameraPosition ).sub( this.worldPosition ).normalize();\n\n\t\tsuper.updateMatrixWorld( this );\n\n\t}\n\n\tpointerHover( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true ) return;\n\n\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );\n\n\t\tif ( intersect ) {\n\n\t\t\tthis.axis = intersect.object.name;\n\n\t\t} else {\n\n\t\t\tthis.axis = null;\n\n\t\t}\n\n\t}\n\n\tpointerDown( pointer ) {\n\n\t\tif ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;\n\n\t\tif ( this.axis !== null ) {\n\n\t\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\t\tif ( planeIntersect ) {\n\n\t\t\t\tthis.object.updateMatrixWorld();\n\t\t\t\tthis.object.parent.updateMatrixWorld();\n\n\t\t\t\tthis._positionStart.copy( this.object.position );\n\t\t\t\tthis._quaternionStart.copy( this.object.quaternion );\n\t\t\t\tthis._scaleStart.copy( this.object.scale );\n\n\t\t\t\tthis.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );\n\n\t\t\t\tthis.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\t\t}\n\n\t\t\tthis.dragging = true;\n\t\t\t_mouseDownEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseDownEvent );\n\n\t\t}\n\n\t}\n\n\tpointerMove( pointer ) {\n\n\t\tconst axis = this.axis;\n\t\tconst mode = this.mode;\n\t\tconst object = this.object;\n\t\tlet space = this.space;\n\n\t\tif ( mode === 'scale' ) {\n\n\t\t\tspace = 'local';\n\n\t\t} else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) {\n\n\t\t\tspace = 'world';\n\n\t\t}\n\n\t\tif ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;\n\n\t\t_raycaster.setFromCamera( pointer, this.camera );\n\n\t\tconst planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );\n\n\t\tif ( ! planeIntersect ) return;\n\n\t\tthis.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );\n\n\t\tif ( mode === 'translate' ) {\n\n\t\t\t// Apply translate\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t}\n\n\t\t\tif ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;\n\t\t\tif ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;\n\t\t\tif ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;\n\n\t\t\tif ( space === 'local' && axis !== 'XYZ' ) {\n\n\t\t\t\tthis._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );\n\n\t\t\t} else {\n\n\t\t\t\tthis._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale );\n\n\t\t\t}\n\n\t\t\tobject.position.copy( this._offset ).add( this._positionStart );\n\n\t\t\t// Apply translation snap\n\n\t\t\tif ( this.translationSnap ) {\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\tobject.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.position.applyQuaternion( this._quaternionStart );\n\n\t\t\t\t}\n\n\t\t\t\tif ( space === 'world' ) {\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\t\tobject.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.parent ) {\n\n\t\t\t\t\t\tobject.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( mode === 'scale' ) {\n\n\t\t\tif ( axis.search( 'XYZ' ) !== - 1 ) {\n\n\t\t\t\tlet d = this.pointEnd.length() / this.pointStart.length();\n\n\t\t\t\tif ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;\n\n\t\t\t\t_tempVector2.set( d, d, d );\n\n\t\t\t} else {\n\n\t\t\t\t_tempVector.copy( this.pointStart );\n\t\t\t\t_tempVector2.copy( this.pointEnd );\n\n\t\t\t\t_tempVector.applyQuaternion( this._worldQuaternionInv );\n\t\t\t\t_tempVector2.applyQuaternion( this._worldQuaternionInv );\n\n\t\t\t\t_tempVector2.divide( _tempVector );\n\n\t\t\t\tif ( axis.search( 'X' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.x = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.y = 1;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) === - 1 ) {\n\n\t\t\t\t\t_tempVector2.z = 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Apply scale\n\n\t\t\tobject.scale.copy( this._scaleStart ).multiply( _tempVector2 );\n\n\t\t\tif ( this.scaleSnap ) {\n\n\t\t\t\tif ( axis.search( 'X' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Y' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t\tif ( axis.search( 'Z' ) !== - 1 ) {\n\n\t\t\t\t\tobject.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( mode === 'rotate' ) {\n\n\t\t\tthis._offset.copy( this.pointEnd ).sub( this.pointStart );\n\n\t\t\tconst ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );\n\n\t\t\tif ( axis === 'E' ) {\n\n\t\t\t\tthis.rotationAxis.copy( this.eye );\n\t\t\t\tthis.rotationAngle = this.pointEnd.angleTo( this.pointStart );\n\n\t\t\t\tthis._startNorm.copy( this.pointStart ).normalize();\n\t\t\t\tthis._endNorm.copy( this.pointEnd ).normalize();\n\n\t\t\t\tthis.rotationAngle *= ( this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1 );\n\n\t\t\t} else if ( axis === 'XYZE' ) {\n\n\t\t\t\tthis.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();\n\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;\n\n\t\t\t} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {\n\n\t\t\t\tthis.rotationAxis.copy( _unit[ axis ] );\n\n\t\t\t\t_tempVector.copy( _unit[ axis ] );\n\n\t\t\t\tif ( space === 'local' ) {\n\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tthis.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;\n\n\t\t\t}\n\n\t\t\t// Apply rotation snap\n\n\t\t\tif ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap;\n\n\t\t\t// Apply rotate\n\t\t\tif ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {\n\n\t\t\t\tobject.quaternion.copy( this._quaternionStart );\n\t\t\t\tobject.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\tthis.rotationAxis.applyQuaternion( this._parentQuaternionInv );\n\t\t\t\tobject.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) );\n\t\t\t\tobject.quaternion.multiply( this._quaternionStart ).normalize();\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.dispatchEvent( _changeEvent );\n\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t}\n\n\tpointerUp( pointer ) {\n\n\t\tif ( pointer.button !== 0 ) return;\n\n\t\tif ( this.dragging && ( this.axis !== null ) ) {\n\n\t\t\t_mouseUpEvent.mode = this.mode;\n\t\t\tthis.dispatchEvent( _mouseUpEvent );\n\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tthis.axis = null;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.domElement.removeEventListener( 'pointerdown', this._onPointerDown );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerHover );\n\t\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\t\tthis.domElement.removeEventListener( 'pointerup', this._onPointerUp );\n\n\t\tthis.traverse( function ( child ) {\n\n\t\t\tif ( child.geometry ) child.geometry.dispose();\n\t\t\tif ( child.material ) child.material.dispose();\n\n\t\t} );\n\n\t}\n\n\t// Set current object\n\tattach( object ) {\n\n\t\tthis.object = object;\n\t\tthis.visible = true;\n\n\t\treturn this;\n\n\t}\n\n\t// Detatch from object\n\tdetach() {\n\n\t\tthis.object = undefined;\n\t\tthis.visible = false;\n\t\tthis.axis = null;\n\n\t\treturn this;\n\n\t}\n\n\treset() {\n\n\t\tif ( ! this.enabled ) return;\n\n\t\tif ( this.dragging ) {\n\n\t\t\tthis.object.position.copy( this._positionStart );\n\t\t\tthis.object.quaternion.copy( this._quaternionStart );\n\t\t\tthis.object.scale.copy( this._scaleStart );\n\n\t\t\tthis.dispatchEvent( _changeEvent );\n\t\t\tthis.dispatchEvent( _objectChangeEvent );\n\n\t\t\tthis.pointStart.copy( this.pointEnd );\n\n\t\t}\n\n\t}\n\n\tgetRaycaster() {\n\n\t\treturn _raycaster;\n\n\t}\n\n\t// TODO: deprecate\n\n\tgetMode() {\n\n\t\treturn this.mode;\n\n\t}\n\n\tsetMode( mode ) {\n\n\t\tthis.mode = mode;\n\n\t}\n\n\tsetTranslationSnap( translationSnap ) {\n\n\t\tthis.translationSnap = translationSnap;\n\n\t}\n\n\tsetRotationSnap( rotationSnap ) {\n\n\t\tthis.rotationSnap = rotationSnap;\n\n\t}\n\n\tsetScaleSnap( scaleSnap ) {\n\n\t\tthis.scaleSnap = scaleSnap;\n\n\t}\n\n\tsetSize( size ) {\n\n\t\tthis.size = size;\n\n\t}\n\n\tsetSpace( space ) {\n\n\t\tthis.space = space;\n\n\t}\n\n\tupdate() {\n\n\t\tconsole.warn( 'THREE.TransformControls: update function has no more functionality and therefore has been deprecated.' );\n\n\t}\n\n}\n\nTransformControls.prototype.isTransformControls = true;\n\n// mouse / touch event handlers\n\nfunction getPointer( event ) {\n\n\tif ( this.domElement.ownerDocument.pointerLockElement ) {\n\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tbutton: event.button\n\t\t};\n\n\t} else {\n\n\t\tconst rect = this.domElement.getBoundingClientRect();\n\n\t\treturn {\n\t\t\tx: ( event.clientX - rect.left ) / rect.width * 2 - 1,\n\t\t\ty: - ( event.clientY - rect.top ) / rect.height * 2 + 1,\n\t\t\tbutton: event.button\n\t\t};\n\n\t}\n\n}\n\nfunction onPointerHover( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tswitch ( event.pointerType ) {\n\n\t\tcase 'mouse':\n\t\tcase 'pen':\n\t\t\tthis.pointerHover( this._getPointer( event ) );\n\t\t\tbreak;\n\n\t}\n\n}\n\nfunction onPointerDown( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tif ( ! document.pointerLockElement ) {\n\n\t\tthis.domElement.setPointerCapture( event.pointerId );\n\n\t}\n\n\tthis.domElement.addEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerHover( this._getPointer( event ) );\n\tthis.pointerDown( this._getPointer( event ) );\n\n}\n\nfunction onPointerMove( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.pointerMove( this._getPointer( event ) );\n\n}\n\nfunction onPointerUp( event ) {\n\n\tif ( ! this.enabled ) return;\n\n\tthis.domElement.releasePointerCapture( event.pointerId );\n\n\tthis.domElement.removeEventListener( 'pointermove', this._onPointerMove );\n\n\tthis.pointerUp( this._getPointer( event ) );\n\n}\n\nfunction intersectObjectWithRay( object, raycaster, includeInvisible ) {\n\n\tconst allIntersections = raycaster.intersectObject( object, true );\n\n\tfor ( let i = 0; i < allIntersections.length; i ++ ) {\n\n\t\tif ( allIntersections[ i ].object.visible || includeInvisible ) {\n\n\t\t\treturn allIntersections[ i ];\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\n//\n\n// Reusable utility variables\n\nconst _tempEuler = new Euler();\nconst _alignVector = new Vector3( 0, 1, 0 );\nconst _zeroVector = new Vector3( 0, 0, 0 );\nconst _lookAtMatrix = new Matrix4();\nconst _tempQuaternion2 = new Quaternion();\nconst _identityQuaternion = new Quaternion();\nconst _dirVector = new Vector3();\nconst _tempMatrix = new Matrix4();\n\nconst _unitX = new Vector3( 1, 0, 0 );\nconst _unitY = new Vector3( 0, 1, 0 );\nconst _unitZ = new Vector3( 0, 0, 1 );\n\nconst _v1 = new Vector3();\nconst _v2 = new Vector3();\nconst _v3 = new Vector3();\n\nclass TransformControlsGizmo extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.type = 'TransformControlsGizmo';\n\n\t\t// shared materials\n\n\t\tconst gizmoMaterial = new MeshBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\tconst gizmoLineMaterial = new LineBasicMaterial( {\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\tfog: false,\n\t\t\ttoneMapped: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\t// Make unique material for each axis/color\n\n\t\tconst matInvisible = gizmoMaterial.clone();\n\t\tmatInvisible.opacity = 0.15;\n\n\t\tconst matHelper = gizmoLineMaterial.clone();\n\t\tmatHelper.opacity = 0.5;\n\n\t\tconst matRed = gizmoMaterial.clone();\n\t\tmatRed.color.setHex( 0xff0000 );\n\n\t\tconst matGreen = gizmoMaterial.clone();\n\t\tmatGreen.color.setHex( 0x00ff00 );\n\n\t\tconst matBlue = gizmoMaterial.clone();\n\t\tmatBlue.color.setHex( 0x0000ff );\n\n\t\tconst matRedTransparent = gizmoMaterial.clone();\n\t\tmatRedTransparent.color.setHex( 0xff0000 );\n\t\tmatRedTransparent.opacity = 0.5;\n\n\t\tconst matGreenTransparent = gizmoMaterial.clone();\n\t\tmatGreenTransparent.color.setHex( 0x00ff00 );\n\t\tmatGreenTransparent.opacity = 0.5;\n\n\t\tconst matBlueTransparent = gizmoMaterial.clone();\n\t\tmatBlueTransparent.color.setHex( 0x0000ff );\n\t\tmatBlueTransparent.opacity = 0.5;\n\n\t\tconst matWhiteTransparent = gizmoMaterial.clone();\n\t\tmatWhiteTransparent.opacity = 0.25;\n\n\t\tconst matYellowTransparent = gizmoMaterial.clone();\n\t\tmatYellowTransparent.color.setHex( 0xffff00 );\n\t\tmatYellowTransparent.opacity = 0.25;\n\n\t\tconst matYellow = gizmoMaterial.clone();\n\t\tmatYellow.color.setHex( 0xffff00 );\n\n\t\tconst matGray = gizmoMaterial.clone();\n\t\tmatGray.color.setHex( 0x787878 );\n\n\t\t// reusable geometry\n\n\t\tconst arrowGeometry = new CylinderGeometry( 0, 0.04, 0.1, 12 );\n\t\tarrowGeometry.translate( 0, 0.05, 0 );\n\n\t\tconst scaleHandleGeometry = new BoxGeometry( 0.08, 0.08, 0.08 );\n\t\tscaleHandleGeometry.translate( 0, 0.04, 0 );\n\n\t\tconst lineGeometry = new BufferGeometry();\n\t\tlineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0,\t1, 0, 0 ], 3 ) );\n\n\t\tconst lineGeometry2 = new CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );\n\t\tlineGeometry2.translate( 0, 0.25, 0 );\n\n\t\tfunction CircleGeometry( radius, arc ) {\n\n\t\t\tconst geometry = new TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );\n\t\t\tgeometry.rotateY( Math.PI / 2 );\n\t\t\tgeometry.rotateX( Math.PI / 2 );\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position\n\n\t\tfunction TranslateHelperGeometry() {\n\n\t\t\tconst geometry = new BufferGeometry();\n\n\t\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\t// Gizmo definitions - custom hierarchy definitions for setupGizmo() function\n\n\t\tconst gizmoTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matGreen ), [ 0, - 0.5, 0 ], [ Math.PI, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), null, [ Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent.clone() ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerTranslate = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.2, 0 ), matInvisible ) ]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperTranslate = {\n\t\t\tSTART: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tEND: [\n\t\t\t\t[ new Mesh( new OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tDELTA: [\n\t\t\t\t[ new Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 1 ), matGray ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matRed ) ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matGreen ), null, [ 0, 0, - Math.PI / 2 ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.5, 0.5 ), matBlue ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( CircleGeometry( 0.75, 1 ), matYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]]\n\t\t\t]\n\t\t};\n\n\t\tconst helperRotate = {\n\t\t\tAXIS: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\tconst pickerRotate = {\n\t\t\tXYZE: [\n\t\t\t\t[ new Mesh( new SphereGeometry( 0.25, 10, 8 ), matInvisible ) ]\n\t\t\t],\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t],\n\t\t\tE: [\n\t\t\t\t[ new Mesh( new TorusGeometry( 0.75, 0.1, 2, 24 ), matInvisible ) ]\n\t\t\t]\n\t\t};\n\n\t\tconst gizmoScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]],\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.5, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matGreen ) ],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matGreen ), [ 0, - 0.5, 0 ], [ 0, 0, Math.PI ]],\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( lineGeometry2, matBlue ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.1, 0.1, 0.1 ), matWhiteTransparent.clone() ) ],\n\t\t\t]\n\t\t};\n\n\t\tconst pickerScale = {\n\t\t\tX: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]],\n\t\t\t\t[ new Mesh( new CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]\n\t\t\t],\n\t\t\tXY: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]],\n\t\t\t],\n\t\t\tYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]],\n\t\t\t],\n\t\t\tXZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]],\n\t\t\t],\n\t\t\tXYZ: [\n\t\t\t\t[ new Mesh( new BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 0 ]],\n\t\t\t]\n\t\t};\n\n\t\tconst helperScale = {\n\t\t\tX: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tY: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t],\n\t\t\tZ: [\n\t\t\t\t[ new Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]\n\t\t\t]\n\t\t};\n\n\t\t// Creates an Object3D with gizmos described in custom hierarchy definition.\n\n\t\tfunction setupGizmo( gizmoMap ) {\n\n\t\t\tconst gizmo = new Object3D();\n\n\t\t\tfor ( const name in gizmoMap ) {\n\n\t\t\t\tfor ( let i = gizmoMap[ name ].length; i --; ) {\n\n\t\t\t\t\tconst object = gizmoMap[ name ][ i ][ 0 ].clone();\n\t\t\t\t\tconst position = gizmoMap[ name ][ i ][ 1 ];\n\t\t\t\t\tconst rotation = gizmoMap[ name ][ i ][ 2 ];\n\t\t\t\t\tconst scale = gizmoMap[ name ][ i ][ 3 ];\n\t\t\t\t\tconst tag = gizmoMap[ name ][ i ][ 4 ];\n\n\t\t\t\t\t// name and tag properties are essential for picking and updating logic.\n\t\t\t\t\tobject.name = name;\n\t\t\t\t\tobject.tag = tag;\n\n\t\t\t\t\tif ( position ) {\n\n\t\t\t\t\t\tobject.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( rotation ) {\n\n\t\t\t\t\t\tobject.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( scale ) {\n\n\t\t\t\t\t\tobject.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobject.updateMatrix();\n\n\t\t\t\t\tconst tempGeometry = object.geometry.clone();\n\t\t\t\t\ttempGeometry.applyMatrix4( object.matrix );\n\t\t\t\t\tobject.geometry = tempGeometry;\n\t\t\t\t\tobject.renderOrder = Infinity;\n\n\t\t\t\t\tobject.position.set( 0, 0, 0 );\n\t\t\t\t\tobject.rotation.set( 0, 0, 0 );\n\t\t\t\t\tobject.scale.set( 1, 1, 1 );\n\n\t\t\t\t\tgizmo.add( object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn gizmo;\n\n\t\t}\n\n\t\t// Gizmo creation\n\n\t\tthis.gizmo = {};\n\t\tthis.picker = {};\n\t\tthis.helper = {};\n\n\t\tthis.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) );\n\t\tthis.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) );\n\t\tthis.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) );\n\t\tthis.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) );\n\t\tthis.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) );\n\t\tthis.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );\n\t\tthis.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );\n\t\tthis.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );\n\t\tthis.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) );\n\n\t\t// Pickers should be hidden always\n\n\t\tthis.picker[ 'translate' ].visible = false;\n\t\tthis.picker[ 'rotate' ].visible = false;\n\t\tthis.picker[ 'scale' ].visible = false;\n\n\t}\n\n\t// updateMatrixWorld will update transformations and appearance of individual handles\n\n\tupdateMatrixWorld( force ) {\n\n\t\tconst space = ( this.mode === 'scale' ) ? 'local' : this.space; // scale always oriented to local rotation\n\n\t\tconst quaternion = ( space === 'local' ) ? this.worldQuaternion : _identityQuaternion;\n\n\t\t// Show only gizmos for current transform mode\n\n\t\tthis.gizmo[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.gizmo[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.gizmo[ 'scale' ].visible = this.mode === 'scale';\n\n\t\tthis.helper[ 'translate' ].visible = this.mode === 'translate';\n\t\tthis.helper[ 'rotate' ].visible = this.mode === 'rotate';\n\t\tthis.helper[ 'scale' ].visible = this.mode === 'scale';\n\n\n\t\tlet handles = [];\n\t\thandles = handles.concat( this.picker[ this.mode ].children );\n\t\thandles = handles.concat( this.gizmo[ this.mode ].children );\n\t\thandles = handles.concat( this.helper[ this.mode ].children );\n\n\t\tfor ( let i = 0; i < handles.length; i ++ ) {\n\n\t\t\tconst handle = handles[ i ];\n\n\t\t\t// hide aligned to camera\n\n\t\t\thandle.visible = true;\n\t\t\thandle.rotation.set( 0, 0, 0 );\n\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\tlet factor;\n\n\t\t\tif ( this.camera.isOrthographicCamera ) {\n\n\t\t\t\tfactor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;\n\n\t\t\t} else {\n\n\t\t\t\tfactor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );\n\n\t\t\t}\n\n\t\t\thandle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 );\n\n\t\t\t// TODO: simplify helpers and consider decoupling from gizmo\n\n\t\t\tif ( handle.tag === 'helper' ) {\n\n\t\t\t\thandle.visible = false;\n\n\t\t\t\tif ( handle.name === 'AXIS' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.visible = !! this.axis;\n\n\t\t\t\t\tif ( this.axis === 'X' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Y' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'Z' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\thandle.quaternion.copy( quaternion ).multiply( _tempQuaternion );\n\n\t\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {\n\n\t\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'XYZE' ) {\n\n\t\t\t\t\t\t_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );\n\t\t\t\t\t\t_alignVector.copy( this.rotationAxis );\n\t\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );\n\t\t\t\t\t\thandle.quaternion.multiply( _tempQuaternion );\n\t\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis === 'E' ) {\n\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\n\t\t\t\t} else if ( handle.name === 'START' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'END' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPosition );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else if ( handle.name === 'DELTA' ) {\n\n\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\t\t\t\t\thandle.quaternion.copy( this.worldQuaternionStart );\n\t\t\t\t\t_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );\n\t\t\t\t\t_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );\n\t\t\t\t\thandle.scale.copy( _tempVector );\n\t\t\t\t\thandle.visible = this.dragging;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\t\t\tif ( this.dragging ) {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPositionStart );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\thandle.position.copy( this.worldPosition );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( this.axis ) {\n\n\t\t\t\t\t\thandle.visible = this.axis.search( handle.name ) !== - 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// If updating helper, skip rest of the loop\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// Align handles to current local or world rotation\n\n\t\t\thandle.quaternion.copy( quaternion );\n\n\t\t\tif ( this.mode === 'translate' || this.mode === 'scale' ) {\n\n\t\t\t\t// Hide translate and scale axis facing the camera\n\n\t\t\t\tconst AXIS_HIDE_TRESHOLD = 0.99;\n\t\t\t\tconst PLANE_HIDE_TRESHOLD = 0.2;\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XY' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'YZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'XZ' ) {\n\n\t\t\t\t\tif ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {\n\n\t\t\t\t\t\thandle.scale.set( 1e-10, 1e-10, 1e-10 );\n\t\t\t\t\t\thandle.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.mode === 'rotate' ) {\n\n\t\t\t\t// Align handles to current local or world rotation\n\n\t\t\t\t_tempQuaternion2.copy( quaternion );\n\t\t\t\t_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );\n\n\t\t\t\tif ( handle.name.search( 'E' ) !== - 1 ) {\n\n\t\t\t\t\thandle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'X' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Y' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t\tif ( handle.name === 'Z' ) {\n\n\t\t\t\t\t_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );\n\t\t\t\t\t_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );\n\t\t\t\t\thandle.quaternion.copy( _tempQuaternion );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Hide disabled axes\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );\n\t\t\thandle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || ( this.showX && this.showY && this.showZ ) );\n\n\t\t\t// highlight selected axis\n\n\t\t\thandle.material._color = handle.material._color || handle.material.color.clone();\n\t\t\thandle.material._opacity = handle.material._opacity || handle.material.opacity;\n\n\t\t\thandle.material.color.copy( handle.material._color );\n\t\t\thandle.material.opacity = handle.material._opacity;\n\n\t\t\tif ( this.enabled && this.axis ) {\n\n\t\t\t\tif ( handle.name === this.axis ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t} else if ( this.axis.split( '' ).some( function ( a ) {\n\n\t\t\t\t\treturn handle.name === a;\n\n\t\t\t\t} ) ) {\n\n\t\t\t\t\thandle.material.color.setHex( 0xffff00 );\n\t\t\t\t\thandle.material.opacity = 1.0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nTransformControlsGizmo.prototype.isTransformControlsGizmo = true;\n\n//\n\nclass TransformControlsPlane extends Mesh {\n\n\tconstructor() {\n\n\t\tsuper(\n\t\t\tnew PlaneGeometry( 100000, 100000, 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { visible: false, wireframe: true, side: DoubleSide, transparent: true, opacity: 0.1, toneMapped: false } )\n\t\t);\n\n\t\tthis.type = 'TransformControlsPlane';\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tlet space = this.space;\n\n\t\tthis.position.copy( this.worldPosition );\n\n\t\tif ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation\n\n\t\t_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\t\t_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );\n\n\t\t// Align the plane for current transform mode, axis and space.\n\n\t\t_alignVector.copy( _v2 );\n\n\t\tswitch ( this.mode ) {\n\n\t\t\tcase 'translate':\n\t\t\tcase 'scale':\n\t\t\t\tswitch ( this.axis ) {\n\n\t\t\t\t\tcase 'X':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v1 );\n\t\t\t\t\t\t_dirVector.copy( _v1 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Y':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v2 );\n\t\t\t\t\t\t_dirVector.copy( _v2 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\t\t_alignVector.copy( this.eye ).cross( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v3 ).cross( _alignVector );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XY':\n\t\t\t\t\t\t_dirVector.copy( _v3 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'YZ':\n\t\t\t\t\t\t_dirVector.copy( _v1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XZ':\n\t\t\t\t\t\t_alignVector.copy( _v3 );\n\t\t\t\t\t\t_dirVector.copy( _v2 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'XYZ':\n\t\t\t\t\tcase 'E':\n\t\t\t\t\t\t_dirVector.set( 0, 0, 0 );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 'rotate':\n\t\t\tdefault:\n\t\t\t\t// special case for rotate\n\t\t\t\t_dirVector.set( 0, 0, 0 );\n\n\t\t}\n\n\t\tif ( _dirVector.length() === 0 ) {\n\n\t\t\t// If in rotate mode, make the plane parallel to camera\n\t\t\tthis.quaternion.copy( this.cameraQuaternion );\n\n\t\t} else {\n\n\t\t\t_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( _tempMatrix );\n\n\t\t}\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nTransformControlsPlane.prototype.isTransformControlsPlane = true;\n\nexport { TransformControls, TransformControlsGizmo, TransformControlsPlane };\n","import { AmbientLight, AxesHelper, Box3, BufferAttribute, BufferGeometry, BufferGeometryUtils, Color, DirectionalLight, EventDispatcher, Group, Mesh, MeshBasicMaterial, MeshStandardMaterial, Object3D, OrthographicCamera, PerspectiveCamera, Raycaster, Scene, Triangle, Vector2, Vector3, WebGLRenderer } from \"three\";\r\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';\r\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls';\r\nexport enum OutEventTypes {\r\n /**\r\n * 模型选中,事件参数会返回模型名\r\n */\r\n MODEL_SELECTED = 'onModelSelected',\r\n /**\r\n * 取消选中\r\n */\r\n UNSELECT = 'onUnselect',\r\n /**\r\n * 模型位移旋转缩放时派发,事件参数会返回模型名、具体操作、数值\r\n */\r\n // MODEL_TRANSFORM = 'onModelTransform',\r\n}\r\nObject3D.DefaultUp = new Vector3(0, 0, 1)\r\nexport class Main extends EventDispatcher {\r\n version() {\r\n const pkg = require(\"../package.json\");\r\n return pkg.version;\r\n }\r\n private scene: Scene;\r\n private camera: PerspectiveCamera | OrthographicCamera;\r\n private renderer: WebGLRenderer\r\n private requestID: number;\r\n private orbit: OrbitControls;\r\n private igsGroup: Group;\r\n constructor(private container: HTMLDivElement, private option?: { isOrthographicCamera?: boolean }) {\r\n super();\r\n console.log(\r\n \"%cigs-view version:\" + this.version(),\r\n \"text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:3em\"\r\n )\r\n let width = container.clientWidth;\r\n let height = container.clientHeight;\r\n let renderer = this.renderer = new WebGLRenderer({ alpha: true, antialias: true, logarithmicDepthBuffer: true })\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.autoClear = true;\r\n renderer.localClippingEnabled = true;\r\n // renderer.setClearColor(0xf6f6f6);\r\n renderer.setSize(width, height);\r\n container.appendChild(renderer.domElement)\r\n let scene = this.scene = new Scene();\r\n this.igsGroup = new Group()\r\n scene.add(this.igsGroup)\r\n let camera: PerspectiveCamera | OrthographicCamera;\r\n if (option?.isOrthographicCamera) {\r\n const left = -width / 2 / 1;\r\n const right = width / 2 / 1;\r\n const top = height / 2 / 1;\r\n const bottom = -height / 2 / 1;\r\n camera = this.camera = new OrthographicCamera(\r\n left,\r\n right,\r\n top,\r\n bottom\r\n );\r\n camera.position.set(0, 0, 1000);\r\n const orbit = this.orbit = new OrbitControls(camera, renderer.domElement);\r\n orbit.enableRotate = false;\r\n } else {\r\n camera = this.camera = new PerspectiveCamera(\r\n 30,\r\n width / height,\r\n 0.0001,\r\n 100000\r\n );\r\n camera.position.set(1000, 1000, 1000);\r\n //相机控件\r\n const orbit = this.orbit = new OrbitControls(camera, renderer.domElement);\r\n orbit.maxDistance = 10000;\r\n // orbit.enableDamping = true;\r\n // orbit.dampingFactor = 0.005;\r\n }\r\n // var gridHelper = new GridHelper(100, 100, 0x888888, 0x888888);\r\n // gridHelper.rotation.x = Math.PI / 2;\r\n // scene.add(gridHelper);\r\n var axesHelper = new AxesHelper(100);\r\n scene.add(axesHelper);\r\n axesHelper.position.z = 0.001\r\n let self = this;\r\n loop();\r\n function loop() {\r\n renderer.render(scene, camera)\r\n // self.orbit?.update()\r\n self.requestID = requestAnimationFrame(loop)\r\n }\r\n\r\n //测试下分割\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(5, -10, 10)\r\n scene.add(pll)\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(0, 10, 0)\r\n scene.add(pll)\r\n scene.add(new AmbientLight(0xeeeeee, 0.05))\r\n\r\n //\r\n let resize = this.resize = () => {\r\n if (!this.renderer) return;\r\n const w = container.clientWidth;\r\n const h = container.clientHeight;\r\n // this.resize(w, h);\r\n this.renderer?.setSize(w, h);\r\n if (option?.isOrthographicCamera) {\r\n let orthographicCamera = camera as OrthographicCamera\r\n let zoom = 1//orthographicCamera.zoom;\r\n // console.log(zoom)\r\n const left = -w / 2 / zoom;\r\n const right = w / 2 / zoom;\r\n const top = h / 2 / zoom;\r\n const bottom = -h / 2 / zoom;\r\n orthographicCamera.left = left;\r\n orthographicCamera.right = right;\r\n orthographicCamera.top = top;\r\n orthographicCamera.bottom = bottom;\r\n // console.log(zoom)\r\n } else {\r\n (camera as PerspectiveCamera).aspect = w / h;\r\n }\r\n camera.updateProjectionMatrix();\r\n }\r\n window.addEventListener('resize', resize);\r\n this.addMouseEvent();\r\n }\r\n /**\r\n * 显示容器发生变化时调用\r\n */\r\n resize: () => void;\r\n private defaultMeshMaterial = new MeshStandardMaterial({ side: 0, clipIntersection: true });\r\n private defaultMeshMaterial_selected = new MeshBasicMaterial({ side: 0, clipIntersection: true, color: new Color(0xff0000) });\r\n private entities: IEntity[];\r\n async loadIgs(src: string) {\r\n let json: any = await fetch(src)\r\n .then((res) => res.text())\r\n .then((res) => JSON.parse(res))\r\n const Entities: IEntity[] = json.Data.Metadata.Entities\r\n this.parseIgs(Entities)\r\n }\r\n private map: { points: number[], height: number }[] = [];\r\n private box: Box3 = new Box3;\r\n parseIgs(entities: IEntity[]) {\r\n this.box.makeEmpty();\r\n this.map.length = 0;\r\n this.entities = entities;\r\n entities.forEach(({ Triangles, Vertices, Id }) => {\r\n // console.log(Triangles, Vertices)\r\n // ========== 创建BufferGeometry ==========\r\n const geometry = new BufferGeometry();\r\n\r\n // 顶点位置数组\r\n const positions = new Float32Array(Vertices.length * 3);\r\n Vertices.forEach((vert, i) => {\r\n positions[i * 3] = vert.X;\r\n positions[i * 3 + 1] = vert.Y;\r\n positions[i * 3 + 2] = vert.Z;\r\n });\r\n // 三角形索引数组\r\n const indices = [];\r\n Triangles.forEach(({ VertexIndex1, VertexIndex2, VertexIndex3 }) => {\r\n indices.push(VertexIndex1, VertexIndex2, VertexIndex3);\r\n let p1 = [\r\n positions[VertexIndex1 * 3],\r\n positions[VertexIndex1 * 3 + 1],\r\n positions[VertexIndex1 * 3 + 2]\r\n ]\r\n let p2 = [\r\n positions[VertexIndex2 * 3],\r\n positions[VertexIndex2 * 3 + 1],\r\n positions[VertexIndex2 * 3 + 2]\r\n ]\r\n let p3 = [\r\n positions[VertexIndex3 * 3],\r\n positions[VertexIndex3 * 3 + 1],\r\n positions[VertexIndex3 * 3 + 2]\r\n ]\r\n //如果面与z轴平行,跳过\r\n const triangle = new Triangle(\r\n new Vector3(...p1),\r\n new Vector3(...p2),\r\n new Vector3(...p3)\r\n );\r\n const tolerance = 0.0001;\r\n if (Math.abs(triangle.getNormal(new Vector3).z) < tolerance) {\r\n return\r\n }\r\n this.map.push({\r\n height: (p1[2] + p2[2] + p3[2]) / 3,\r\n points: [\r\n p1[0], p1[1],\r\n p2[0], p2[1],\r\n p3[0], p3[1],\r\n ]\r\n })\r\n });\r\n\r\n // 设置几何体属性\r\n geometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n geometry.setIndex(indices);\r\n\r\n // 计算法线(用于光照)\r\n geometry.computeVertexNormals();\r\n\r\n geometry.computeBoundingBox()\r\n this.box.union(geometry.boundingBox)\r\n // ========== 创建网格 ==========\r\n const mesh = new Mesh(geometry, this.defaultMeshMaterial);\r\n mesh.uuid = Id + \"\"\r\n this.igsGroup.add(mesh);\r\n })\r\n }\r\n clearIgs() {\r\n this.igsGroup.clear();\r\n }\r\n private pading = 10;\r\n private scale = 10;\r\n private rotateX: number = 0;\r\n private rotateY: number = 0;\r\n verticalView() {\r\n if (!this.igsGroup.children.length) return null;\r\n // this.igsGroup.position.set(-97,200,-800)\r\n // this. igsGroup.updateMatrix();\r\n // if (this.igsGroup.rotation.x == 0 && this.igsGroup.rotation.y == 0) {\r\n // let canvas = document.createElement(\"canvas\")\r\n // let originX = (this.pading - this.box.min.x) * this.scale;\r\n // let originY = (this.pading - this.box.min.y) * this.scale;\r\n // let vec = this.box.getSize(new Vector3);\r\n // canvas.width = (vec.x + this.pading * 2) * this.scale;\r\n // canvas.height = (vec.y + this.pading * 2) * this.scale;\r\n // let ctx = canvas.getContext(\"2d\")\r\n // ctx.fillStyle = \"#ffffff\"\r\n // ctx.fillRect(0, 0, canvas.width, canvas.height)\r\n // ctx.setTransform(this.scale, 0, 0, this.scale, originX, originY)\r\n // this.map.sort((a, b) => a.height - b.height);\r\n // let max = this.map[this.map.length - 1].height;\r\n // // console.log(this.map)\r\n // this.map.forEach(({ height, points }, index) => {\r\n // let grey = (max - height) / max * 200\r\n // ctx.fillStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;\r\n // ctx.strokeStyle = `rgba(${grey}, ${grey}, ${grey}, 1)`;\r\n // ctx.lineWidth = 1 / this.scale\r\n // ctx.lineCap = \"round\";\r\n // ctx.lineJoin = \"round\"\r\n // ctx.beginPath()\r\n // for (let i = 0; i < points.length; i += 2) {\r\n // if (i == 0) {\r\n // ctx.moveTo(points[i], points[i + 1])\r\n // } else {\r\n // ctx.lineTo(points[i], points[i + 1])\r\n // }\r\n // }\r\n // ctx.closePath();\r\n // ctx.fill();\r\n // ctx.stroke();\r\n // })\r\n // // document.body.appendChild(canvas);\r\n // return {\r\n // rotateX: 0,\r\n // rotateY: 0,\r\n // x: originX,\r\n // y: originY,\r\n // scale: this.scale,\r\n // base64: canvas.toDataURL(\"image/jpeg\", 0.8)\r\n // }\r\n // } else {\r\n //带旋转\r\n let igsGroup = this.igsGroup.clone();\r\n // igsGroup.scale.set(-1, 1, 1)\r\n // igsGroup.position.set(-97,200,-800)\r\n // igsGroup.updateMatrix();\r\n let box = new Box3\r\n igsGroup.children.forEach((m: Mesh) => {\r\n let geo = m.geometry.clone();\r\n geo.applyMatrix4(this.igsGroup.matrix)\r\n geo.computeBoundingBox();\r\n box.union(geo.boundingBox)\r\n })\r\n const size = box.getSize(new Vector3());\r\n // console.log(size)\r\n const center = box.getCenter(new Vector3());\r\n // 2. 创建离屏渲染场景\r\n const scene = new Scene();\r\n scene.background = new Color(0xffffff); // 白色背景\r\n scene.add(igsGroup)\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(5, -10, 10)\r\n scene.add(pll)\r\n var pll = new DirectionalLight(0xffffff, 0.3)\r\n pll.position.set(0, 10, 0)\r\n scene.add(pll)\r\n scene.add(new AmbientLight(0xeeeeee, 0.05))\r\n // 3. 配置正交相机(俯视图)\r\n const viewWidth = size.x + this.pading * 2;\r\n const viewHeight = size.y + this.pading * 2;\r\n // console.log(size,center,viewWidth,viewHeight)\r\n const camera = new OrthographicCamera(\r\n -viewWidth / 2,\r\n viewWidth / 2,\r\n viewHeight / 2,\r\n -viewHeight / 2,\r\n // viewWidth / 2, // left (正值) ← 关键:+X映射到左\r\n // -viewWidth / 2, // right (负值) ← 关键:-X映射到右\r\n // -viewHeight / 2, // top (负值) ← 关键:-Y映射到上\r\n // viewHeight / 2, // bottom (正值) ← 关键:+Y映射到下\r\n 0.1, 1000\r\n );\r\n camera.up = new Vector3(0, -1, 0)\r\n // 相机放在 Z 轴正上方(向下看)\r\n camera.position.set(center.x, center.y, center.z + size.z / 2 + 50);\r\n camera.lookAt(center.x, center.y, center.z);\r\n\r\n // 5. 渲染到 canvas\r\n const renderer = new WebGLRenderer({\r\n antialias: true,\r\n preserveDrawingBuffer: true // 允许导出图片\r\n });\r\n\r\n // 设置合适的像素尺寸(可调整)\r\n const pixelRatio = 2; // 用于提高清晰度\r\n renderer.setSize(viewWidth * pixelRatio, viewHeight * pixelRatio);\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n // 渲染\r\n renderer.render(scene, camera);\r\n // document.body.appendChild(renderer.domElement);\r\n // 6. 返回渲染结果(canvas 元素)\r\n return {\r\n rotateX: this.igsGroup.rotation.x,\r\n rotateY: this.igsGroup.rotation.y,\r\n rotateZ: this.igsGroup.rotation.z,\r\n x: this.pading - box.min.x,\r\n y: this.pading - box.min.y,\r\n scale: 1,\r\n base64: renderer.domElement.toDataURL(\"image/jpeg\", 0.8)\r\n };\r\n // }\r\n }\r\n private raycaster: Raycaster;\r\n private onUpPosition = new Vector2(-1, -1); //\t用于判断点击事件位置\r\n private onDownPosition = new Vector2(-1, -1); //\t同上\r\n private selected: Mesh;\r\n private addMouseEvent() {\r\n this.raycaster = new Raycaster();\r\n const { container } = this;\r\n container.addEventListener('pointerdown', (event: PointerEvent) => {\r\n this.onDownPosition.x = event.offsetX;\r\n this.onDownPosition.y = event.offsetY;\r\n });\r\n // container.addEventListener('pointermove', (event: PointerEvent) => {\r\n // this.hittest(event)\r\n // });\r\n container.addEventListener('pointerup', (event: PointerEvent) => {\r\n this.onUpPosition.x = event.offsetX;\r\n this.onUpPosition.y = event.offsetY;\r\n //\t单击有效(点击的位置已经不同,就直接返回了)\r\n if (this.onDownPosition.distanceTo(this.onUpPosition) > 20) {\r\n return;\r\n }\r\n const clientWidth = this.container.clientWidth;\r\n const clientHeight = this.container.clientHeight;\r\n const { camera, raycaster } = this\r\n\r\n // console.log(clientWidth,clientHeight)\r\n let models: Mesh[] = this.igsGroup.children.slice() as Mesh[]\r\n let x = (event.offsetX / clientWidth) * 2 - 1;\r\n let y = -(event.offsetY / clientHeight) * 2 + 1;\r\n raycaster.setFromCamera(new Vector3(x, y, 0.5), camera);\r\n //只需要距离最近的那个就行\r\n let picks = this.raycaster.intersectObjects(models, true);\r\n if (picks[0]?.object) {\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = picks[0].object as Mesh\r\n this.selected.material = this.defaultMeshMaterial_selected;\r\n //派发个事件出去,TODO,选中了,数据带上uuid\r\n this.dispatchEvent({\r\n type: OutEventTypes.MODEL_SELECTED,\r\n // id: this.selected.id,\r\n uuid: this.selected.uuid,\r\n });\r\n } else {\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = null;\r\n this.dispatchEvent({ type: OutEventTypes.UNSELECT });\r\n }\r\n });\r\n\r\n }\r\n selectedByUuid(uuid: string) {\r\n let mesh = this.igsGroup.children.find((m: Mesh) => {\r\n return m.uuid == uuid\r\n }) as Mesh\r\n if (this.selected) this.selected.material = this.defaultMeshMaterial;\r\n this.selected = mesh\r\n this.selected.material = this.defaultMeshMaterial_selected;\r\n }\r\n private transformControls: TransformControls\r\n /**\r\n * @description: 添加变换控制器\r\n * @return {*}\r\n * @author: shanbian\r\n */\r\n addTransformControls() {\r\n // 添加变换控制器\r\n this.transformControls = new TransformControls(\r\n this.camera,\r\n this.renderer.domElement\r\n );\r\n this.scene.add(this.transformControls);\r\n // 选中父类为需要控制的物体\r\n this.transformControls.attach(this.igsGroup);\r\n this.transformControls.mode = \"rotate\";\r\n this.transformControls.showZ = true;\r\n this.transformControls.showX = this.transformControls.showY = true;\r\n // 如果指针(鼠标/触摸)为活动状态则触发该事件。\r\n this.transformControls.addEventListener('mouseDown', () => {\r\n this.orbit.enabled = false;\r\n });\r\n // 如果指针(鼠标/触摸)不再为活动状态则触发该事件。\r\n this.transformControls.addEventListener('mouseUp', () => {\r\n this.orbit.enabled = true;\r\n });\r\n // 如果被控制的3D对象发生改变则触发该事件。\r\n this.transformControls.addEventListener('objectChange', () => {\r\n // // 更新Box3Helper\r\n // if (this.modelsSystem.getSelectedModelInfo()) {\r\n // const { uuid } = this.modelsSystem.getSelectedModelInfo();\r\n // this.modelsSystem.updateBox3Helper(uuid);\r\n // }\r\n // 渲染界面\r\n });\r\n // 通过按键控制 transformControls的mode\r\n document.addEventListener('keydown', (event) => {\r\n if (event.repeat) {\r\n return false;\r\n }\r\n // console.log(event);\r\n // if (event.key === 'e') {\r\n // this.transformControls.mode = 'scale';\r\n // return false;\r\n // }\r\n\r\n // if (event.key === 'r') {\r\n // this.transformControls.mode = 'rotate';\r\n // this.transformControls.showZ = true;\r\n // this.transformControls.showX = this.transformControls.showY = false;\r\n // return false;\r\n // }\r\n\r\n // if (event.key === 't') {\r\n // this.transformControls.mode = 'translate';\r\n // this.transformControls.showZ = false;\r\n // this.transformControls.showX = this.transformControls.showY = true;\r\n // return false;\r\n // }\r\n });\r\n }\r\n removeTransformControls() {\r\n this.scene.remove(this.transformControls);\r\n // 选中父类为需要控制的物体\r\n this.transformControls.detach();\r\n }\r\n}\r\n\r\n\r\ninterface IEntity {\r\n Triangles: {\r\n \"VertexIndex1\": number,\r\n \"VertexIndex2\": number,\r\n \"VertexIndex3\": number\r\n }[],\r\n Vertices: {\r\n \"X\": number,\r\n \"Y\": number,\r\n \"Z\": number\r\n }[],\r\n Id: number\r\n}","module.exports = __WEBPACK_EXTERNAL_MODULE_three__;"],"sourceRoot":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "igs-view",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "main": "./dist/main.js",
5
5
  "types": "./types/Main.d.ts",
6
6
  "scripts": {
package/types/Main.d.ts CHANGED
@@ -39,6 +39,9 @@ export declare class Main extends EventDispatcher {
39
39
  private rotateX;
40
40
  private rotateY;
41
41
  verticalView(): {
42
+ rotateX: number;
43
+ rotateY: number;
44
+ rotateZ: number;
42
45
  x: number;
43
46
  y: number;
44
47
  scale: number;