diff --git a/src/views/Answer/questions/components/AnswerViewer.vue b/src/views/Answer/questions/components/AnswerViewer.vue
index 67b5adea..d792dbe2 100644
--- a/src/views/Answer/questions/components/AnswerViewer.vue
+++ b/src/views/Answer/questions/components/AnswerViewer.vue
@@ -17,6 +17,7 @@
:surveyId="surveyId"
:defaultWare="defaultWare"
:isLocked="!!config.is_initialize"
+ :freezeRotY="!!config.is_default_perspective"
@onBehaviorFlush="onBehaviorFlush"
/>
diff --git a/src/views/Answer/questions/components/AnswerViewerMatrix.vue b/src/views/Answer/questions/components/AnswerViewerMatrix.vue
index d970a1ed..655a5a65 100644
--- a/src/views/Answer/questions/components/AnswerViewerMatrix.vue
+++ b/src/views/Answer/questions/components/AnswerViewerMatrix.vue
@@ -7,6 +7,7 @@
:surveyId="surveyId"
:defaultWare="defaultWare"
:isLocked="!!config.is_initialize"
+ :freezeRotY="!!config.is_default_perspective"
@onLoadingCompletion="onLoadingCompletion"
@onFromSceneHoldToShelf="onFromSceneHoldToShelf"
@onBehaviorFlush="onBehaviorFlush"
diff --git a/src/views/planetDesign/Design/components/config/Config3D.vue b/src/views/planetDesign/Design/components/config/Config3D.vue
index b1f62cfe..8f6222ff 100644
--- a/src/views/planetDesign/Design/components/config/Config3D.vue
+++ b/src/views/planetDesign/Design/components/config/Config3D.vue
@@ -104,6 +104,14 @@
锁定初始位置
+
+
+ 固定默认视角
+
+
diff --git a/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewer.vue b/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewer.vue
index 95fb25e5..b8cedb3c 100644
--- a/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewer.vue
+++ b/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewer.vue
@@ -7,7 +7,7 @@
var target = null;
export default {
- props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked", "hidden"],
+ props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked", "freezeRotY", "hidden"],
data(){
return {
@@ -29,6 +29,7 @@ export default {
elCart: this.elCart,
defaultWare: this.defaultWare,
isLocked: this.isLocked,
+ freezeRotY: this.freezeRotY,
}
}), '*');
return;
@@ -96,6 +97,7 @@ export default {
data: {
defaultWare: this.defaultWare || null,
isLocked: this.isLocked,
+ freezeRotY: this.freezeRotY,
page: newVal,
}
}), '*');
diff --git a/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview.vue b/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview.vue
index ceac2776..874499ca 100644
--- a/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview.vue
+++ b/src/views/planetDesign/Design/components/config/Viewer3D/SceneSurveyViewerPreview.vue
@@ -6,7 +6,7 @@
import { SurveyViewer } from "@/views/planetDesign/SceneSurveyViewerPage/shelves.module.js";
export default {
- props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked"],
+ props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked", "freezeRotY"],
mounted() {
this.$nextTick(() => this.tryInitView());
@@ -59,6 +59,7 @@ export default {
wareId: this.defaultWare?.planetid,
keepHold: this.isLocked,
frostFarScene: this.isLocked,
+ freezeRotY: this.freezeRotY ? "0" : undefined,
})
});
}
diff --git a/src/views/planetDesign/SceneSurveyViewerPage/Index.vue b/src/views/planetDesign/SceneSurveyViewerPage/Index.vue
index 83148654..f184c550 100644
--- a/src/views/planetDesign/SceneSurveyViewerPage/Index.vue
+++ b/src/views/planetDesign/SceneSurveyViewerPage/Index.vue
@@ -13,7 +13,7 @@ import { SurveyViewer } from "./shelves.module";
import { debounce } from 'lodash-es';
export default {
- // props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked"],
+ // props: ["surveyId", "shopData", "page", "sceneAction", "elCart", "defaultWare", "isLocked", "freezeRotY"],
data(){
return {
@@ -23,7 +23,9 @@ export default {
sceneAction: null,
elCart: null,
defaultWare: null,
+
isLocked: null,
+ freezeRotY: false,
spinning: true,
@@ -133,6 +135,7 @@ export default {
wareId: this.defaultWare?.planetid,
keepHold: this.isLocked,
frostFarScene: this.isLocked,
+ freezeRotY: this.freezeRotY ? "0" : undefined,
})
});
}
diff --git a/src/views/planetDesign/SceneSurveyViewerPage/shelves.module.js b/src/views/planetDesign/SceneSurveyViewerPage/shelves.module.js
index c965073a..42d55295 100644
--- a/src/views/planetDesign/SceneSurveyViewerPage/shelves.module.js
+++ b/src/views/planetDesign/SceneSurveyViewerPage/shelves.module.js
@@ -113,7 +113,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TextSpriteMaterial\": () => (/* binding */ TextSpriteMaterial),\n/* harmony export */ \"default\": () => (/* binding */ TextSprite)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/util/MathUtil */ \"./src-kutsi/crossyo/kutsi/util/MathUtil.js\");\n/* harmony import */ var kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/PerspUtil */ \"./src-kutsi/crossyo/kutsi/util/PerspUtil.js\");\n/* harmony import */ var kutsi_glsl_persp_type_part_glsl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/glsl/persp-type-part.glsl */ \"./src-kutsi/crossyo/kutsi/glsl/persp-type-part.glsl\");\n\r\n\r\n\r\n\r\n\r\n\r\n// TODO 不包括wx部分\r\nlet ctx_measure_ = null\r\nconst measure_ = (font, txt, is_wx, canvas2) => {\r\n if (!ctx_measure_) {\r\n if (!is_wx) {\r\n let canvas = document.createElement('canvas')\r\n ctx_measure_ = canvas.getContext('2d')\r\n } else {\r\n ctx_measure_ = canvas2.getContext('2d')\r\n }\r\n }\r\n ctx_measure_.font = font\r\n return ctx_measure_.measureText(txt)\r\n}\r\n\r\nclass TextSpriteMaterial extends three__WEBPACK_IMPORTED_MODULE_3__.SpriteMaterial {\r\n constructor(param0, param) {\r\n\r\n super(Object.assign({\r\n // map: get_tex_(),\r\n color: 0x000000, // background!\r\n opacity: .6,\r\n toneMapped: false,\r\n depthWrite: false,\r\n depthTest: false,\r\n }, param0))\r\n\r\n this.param_ = param\r\n\r\n this.sizeAttenuation = this.param_.perspType == kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.Persp\r\n\r\n const draw_ = (ctx, w, h, font) => {\r\n\r\n ctx.clearRect(0, 0, w, h)\r\n ctx.font = font\r\n ctx.fillStyle = 'rgba(255,255,255,1)'\r\n ctx.fillText(param.text, param.margin, param.fontSize)\r\n\r\n }\r\n\r\n let w0 = param.measure_.width + param.margin + param.margin\r\n let w = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__.ceilPowerOfTwo)(w0)\r\n this.scale_u_ = w0 / w\r\n let h = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__.ceilPowerOfTwo)(param.fontSize + param.margin + param.margin)\r\n\r\n // console.log('', param.text)\r\n // console.log('est w x h:', w, h)\r\n\r\n let ctx = null\r\n\r\n if (!param.is_wx_) {\r\n let canvas = document.createElement('canvas')\r\n canvas.width = w\r\n canvas.height = h\r\n // canvas.style.width = `${w}px`\r\n // canvas.style.height = `${h}px`\r\n\r\n ctx = canvas.getContext('2d')\r\n\r\n draw_(ctx, w, h, param.font_)\r\n\r\n // { // test\r\n // canvas.style.position = 'absolute'\r\n // document.body.appendChild(canvas)\r\n // }\r\n\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_3__.CanvasTexture(canvas)\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_3__.sRGBEncoding\r\n // tex.minFilter = LinearFilter\r\n // tex.magFilter = LinearFilter\r\n tex.needsUpdate = true\r\n\r\n // console.log(tex)\r\n this.map = tex\r\n\r\n } else {\r\n\r\n // let canvas = wx.createOffscreenCanvas({ type: '2d', width: w, height: h })\r\n // console.log('wx canvas', canvas)\r\n // setTimeout(() => {\r\n\r\n // ctx = canvas.getContext('2d')\r\n // // Unhandled promise rejection ReferenceError: ctx is not defined\r\n // // setTimeout -> ctx is not defined!\r\n // console.log('wx ctx', ctx)\r\n\r\n // }, 0)\r\n\r\n let canvas = param.canvas2__\r\n canvas.width = w\r\n canvas.height = h\r\n // console.log(canvas)\r\n\r\n ctx = canvas.getContext('2d')\r\n\r\n draw_(ctx, w, h, param.font_)\r\n\r\n // wx.canvasGetImageData({\r\n // // 'canvas2'\r\n // canvasId: canvas._canvasId, // it's really a joke API, sb wx!\r\n // x: 0,\r\n // y: 0,\r\n // width: w,\r\n // height: h,\r\n // success(res) {\r\n // console.log('xxxxxxxxxxxxxx', res)\r\n // }\r\n // })\r\n\r\n // console.log(canvas.toDataURL('image/png')) // OK\r\n // console.log(canvas.createImage()) // return
\r\n\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_3__.TextureLoader().load(canvas.toDataURL('image/png'))\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_3__.sRGBEncoding\r\n // console.log(tex)\r\n\r\n // let tex = new CanvasTexture(canvas)\r\n // tex.minFilter = LinearFilter\r\n // tex.magFilter = LinearFilter\r\n // tex.needsUpdate = true\r\n // console.log(tex)\r\n\r\n this.map = tex\r\n\r\n }\r\n\r\n // this.uvt2_ = new Matrix3()\r\n // this.uvt2_.setUvTransform(\r\n // tex_col * .5, 1 - 32 / 1024 * (tex_row + 1) - 6 / 1024,\r\n // (32 - 3) * text_count / 1024, 32 / 1024,\r\n // 0, 0, 0)\r\n\r\n this.update_text_ = txt => {\r\n // console.log('update_text_', txt)\r\n this.param_.text = txt\r\n draw_(ctx, w, h, param.font_)\r\n this.map.needsUpdate = true\r\n }\r\n\r\n }\r\n\r\n replace_vertex_shader_(so) {\r\n so.vertexShader = so.vertexShader.replace('#include ', `\r\n uniform int perspType;\r\n uniform float no_persp_near;\r\n uniform float no_persp_far;\r\n uniform float no_persp_far_scale;\r\n #include \r\n `);\r\n\r\n so.vertexShader = so.vertexShader.replace('if ( isPerspective ) scale *= - mvPosition.z;', `\r\n ${kutsi_glsl_persp_type_part_glsl__WEBPACK_IMPORTED_MODULE_2__[\"default\"]}\r\n `)\r\n }\r\n\r\n onBeforeCompile(so, renderer) {\r\n // console.log(so)\r\n so.uniforms.textColor = {\r\n value: new three__WEBPACK_IMPORTED_MODULE_3__.Color(this.param_.textColor)\r\n }\r\n so.uniforms.scale_u = {\r\n value: this.scale_u_\r\n }\r\n\r\n so.uniforms.perspType = {\r\n value: this.param_.perspType\r\n }\r\n\r\n so.uniforms.no_persp_near = {\r\n value: this.param_.no_persp_near\r\n }\r\n\r\n so.uniforms.no_persp_far = {\r\n value: this.param_.no_persp_far\r\n }\r\n\r\n so.uniforms.no_persp_far_scale = {\r\n value: this.param_.no_persp_far_scale\r\n }\r\n\r\n this.replace_vertex_shader_(so)\r\n // console.log(so.vertexShader)\r\n\r\n so.fragmentShader = so.fragmentShader.replace('#include ', `\r\n #include \r\n uniform vec3 textColor;\r\n uniform float scale_u;\r\n `)\r\n\r\n // 说明:>= 0.137.0 map_fragement.glsl.js改写,取消mapTexelToLinear\r\n // https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js\r\n const inline_sRGB_decode = parseInt(three__WEBPACK_IMPORTED_MODULE_3__.REVISION) >= 137 ? '' : 'texelColor509 = mapTexelToLinear( texelColor509 );'\r\n\r\n so.fragmentShader = so.fragmentShader.replace('#include ', `\r\n // #include \r\n \r\n vec4 texelColor509 = texture2D( map, vUv * vec2(scale_u, 1.)); // text\r\n ${inline_sRGB_decode}\r\n // diffuseColor.xyz = mix( diffuseColor.xyz, textColor, texelColor509.w);\r\n diffuseColor = mix( diffuseColor, vec4(textColor, 1.), texelColor509.w);\r\n `)\r\n\r\n // console.log(so.fragmentShader)\r\n }\r\n\r\n}\r\n\r\n// #20220117,不同于red valley中的偏移版本,由bubble sprite与pamir map中的LabelO3d合写而成\r\n// #20220302,shelves,three@0.137.5 出现 shader 错误\r\nclass TextSprite extends three__WEBPACK_IMPORTED_MODULE_3__.Sprite {\r\n\r\n constructor(param0, param) {\r\n\r\n param = Object.assign({\r\n text: '新炊间黄粱',\r\n\r\n textColor: 0xffffff,\r\n\r\n fontSize: 24,\r\n margin: 4,\r\n\r\n is_wx_: false,\r\n canvas2__: null, // for wx!\r\n\r\n center_x: .5,\r\n center_y: 0,\r\n\r\n perspType: kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.NoPersp,\r\n no_persp_near: 100,\r\n no_persp_far: 400,\r\n no_persp_far_scale: .618,\r\n\r\n noPerspScale: .0185,\r\n\r\n // #20220621, for shelves v3 / TextPlaneSprite\r\n clzMaterial_: TextSpriteMaterial\r\n }, param)\r\n\r\n param.font_ = `normal 100 ${param.fontSize}px Microsoft YaHei`\r\n param.measure_ = measure_(param.font_, param.text, param.is_wx_, param.canvas2__)\r\n let w = param.measure_.width + param.margin + param.margin\r\n let h = param.fontSize + param.margin + param.margin\r\n\r\n super(new param.clzMaterial_(param0, param))\r\n\r\n if (param.perspType == kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.Persp) {\r\n this.scale.set(100, 100, 1)\r\n } else {\r\n // NoPersp, NearFarPersp\r\n // let s = .0185\r\n let s = param.noPerspScale\r\n this.scale.set(s * w / h, s, 1)\r\n }\r\n\r\n // this.center.set(.5, -.25)\r\n this.center.set(param.center_x, param.center_y)\r\n }\r\n\r\n // #20220909, for hvac\r\n updateText(txt) {\r\n this.material.update_text_(txt)\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-red-valley/crossyo/kutsi/o3d/TextSprite.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TextSpriteMaterial\": () => (/* binding */ TextSpriteMaterial),\n/* harmony export */ \"default\": () => (/* binding */ TextSprite)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/util/MathUtil */ \"./src-kutsi/crossyo/kutsi/util/MathUtil.js\");\n/* harmony import */ var kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/PerspUtil */ \"./src-kutsi/crossyo/kutsi/util/PerspUtil.js\");\n/* harmony import */ var kutsi_glsl_persp_type_part_glsl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/glsl/persp-type-part.glsl */ \"./src-kutsi/crossyo/kutsi/glsl/persp-type-part.glsl\");\n\r\n\r\n\r\n\r\n\r\n\r\n// TODO 不包括wx部分\r\nlet ctx_measure_ = null\r\nconst measure_ = (font, txt, is_wx, canvas2) => {\r\n if (!ctx_measure_) {\r\n if (!is_wx) {\r\n let canvas = document.createElement('canvas')\r\n ctx_measure_ = canvas.getContext('2d')\r\n } else {\r\n ctx_measure_ = canvas2.getContext('2d')\r\n }\r\n }\r\n ctx_measure_.font = font\r\n return ctx_measure_.measureText(txt)\r\n}\r\n\r\nclass TextSpriteMaterial extends three__WEBPACK_IMPORTED_MODULE_3__.SpriteMaterial {\r\n constructor(param0, param) {\r\n\r\n super(Object.assign({\r\n // map: get_tex_(),\r\n color: 0x000000, // background!\r\n opacity: .6,\r\n toneMapped: false,\r\n depthWrite: false,\r\n depthTest: false,\r\n }, param0))\r\n\r\n this.param_ = param\r\n\r\n this.sizeAttenuation = this.param_.perspType == kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.Persp\r\n\r\n const draw_ = (ctx, w, h, font) => {\r\n\r\n ctx.clearRect(0, 0, w, h)\r\n ctx.font = font\r\n ctx.fillStyle = 'rgba(255,255,255,1)'\r\n ctx.fillText(param.text, param.margin, param.fontSize)\r\n\r\n }\r\n\r\n let w0 = param.measure_.width + param.margin + param.margin\r\n let w = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__.ceilPowerOfTwo)(w0)\r\n this.scale_u_ = w0 / w\r\n let h = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_0__.ceilPowerOfTwo)(param.fontSize + param.margin + param.margin)\r\n\r\n // console.log('', param.text)\r\n // console.log('est w x h:', w, h)\r\n\r\n let ctx = null\r\n\r\n if (!param.is_wx_) {\r\n let canvas = document.createElement('canvas')\r\n canvas.width = w\r\n canvas.height = h\r\n // canvas.style.width = `${w}px`\r\n // canvas.style.height = `${h}px`\r\n\r\n ctx = canvas.getContext('2d')\r\n\r\n draw_(ctx, w, h, param.font_)\r\n\r\n // { // test\r\n // canvas.style.position = 'absolute'\r\n // document.body.appendChild(canvas)\r\n // }\r\n\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_3__.CanvasTexture(canvas)\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_3__.sRGBEncoding\r\n // tex.minFilter = LinearFilter\r\n // tex.magFilter = LinearFilter\r\n tex.needsUpdate = true\r\n\r\n // console.log(tex)\r\n this.map = tex\r\n\r\n } else {\r\n\r\n // let canvas = wx.createOffscreenCanvas({ type: '2d', width: w, height: h })\r\n // console.log('wx canvas', canvas)\r\n // setTimeout(() => {\r\n\r\n // ctx = canvas.getContext('2d')\r\n // // Unhandled promise rejection ReferenceError: ctx is not defined\r\n // // setTimeout -> ctx is not defined!\r\n // console.log('wx ctx', ctx)\r\n\r\n // }, 0)\r\n\r\n let canvas = param.canvas2__\r\n canvas.width = w\r\n canvas.height = h\r\n // console.log(canvas)\r\n\r\n ctx = canvas.getContext('2d')\r\n\r\n draw_(ctx, w, h, param.font_)\r\n\r\n // wx.canvasGetImageData({\r\n // // 'canvas2'\r\n // canvasId: canvas._canvasId, // it's really a joke API, sb wx!\r\n // x: 0,\r\n // y: 0,\r\n // width: w,\r\n // height: h,\r\n // success(res) {\r\n // console.log('xxxxxxxxxxxxxx', res)\r\n // }\r\n // })\r\n\r\n // console.log(canvas.toDataURL('image/png')) // OK\r\n // console.log(canvas.createImage()) // return
\r\n\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_3__.TextureLoader().load(canvas.toDataURL('image/png'))\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_3__.sRGBEncoding\r\n // console.log(tex)\r\n\r\n // let tex = new CanvasTexture(canvas)\r\n // tex.minFilter = LinearFilter\r\n // tex.magFilter = LinearFilter\r\n // tex.needsUpdate = true\r\n // console.log(tex)\r\n\r\n this.map = tex\r\n\r\n }\r\n\r\n // this.uvt2_ = new Matrix3()\r\n // this.uvt2_.setUvTransform(\r\n // tex_col * .5, 1 - 32 / 1024 * (tex_row + 1) - 6 / 1024,\r\n // (32 - 3) * text_count / 1024, 32 / 1024,\r\n // 0, 0, 0)\r\n\r\n this.update_text_ = txt => {\r\n // console.log('update_text_', txt)\r\n this.param_.text = txt\r\n draw_(ctx, w, h, param.font_)\r\n this.map.needsUpdate = true\r\n }\r\n\r\n }\r\n\r\n replace_vertex_shader_(so) {\r\n so.vertexShader = so.vertexShader.replace('#include ', `\r\n uniform int perspType;\r\n uniform float no_persp_near;\r\n uniform float no_persp_far;\r\n uniform float no_persp_far_scale;\r\n #include \r\n `);\r\n\r\n so.vertexShader = so.vertexShader.replace('if ( isPerspective ) scale *= - mvPosition.z;', `\r\n ${kutsi_glsl_persp_type_part_glsl__WEBPACK_IMPORTED_MODULE_2__[\"default\"]}\r\n `)\r\n }\r\n\r\n onBeforeCompile(so, renderer) {\r\n // console.log(so)\r\n so.uniforms.textColor = {\r\n value: new three__WEBPACK_IMPORTED_MODULE_3__.Color(this.param_.textColor)\r\n }\r\n so.uniforms.scale_u = {\r\n value: this.scale_u_\r\n }\r\n\r\n so.uniforms.perspType = {\r\n value: this.param_.perspType\r\n }\r\n\r\n so.uniforms.no_persp_near = {\r\n value: this.param_.no_persp_near\r\n }\r\n\r\n so.uniforms.no_persp_far = {\r\n value: this.param_.no_persp_far\r\n }\r\n\r\n so.uniforms.no_persp_far_scale = {\r\n value: this.param_.no_persp_far_scale\r\n }\r\n\r\n this.replace_vertex_shader_(so)\r\n // console.log(so.vertexShader)\r\n\r\n so.fragmentShader = so.fragmentShader.replace('#include ', `\r\n #include \r\n uniform vec3 textColor;\r\n uniform float scale_u;\r\n `)\r\n\r\n // 说明:>= 0.137.0 map_fragement.glsl.js改写,取消mapTexelToLinear\r\n // https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js\r\n const inline_sRGB_decode = parseInt(three__WEBPACK_IMPORTED_MODULE_3__.REVISION) >= 137 ? '' : 'texelColor509 = mapTexelToLinear( texelColor509 );'\r\n\r\n so.fragmentShader = so.fragmentShader.replace('#include ', `\r\n // #include \r\n \r\n vec4 texelColor509 = texture2D( map, vUv * vec2(scale_u, 1.)); // text\r\n ${inline_sRGB_decode}\r\n // diffuseColor.xyz = mix( diffuseColor.xyz, textColor, texelColor509.w);\r\n diffuseColor = mix( diffuseColor, vec4(textColor, 1.), texelColor509.w);\r\n `)\r\n\r\n // console.log(so.fragmentShader)\r\n }\r\n\r\n}\r\n\r\n// #20220117,不同于red valley中的偏移版本,由bubble sprite与pamir map中的LabelO3d合写而成\r\n// #20220302,shelves,three@0.137.5 出现 shader 错误\r\nclass TextSprite extends three__WEBPACK_IMPORTED_MODULE_3__.Sprite {\r\n\r\n constructor(param0, param) {\r\n\r\n param = Object.assign({\r\n text: '新炊间黄粱',\r\n\r\n textColor: 0xffffff,\r\n\r\n fontSize: 24,\r\n margin: 4,\r\n\r\n is_wx_: false,\r\n canvas2__: null, // for wx!\r\n\r\n center_x: .5,\r\n center_y: 0,\r\n\r\n perspType: kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.NoPersp,\r\n no_persp_near: 100,\r\n no_persp_far: 400,\r\n no_persp_far_scale: .618,\r\n\r\n noPerspScale: .0185,\r\n\r\n // #20220621, for shelves v3 / TextPlaneSprite\r\n clzMaterial_: TextSpriteMaterial\r\n }, param)\r\n\r\n param.font_ = `normal 100 ${param.fontSize}px Microsoft YaHei`\r\n param.measure_ = measure_(param.font_, param.text, param.is_wx_, param.canvas2__)\r\n let w = param.measure_.width + param.margin + param.margin\r\n let h = param.fontSize + param.margin + param.margin\r\n\r\n super(new param.clzMaterial_(param0, param))\r\n\r\n if (param.perspType == kutsi_util_PerspUtil__WEBPACK_IMPORTED_MODULE_1__.PerspType.Persp) {\r\n this.scale.set(100, 100, 1)\r\n } else {\r\n // NoPersp, NearFarPersp\r\n // let s = .0185\r\n let s = param.noPerspScale\r\n this.scale.set(s * w / h, s, 1)\r\n }\r\n\r\n // this.center.set(.5, -.25)\r\n this.center.set(param.center_x, param.center_y)\r\n }\r\n\r\n // #20220909, for hvac\r\n updateText(txt) {\r\n this.material.update_text_(txt)\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-red-valley/crossyo/kutsi/o3d/TextSprite.js?");
/***/ }),
@@ -124,7 +124,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ ElasticFreeLookControls)\n/* harmony export */ });\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n/* harmony import */ var _FreeLookTurnControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FreeLookTurnControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookTurnControls.js\");\n/* harmony import */ var kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/util/MathUtil */ \"./src-kutsi/crossyo/kutsi/util/MathUtil.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n// import FreeLookControls from './FreeLookControls'\r\n\r\n\r\n\r\n\r\n\r\n/*\r\nshelves 示例\r\n\r\nnew ElasticFreeLookControls (this.camera_, this.renderer_.domElement, {\r\n lookDirection: -1, // 方向\r\n elasticDirection: target,\r\n zoomResetFunction: e => {\r\n return e.object.zoomFov\r\n },\r\n zoomFunction: e => {\r\n e.object.zoomFov = e.zoom2\r\n },\r\n zoomMin: .5,\r\n zoomMax: 1,\r\n})\r\n\r\nBaseControls\r\n\tPointerBaseControls / Pointers\r\n\t\tFreeLookControls\r\n\t\t\tElasticFreeLookControls\r\n\r\n*/\r\nclass ElasticFreeLookControls extends _FreeLookTurnControls__WEBPACK_IMPORTED_MODULE_1__.FreeLookTurnControls {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n this.elDir_ = null;\r\n if (this.opts_.elasticDirection) {\r\n this.elasticDirection = this.opts_.elasticDirection\r\n }\r\n this.EL_COUNTDOWN_ = 1; //s\r\n }\r\n\r\n set elasticDirection(v) {\r\n this.elDir_ = v;\r\n if (v) {\r\n this.elOri_ = this.to_ori__(v);\r\n } else {\r\n this.elOri_ = null;\r\n }\r\n }\r\n\r\n get elasticDirection() {\r\n return this.elDir_;\r\n }\r\n\r\n update(delta) {\r\n\r\n if (!this.enabled_) {\r\n return\r\n }\r\n\r\n if (this.hasState(kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__.STATE.LOOK)) {\r\n this.update_quat_()\r\n } else {\r\n if (this.el_countdown_ > 0 && this.elOri_) {\r\n this.el_countdown_ -= delta\r\n var ut = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_2__.easeOutQuad)(1 - Math.max(0, this.el_countdown_) / this.EL_COUNTDOWN_, 0, 1, 1)\r\n // 0 ~ 1\r\n this.ori_.y = three__WEBPACK_IMPORTED_MODULE_3__.MathUtils.lerp(this.eflc_look_end_ori_.y, this.elOri_.y, ut)\r\n this.ori_.x = three__WEBPACK_IMPORTED_MODULE_3__.MathUtils.lerp(this.eflc_look_end_ori_.x, this.elOri_.x, ut)\r\n this.update_quat_()\r\n }\r\n }\r\n\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // private \r\n\r\n flc_look_end_() {\r\n this.eflc_look_end_ori_ = {\r\n y: this.ori_.y,\r\n x: this.ori_.x,\r\n };\r\n this.el_countdown_ = this.EL_COUNTDOWN_;\r\n super.flc_look_end_();\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/ElasticFreeLookControls.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ ElasticFreeLookControls)\n/* harmony export */ });\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n/* harmony import */ var _FreeLookTurnControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FreeLookTurnControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookTurnControls.js\");\n/* harmony import */ var kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/util/MathUtil */ \"./src-kutsi/crossyo/kutsi/util/MathUtil.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n// import FreeLookControls from './FreeLookControls'\r\n\r\n\r\n\r\n\r\n\r\n/*\r\nshelves 示例\r\n\r\nnew ElasticFreeLookControls (this.camera_, this.renderer_.domElement, {\r\n lookDirection: -1, // 方向\r\n elasticDirection: target,\r\n zoomResetFunction: e => {\r\n return e.object.zoomFov\r\n },\r\n zoomFunction: e => {\r\n e.object.zoomFov = e.zoom2\r\n },\r\n zoomMin: .5,\r\n zoomMax: 1,\r\n})\r\n\r\nBaseControls\r\n\tPointerBaseControls / Pointers\r\n\t\tFreeLookControls\r\n\t\t\tElasticFreeLookControls\r\n\r\n*/\r\nclass ElasticFreeLookControls extends _FreeLookTurnControls__WEBPACK_IMPORTED_MODULE_1__.FreeLookTurnControls {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n this.elDir_ = null;\r\n if (this.opts_.elasticDirection) {\r\n this.elasticDirection = this.opts_.elasticDirection\r\n }\r\n this.EL_COUNTDOWN_ = 1; //s\r\n }\r\n\r\n set elasticDirection(v) {\r\n this.elDir_ = v;\r\n if (v) {\r\n this.elOri_ = this.to_ori__(v);\r\n } else {\r\n this.elOri_ = null;\r\n }\r\n }\r\n\r\n get elasticDirection() {\r\n return this.elDir_;\r\n }\r\n\r\n update(delta) {\r\n\r\n if (!this.enabled_) {\r\n return\r\n }\r\n\r\n if (this.hasState(kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__.STATE.LOOK)) {\r\n this.update_quat_()\r\n } else {\r\n if (this.el_countdown_ > 0 && this.elOri_) {\r\n this.el_countdown_ -= delta\r\n var ut = (0,kutsi_util_MathUtil__WEBPACK_IMPORTED_MODULE_2__.easeOutQuad)(1 - Math.max(0, this.el_countdown_) / this.EL_COUNTDOWN_, 0, 1, 1)\r\n // 0 ~ 1\r\n this.ori_.y = three__WEBPACK_IMPORTED_MODULE_3__.MathUtils.lerp(this.eflc_look_end_ori_.y, this.elOri_.y, ut)\r\n this.ori_.x = three__WEBPACK_IMPORTED_MODULE_3__.MathUtils.lerp(this.eflc_look_end_ori_.x, this.elOri_.x, ut)\r\n this.update_quat_()\r\n }\r\n }\r\n\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // private \r\n\r\n flc_look_end_() {\r\n this.eflc_look_end_ori_ = {\r\n y: this.ori_.y,\r\n x: this.ori_.x,\r\n };\r\n this.el_countdown_ = this.EL_COUNTDOWN_;\r\n super.flc_look_end_();\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/ElasticFreeLookControls.js?");
/***/ }),
@@ -135,7 +135,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"fovZoomFunction\": () => (/* binding */ fovZoomFunction),\n/* harmony export */ \"fovZoomResetFunction\": () => (/* binding */ fovZoomResetFunction)\n/* harmony export */ });\n/* harmony import */ var _PointerBaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PointerBaseControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/PointerBaseControls.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n\r\n\r\n\r\n\r\n\r\n// import { runtime } from 'kutsi/runtime'\r\n\r\n/**\r\n * @class\r\n * @extends PointersBaseControls\r\n * @memberof module:pamir_base\r\n */\r\nclass FreeLookControls extends _PointerBaseControls__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n\r\n this.opts_ = Object.assign({\r\n lookDirection: 1,// #20220228, 1(like orbit direction!) or -1\r\n lookSpeed: 1, // #20220302\r\n zoomResetFunction: null, //\r\n zoomFunction: null, // ()=>{} or fovZoomFunction\r\n zoomMin: 1e-3,\r\n zoomMax: 1e3,\r\n }, opts)\r\n\r\n this.quat_ = {\r\n x: new three__WEBPACK_IMPORTED_MODULE_2__.Quaternion(),\r\n y: new three__WEBPACK_IMPORTED_MODULE_2__.Quaternion()\r\n }\r\n this.xvec_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(1, 0, 0)\r\n this.yvec_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 1, 0)\r\n this.ori_ = {\r\n x: 0,\r\n y: 0\r\n }\r\n this.target_ = null\r\n\r\n }\r\n\r\n set lookSpeed(v) {\r\n this.opts_.lookSpeed = v\r\n }\r\n\r\n get lookSpeed() {\r\n return this.opts_.lookSpeed\r\n }\r\n\r\n update(delta) {\r\n\r\n if (!this.enabled_) {\r\n return;\r\n }\r\n\r\n if (this.hasState(kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK)) {\r\n this.update_quat_()\r\n }\r\n\r\n }\r\n\r\n get target() { // 可能会用到!\r\n if (this.target_) {\r\n return this.target_\r\n } else {\r\n // console.log('get target is none! calc', new Vector3().addVectors(this.object_.position, this.direction));\r\n return new three__WEBPACK_IMPORTED_MODULE_2__.Vector3().addVectors(this.object_.position, this.direction)\r\n }\r\n }\r\n\r\n set target(v) {\r\n // console.log('#### FreeLookControls set target', v)\r\n this.target_ = v\r\n var dpos = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3().subVectors(v, this.object_.position)\r\n if (dpos.lengthSq() < 0.00001) {\r\n return\r\n }\r\n // this.ori_.y = -Math.atan2(dpos.x, -dpos.z); // Yaw\r\n // // #20180908,Samuel,E,Pitch\r\n // this.ori_.x = Math.atan2(dpos.y, Math.sqrt(dpos.x * dpos.x + dpos.z * dpos.z))\r\n // // console.log('FreeLook set target', v, dpos, this.ori_)\r\n this.ori_ = this.to_ori__(dpos)\r\n this.update_quat_()\r\n }\r\n\r\n get direction() {\r\n return new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, -1).applyQuaternion(this.object_.quaternion)\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // override\r\n\r\n reset() {\r\n super.reset()\r\n if (this.target0) {\r\n this.target = this.target0.clone()\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n\r\n pbc_reset__() {\r\n this.flc_shared_ = {\r\n look_xy: null,\r\n zoom: 1,\r\n zoom2: 1,\r\n p2: null,\r\n p2_dist: 0,\r\n }\r\n if (this.opts_.zoomResetFunction) {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2 = this.opts_.zoomResetFunction({ object: this.object_ })\r\n }\r\n }\r\n pbc_down__(event) {\r\n if (event.button == 0) {\r\n event.preventDefault()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK\r\n this.flc_shared_.look_xy = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY)\r\n this.flc_look_begin_(this.flc_shared_.look_xy)\r\n }\r\n }\r\n pbc_touch_start__(event, po) {\r\n if (po._pointers.length == 1) {\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK\r\n let pp0 = po._pointers[0]\r\n this.flc_shared_.look_xy = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(pp0.offsetX, pp0.offsetY)\r\n this.flc_look_begin_(this.flc_shared_.look_xy)\r\n } else { // >= 2\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.ZOOM\r\n let p2 = [\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(po._pointers[0].offsetX, po._pointers[0].offsetY),\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(po._pointers[1].offsetX, po._pointers[1].offsetY)\r\n ]\r\n this.flc_shared_.p2_dist = p2[0].distanceTo(p2[1])\r\n this.flc_shared_.p2 = p2\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom\r\n this.flc_zoom_begin_()\r\n }\r\n }\r\n pbc_move__(event) {\r\n if (this.flc_shared_.look_xy) {\r\n this.flc_look_move_(this.flc_shared_.look_xy, new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY))\r\n }\r\n }\r\n pbc_touch_move__(event, po) {\r\n if (this.state_ != kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE) {\r\n if (po._pointers.length == 1) {\r\n this.flc_look_move_(this.flc_shared_.look_xy, new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY))\r\n } else { // >= 2\r\n\r\n let p2n = [\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY),\r\n po.getSecondPointerPosition(event),\r\n ]\r\n let dist = p2n[0].distanceTo(p2n[1])\r\n // console.log(this.flc_shared_.p2_dist, dist)\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom * this.flc_shared_.p2_dist / dist\r\n this.flc_zoom_move_(this.flc_shared_.zoom, this.flc_shared_.zoom2)\r\n }\r\n }\r\n }\r\n ptc_up__(event) {\r\n this.flc_shared_.look_xy = null\r\n this.flc_look_end_()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n }\r\n pbc_touch_end__(event, po) {\r\n // console.log('pbc_touch_end__', event, po, po._pointers.length)\r\n if (po._pointers.length == 0) {\r\n this.flc_shared_.look_xy = null\r\n this.flc_look_end_()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n } else if (po._pointers.length == 1) {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2\r\n this.flc_zoom_end_()\r\n // this.state_ = STATE.LOOK // 容易产生尾迹\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n }\r\n }\r\n\r\n update_enabled_() {\r\n super.update_enabled_()\r\n if (!this.wheel_) {\r\n this.wheel_ = event => {\r\n event.preventDefault()\r\n let dz = 0\r\n switch (event.deltaMode) {\r\n case 2:\r\n // Zoom in pages\r\n dz = event.deltaY * 0.025 * 4;\r\n break;\r\n case 1:\r\n // Zoom in lines\r\n dz = event.deltaY * 0.01 * 4;\r\n break;\r\n default:\r\n // undefined, 0, assume pixels\r\n dz = event.deltaY * 0.00025 * 4;\r\n break;\r\n }\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom * (1 - dz)\r\n this.flc_zoom_move_()\r\n this.flc_zoom_end_()\r\n }\r\n }\r\n if (this.enabled_) {\r\n if (this.opts_.zoomFunction) {\r\n this.domElement_.addEventListener('wheel', this.wheel_, { passive: false })\r\n }\r\n } else {\r\n if (this.opts_.zoomFunction) {\r\n this.domElement_.removeEventListener('wheel', this.wheel_)\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // private\r\n\r\n update_quat_() {\r\n // console.log('update_quat_', this.ori_, this.object_.uuid)\r\n this.quat_.x.setFromAxisAngle(this.xvec_, this.ori_.x)\r\n this.quat_.y.setFromAxisAngle(this.yvec_, this.ori_.y)\r\n this.object_.quaternion.copy(this.quat_.y).multiply(this.quat_.x)\r\n }\r\n\r\n flc_look_begin_(xy1) {\r\n\r\n // 由于继承后继类会改变转向,所以每次启动drag时,最好计算一下当前的ori_0_\r\n this.ori_ = this.to_ori__(this.direction)\r\n this.ori_0_ = {\r\n x: this.ori_.x,\r\n y: this.ori_.y,\r\n }\r\n }\r\n\r\n flc_look_move_(xy1, xy2) {\r\n // console.log('drag_', xy1, xy2);\r\n let rsd = this.opts_.lookSpeed * this.opts_.lookDirection\r\n this.ori_.y = this.ori_0_.y - (xy2.x - xy1.x) * 0.0025 * rsd\r\n this.ori_.x = this.ori_0_.x - (xy2.y - xy1.y) * 0.0025 * rsd\r\n\r\n var PI_2 = Math.PI / 2;\r\n this.ori_.x = Math.max(-PI_2, Math.min(PI_2, this.ori_.x))\r\n\r\n }\r\n\r\n flc_look_end_() {\r\n }\r\n\r\n flc_zoom_begin_() {\r\n }\r\n\r\n flc_zoom_move_() {\r\n // restrict\r\n let z2 = this.flc_shared_.zoom2\r\n if (z2 < this.opts_.zoomMin) {\r\n this.flc_shared_.zoom2 = this.opts_.zoomMin\r\n } else if (z2 > this.opts_.zoomMax) {\r\n this.flc_shared_.zoom2 = this.opts_.zoomMax\r\n }\r\n this.opts_.zoomFunction({\r\n object: this.object_,\r\n zoom1: this.flc_shared_.zoom,\r\n zoom2: this.flc_shared_.zoom2,\r\n })\r\n }\r\n\r\n flc_zoom_end_() {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n\r\n to_ori__(dpos) {\r\n return {\r\n y: -Math.atan2(dpos.x, -dpos.z), // Yaw\r\n x: Math.atan2(dpos.y, Math.sqrt(dpos.x * dpos.x + dpos.z * dpos.z))\r\n }\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FreeLookControls);\r\n\r\nconst fovZoomResetFunction = e => {\r\n return e.object.fov\r\n}\r\nconst fovZoomFunction = e => {\r\n e.object.fov = e.zoom2\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookControls.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"fovZoomFunction\": () => (/* binding */ fovZoomFunction),\n/* harmony export */ \"fovZoomResetFunction\": () => (/* binding */ fovZoomResetFunction)\n/* harmony export */ });\n/* harmony import */ var _PointerBaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PointerBaseControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/PointerBaseControls.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n\r\n\r\n\r\n\r\n\r\n// import { runtime } from 'kutsi/runtime'\r\n\r\n/**\r\n * @class\r\n * @extends PointersBaseControls\r\n * @memberof module:pamir_base\r\n */\r\nclass FreeLookControls extends _PointerBaseControls__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n\r\n this.opts_ = Object.assign({\r\n lookDirection: 1,// #20220228, 1(like orbit direction!) or -1\r\n lookSpeed: 1, // #20220302\r\n zoomResetFunction: null, //\r\n zoomFunction: null, // ()=>{} or fovZoomFunction\r\n zoomMin: 1e-3,\r\n zoomMax: 1e3,\r\n }, opts)\r\n\r\n this.quat_ = {\r\n x: new three__WEBPACK_IMPORTED_MODULE_2__.Quaternion(),\r\n y: new three__WEBPACK_IMPORTED_MODULE_2__.Quaternion()\r\n }\r\n this.xvec_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(1, 0, 0)\r\n this.yvec_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 1, 0)\r\n this.ori_ = {\r\n x: 0,\r\n y: 0\r\n }\r\n this.target_ = null\r\n\r\n }\r\n\r\n set lookSpeed(v) {\r\n this.opts_.lookSpeed = v\r\n }\r\n\r\n get lookSpeed() {\r\n return this.opts_.lookSpeed\r\n }\r\n\r\n update(delta) {\r\n\r\n if (!this.enabled_) {\r\n return;\r\n }\r\n\r\n if (this.hasState(kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK)) {\r\n this.update_quat_()\r\n }\r\n\r\n }\r\n\r\n get target() { // 可能会用到!\r\n if (this.target_) {\r\n return this.target_\r\n } else {\r\n // console.log('get target is none! calc', new Vector3().addVectors(this.object_.position, this.direction));\r\n return new three__WEBPACK_IMPORTED_MODULE_2__.Vector3().addVectors(this.object_.position, this.direction)\r\n }\r\n }\r\n\r\n set target(v) {\r\n // console.log('#### FreeLookControls set target', v)\r\n this.target_ = v\r\n var dpos = new three__WEBPACK_IMPORTED_MODULE_2__.Vector3().subVectors(v, this.object_.position)\r\n if (dpos.lengthSq() < 0.00001) {\r\n return\r\n }\r\n // this.ori_.y = -Math.atan2(dpos.x, -dpos.z); // Yaw\r\n // // #20180908,Samuel,E,Pitch\r\n // this.ori_.x = Math.atan2(dpos.y, Math.sqrt(dpos.x * dpos.x + dpos.z * dpos.z))\r\n // // console.log('FreeLook set target', v, dpos, this.ori_)\r\n this.ori_ = this.to_ori__(dpos)\r\n this.update_quat_()\r\n }\r\n\r\n get direction() {\r\n return new three__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, -1).applyQuaternion(this.object_.quaternion)\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // override\r\n\r\n reset() {\r\n super.reset()\r\n if (this.target0) {\r\n this.target = this.target0.clone()\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n\r\n pbc_reset__() {\r\n this.flc_shared_ = {\r\n look_xy: null,\r\n zoom: 1,\r\n zoom2: 1,\r\n p2: null,\r\n p2_dist: 0,\r\n }\r\n if (this.opts_.zoomResetFunction) {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2 = this.opts_.zoomResetFunction({ object: this.object_ })\r\n }\r\n }\r\n pbc_down__(event) {\r\n if (event.button == 0) {\r\n event.preventDefault()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK\r\n this.flc_shared_.look_xy = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY)\r\n this.flc_look_begin_(this.flc_shared_.look_xy)\r\n }\r\n }\r\n pbc_touch_start__(event, po) {\r\n if (po._pointers.length == 1) {\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.LOOK\r\n let pp0 = po._pointers[0]\r\n this.flc_shared_.look_xy = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(pp0.offsetX, pp0.offsetY)\r\n this.flc_look_begin_(this.flc_shared_.look_xy)\r\n } else { // >= 2\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.ZOOM\r\n let p2 = [\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(po._pointers[0].offsetX, po._pointers[0].offsetY),\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(po._pointers[1].offsetX, po._pointers[1].offsetY)\r\n ]\r\n this.flc_shared_.p2_dist = p2[0].distanceTo(p2[1])\r\n this.flc_shared_.p2 = p2\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom\r\n this.flc_zoom_begin_()\r\n }\r\n }\r\n pbc_move__(event) {\r\n if (this.flc_shared_.look_xy) {\r\n this.flc_look_move_(this.flc_shared_.look_xy, new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY))\r\n }\r\n }\r\n pbc_touch_move__(event, po) {\r\n if (this.state_ != kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE) {\r\n if (po._pointers.length == 1) {\r\n this.flc_look_move_(this.flc_shared_.look_xy, new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY))\r\n } else { // >= 2\r\n\r\n let p2n = [\r\n new three__WEBPACK_IMPORTED_MODULE_2__.Vector2(event.offsetX, event.offsetY),\r\n po.getSecondPointerPosition(event),\r\n ]\r\n let dist = p2n[0].distanceTo(p2n[1])\r\n // console.log(this.flc_shared_.p2_dist, dist)\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom * this.flc_shared_.p2_dist / dist\r\n this.flc_zoom_move_(this.flc_shared_.zoom, this.flc_shared_.zoom2)\r\n }\r\n }\r\n }\r\n ptc_up__(event) {\r\n this.flc_shared_.look_xy = null\r\n this.flc_look_end_()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n }\r\n pbc_touch_end__(event, po) {\r\n // console.log('pbc_touch_end__', event, po, po._pointers.length)\r\n if (po._pointers.length == 0) {\r\n this.flc_shared_.look_xy = null\r\n this.flc_look_end_()\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n } else if (po._pointers.length == 1) {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2\r\n this.flc_zoom_end_()\r\n // this.state_ = STATE.LOOK // 容易产生尾迹\r\n this.state_ = kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_1__.STATE.NONE\r\n }\r\n }\r\n\r\n update_enabled_() {\r\n super.update_enabled_()\r\n if (!this.wheel_) {\r\n this.wheel_ = event => {\r\n event.preventDefault()\r\n let dz = 0\r\n switch (event.deltaMode) {\r\n case 2:\r\n // Zoom in pages\r\n dz = event.deltaY * 0.025 * 4;\r\n break;\r\n case 1:\r\n // Zoom in lines\r\n dz = event.deltaY * 0.01 * 4;\r\n break;\r\n default:\r\n // undefined, 0, assume pixels\r\n dz = event.deltaY * 0.00025 * 4;\r\n break;\r\n }\r\n this.flc_shared_.zoom2 = this.flc_shared_.zoom * (1 - dz)\r\n this.flc_zoom_move_()\r\n this.flc_zoom_end_()\r\n }\r\n }\r\n if (this.enabled_) {\r\n if (this.opts_.zoomFunction) {\r\n this.domElement_.addEventListener('wheel', this.wheel_, { passive: false })\r\n }\r\n } else {\r\n if (this.opts_.zoomFunction) {\r\n this.domElement_.removeEventListener('wheel', this.wheel_)\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // private\r\n\r\n update_quat_() {\r\n // console.log('update_quat_', this.ori_, this.object_.uuid)\r\n this.quat_.x.setFromAxisAngle(this.xvec_, this.ori_.x)\r\n this.quat_.y.setFromAxisAngle(this.yvec_, this.ori_.y)\r\n this.object_.quaternion.copy(this.quat_.y).multiply(this.quat_.x)\r\n }\r\n\r\n flc_look_begin_(xy1) {\r\n\r\n // 由于继承后继类会改变转向,所以每次启动drag时,最好计算一下当前的ori_0_\r\n this.ori_ = this.to_ori__(this.direction)\r\n this.ori_0_ = {\r\n x: this.ori_.x,\r\n y: this.ori_.y,\r\n }\r\n }\r\n\r\n flc_look_move_(xy1, xy2) {\r\n // console.log('drag_', xy1, xy2);\r\n let rsd = this.opts_.lookSpeed * this.opts_.lookDirection\r\n this.ori_.y = this.ori_0_.y - (xy2.x - xy1.x) * 0.0025 * rsd\r\n this.ori_.x = this.ori_0_.x - (xy2.y - xy1.y) * 0.0025 * rsd\r\n\r\n var PI_2 = Math.PI / 2;\r\n this.ori_.x = Math.max(-PI_2, Math.min(PI_2, this.ori_.x))\r\n\r\n }\r\n\r\n flc_look_end_() {\r\n }\r\n\r\n flc_zoom_begin_() {\r\n }\r\n\r\n flc_zoom_move_() {\r\n // restrict\r\n let z2 = this.flc_shared_.zoom2\r\n if (z2 < this.opts_.zoomMin) {\r\n this.flc_shared_.zoom2 = this.opts_.zoomMin\r\n } else if (z2 > this.opts_.zoomMax) {\r\n this.flc_shared_.zoom2 = this.opts_.zoomMax\r\n }\r\n this.opts_.zoomFunction({\r\n object: this.object_,\r\n zoom1: this.flc_shared_.zoom,\r\n zoom2: this.flc_shared_.zoom2,\r\n })\r\n }\r\n\r\n flc_zoom_end_() {\r\n this.flc_shared_.zoom = this.flc_shared_.zoom2\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n\r\n to_ori__(dpos) {\r\n return {\r\n y: -Math.atan2(dpos.x, -dpos.z), // Yaw\r\n x: Math.atan2(dpos.y, Math.sqrt(dpos.x * dpos.x + dpos.z * dpos.z))\r\n }\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FreeLookControls);\r\n\r\nconst fovZoomResetFunction = e => {\r\n return e.object.fov\r\n}\r\nconst fovZoomFunction = e => {\r\n e.object.fov = e.zoom2\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookControls.js?");
/***/ }),
@@ -157,7 +157,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n\r\n\r\n\r\nclass Pointers {\r\n\r\n // rewrite from \r\n // https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TrackballControls.js\r\n\r\n constructor() {\r\n this.reset()\r\n }\r\n\r\n reset() {\r\n this._pointers = []\r\n this._pointerPositions = {}\r\n }\r\n\r\n addPointer(event) {\r\n this._pointers.push(event)\r\n }\r\n\r\n removePointer(event) {\r\n delete this._pointerPositions[event.pointerId]\r\n for (let i = 0; i < this._pointers.length; i++) {\r\n if (this._pointers[i].pointerId == event.pointerId) {\r\n this._pointers.splice(i, 1)\r\n return\r\n }\r\n }\r\n }\r\n\r\n trackPointer(event) {\r\n let position = this._pointerPositions[event.pointerId]\r\n if (position === undefined) {\r\n position = new three__WEBPACK_IMPORTED_MODULE_1__.Vector2()\r\n this._pointerPositions[event.pointerId] = position\r\n }\r\n position.set(event.offsetX, event.offsetY)\r\n }\r\n\r\n getSecondPointerPosition(event) {\r\n const pointer = (event.pointerId === this._pointers[0].pointerId) ? this._pointers[1] : this._pointers[0]\r\n return this._pointerPositions[pointer.pointerId]\r\n }\r\n\r\n}\r\n\r\nclass PointerBaseControls extends kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n }\r\n\r\n // pbc_reset__() { }\r\n // pbc_down__(event) {}\r\n // pbc_touch_start__(event, pointers) {}\r\n // pbc_move__(event) {}\r\n // pbc_touch_move__(event, pointers) {}\r\n // ptc_up__(event) {}\r\n // pbc_touch_end__(event, pointers) {}\r\n\r\n update_enabled_() {\r\n super.update_enabled_()\r\n\r\n if (!this.pbc_evts_) {\r\n let po = new Pointers()\r\n this.pbc_evts_ = {\r\n reset: () => {\r\n po.reset()\r\n this.pbc_reset__()\r\n },\r\n down: event => {\r\n if (this.domElement_.tabIndex < 0) {\r\n this.domElement_.tabIndex = 1\r\n }\r\n // console.log('this.domElement_.tabIndex', this.domElement_.tabIndex);\r\n this.domElement_.focus()\r\n\r\n if (event.pointerType == 'touch') {\r\n if (po._pointers.length == 0) {\r\n this.domElement_.setPointerCapture(event.pointerId)\r\n }\r\n po.addPointer(event)\r\n po.trackPointer(event)\r\n this.pbc_touch_start__(event, po)\r\n } else {\r\n this.pbc_down__(event)\r\n }\r\n },\r\n move: event => {\r\n if (event.pointerType == 'touch') {\r\n po.trackPointer(event)\r\n this.pbc_touch_move__(event, po)\r\n } else {\r\n this.pbc_move__(event)\r\n }\r\n },\r\n up: event => {\r\n if (event.pointerType == 'touch') {\r\n po.removePointer(event)\r\n this.pbc_touch_end__(event, po)\r\n if (po._pointers.length == 0) {\r\n this.domElement_.releasePointerCapture(event.pointerId)\r\n }\r\n } else {\r\n this.ptc_up__(event)\r\n }\r\n },\r\n cancel: event => {\r\n po.removePointer(event)\r\n },\r\n }\r\n }\r\n\r\n if (this.enabled_) {\r\n // console.log(this.domElement_)\r\n this.pbc_evts_.reset()\r\n this.domElement_.addEventListener('pointerdown', this.pbc_evts_.down)\r\n this.domElement_.addEventListener('pointermove', this.pbc_evts_.move)\r\n this.domElement_.addEventListener('pointerup', this.pbc_evts_.up)\r\n this.domElement_.addEventListener('pointercancel', this.pbc_evts_.cancel)\r\n } else {\r\n this.domElement_.removeEventListener('pointercancel', this.pbc_evts_.cancel)\r\n this.domElement_.removeEventListener('pointerup', this.pbc_evts_.up)\r\n this.domElement_.removeEventListener('pointermove', this.pbc_evts_.move)\r\n this.domElement_.removeEventListener('pointerdown', this.pbc_evts_.down)\r\n }\r\n\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PointerBaseControls);\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/PointerBaseControls.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/controls/BaseControls */ \"./src-kutsi/crossyo/kutsi/controls/BaseControls.js\");\n\r\n\r\n\r\nclass Pointers {\r\n\r\n // rewrite from \r\n // https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TrackballControls.js\r\n\r\n constructor() {\r\n this.reset()\r\n }\r\n\r\n reset() {\r\n this._pointers = []\r\n this._pointerPositions = {}\r\n }\r\n\r\n addPointer(event) {\r\n this._pointers.push(event)\r\n }\r\n\r\n removePointer(event) {\r\n delete this._pointerPositions[event.pointerId]\r\n for (let i = 0; i < this._pointers.length; i++) {\r\n if (this._pointers[i].pointerId == event.pointerId) {\r\n this._pointers.splice(i, 1)\r\n return\r\n }\r\n }\r\n }\r\n\r\n trackPointer(event) {\r\n let position = this._pointerPositions[event.pointerId]\r\n if (position === undefined) {\r\n position = new three__WEBPACK_IMPORTED_MODULE_1__.Vector2()\r\n this._pointerPositions[event.pointerId] = position\r\n }\r\n position.set(event.offsetX, event.offsetY)\r\n }\r\n\r\n getSecondPointerPosition(event) {\r\n const pointer = (event.pointerId === this._pointers[0].pointerId) ? this._pointers[1] : this._pointers[0]\r\n return this._pointerPositions[pointer.pointerId]\r\n }\r\n\r\n}\r\n\r\nclass PointerBaseControls extends kutsi_controls_BaseControls__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n constructor(object, domElement, opts) {\r\n super(object, domElement, opts)\r\n }\r\n\r\n // pbc_reset__() { }\r\n // pbc_down__(event) {}\r\n // pbc_touch_start__(event, pointers) {}\r\n // pbc_move__(event) {}\r\n // pbc_touch_move__(event, pointers) {}\r\n // ptc_up__(event) {}\r\n // pbc_touch_end__(event, pointers) {}\r\n\r\n update_enabled_() {\r\n super.update_enabled_()\r\n\r\n if (!this.pbc_evts_) {\r\n let po = new Pointers()\r\n this.pbc_evts_ = {\r\n reset: () => {\r\n po.reset()\r\n this.pbc_reset__()\r\n },\r\n down: event => {\r\n if (this.domElement_.tabIndex < 0) {\r\n this.domElement_.tabIndex = 1\r\n }\r\n // console.log('this.domElement_.tabIndex', this.domElement_.tabIndex);\r\n this.domElement_.focus()\r\n\r\n if (event.pointerType == 'touch') {\r\n if (po._pointers.length == 0) {\r\n this.domElement_.setPointerCapture(event.pointerId)\r\n }\r\n po.addPointer(event)\r\n po.trackPointer(event)\r\n this.pbc_touch_start__(event, po)\r\n } else {\r\n this.pbc_down__(event)\r\n }\r\n },\r\n move: event => {\r\n if (event.pointerType == 'touch') {\r\n po.trackPointer(event)\r\n this.pbc_touch_move__(event, po)\r\n } else {\r\n this.pbc_move__(event)\r\n }\r\n },\r\n up: event => {\r\n if (event.pointerType == 'touch') {\r\n po.removePointer(event)\r\n this.pbc_touch_end__(event, po)\r\n if (po._pointers.length == 0) {\r\n this.domElement_.releasePointerCapture(event.pointerId)\r\n }\r\n } else {\r\n this.ptc_up__(event)\r\n }\r\n },\r\n cancel: event => {\r\n po.removePointer(event)\r\n },\r\n }\r\n }\r\n\r\n if (this.enabled_) {\r\n // console.log(this.domElement_)\r\n this.pbc_evts_.reset()\r\n this.domElement_.addEventListener('pointerdown', this.pbc_evts_.down)\r\n this.domElement_.addEventListener('pointermove', this.pbc_evts_.move)\r\n this.domElement_.addEventListener('pointerup', this.pbc_evts_.up)\r\n this.domElement_.addEventListener('pointercancel', this.pbc_evts_.cancel)\r\n } else {\r\n this.domElement_.removeEventListener('pointercancel', this.pbc_evts_.cancel)\r\n this.domElement_.removeEventListener('pointerup', this.pbc_evts_.up)\r\n this.domElement_.removeEventListener('pointermove', this.pbc_evts_.move)\r\n this.domElement_.removeEventListener('pointerdown', this.pbc_evts_.down)\r\n }\r\n\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PointerBaseControls);\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/controls/PointerBaseControls.js?");
/***/ }),
@@ -168,7 +168,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"FrostFar_pp\": () => (/* binding */ FrostFar_pp)\n/* harmony export */ });\n/* harmony import */ var kutsi_pp_Base_pp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/pp/Base_pp */ \"./src-kutsi/crossyo/kutsi/pp/Base_pp.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_EffectComposer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three/examples/jsm/postprocessing/EffectComposer */ \"./node_modules/_three@0.139.2@three/examples/jsm/postprocessing/EffectComposer.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_RenderPass__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/postprocessing/RenderPass */ \"./node_modules/_three@0.139.2@three/examples/jsm/postprocessing/RenderPass.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/postprocessing/ShaderPass */ \"./node_modules/_three@0.139.2@three/examples/jsm/postprocessing/ShaderPass.js\");\n/* harmony import */ var three_examples_jsm_shaders_GammaCorrectionShader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three/examples/jsm/shaders/GammaCorrectionShader */ \"./node_modules/_three@0.139.2@three/examples/jsm/shaders/GammaCorrectionShader.js\");\n/* harmony import */ var _GrayTendShader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./GrayTendShader */ \"./src-kutsi-shelves/crossyo/kutsi/pp/GrayTendShader.js\");\n/* harmony import */ var _FrostShader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./FrostShader */ \"./src-kutsi-shelves/crossyo/kutsi/pp/FrostShader.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// #20221115, FrostFar\r\nclass FrostFar_pp extends kutsi_pp_Base_pp__WEBPACK_IMPORTED_MODULE_0__.Base_pp {\r\n\r\n constructor() {\r\n super()\r\n this.pass1__ = null\r\n this.pass2__ = null\r\n\r\n this.default_frost_ = true // false\r\n this.gray_tend_ = {\r\n value: .5 // 0 ~ 1, 0 forbit !\r\n }\r\n }\r\n\r\n get grayTend() {\r\n return this.gray_tend_.value\r\n }\r\n\r\n set grayTend(v) {\r\n this.gray_tend_.value = v\r\n if (v == 0) {\r\n if (this.pass_lumi_) {\r\n this.pass_lumi_.enabled = false\r\n }\r\n }\r\n }\r\n\r\n use() {\r\n\r\n let v = this.viewer_\r\n let size = v.size_\r\n // https://github.com/mrdoob/three.js/blob/dev/examples/js/postprocessing/EffectComposer.js\r\n\r\n this.composer1_ = new three_examples_jsm_postprocessing_EffectComposer__WEBPACK_IMPORTED_MODULE_1__.EffectComposer(this.renderer_)\r\n // this.composer1_.renderTarget1.samples = this.composer1_.renderTarget2.samples = 4\r\n // this.composer1_.setPixelRatio(v.pixelRatio_)\r\n this.composer1_.setSize(size.w, size.h)\r\n\r\n // https://github.com/mrdoob/three.js/blob/dev/examples/jsm/postprocessing/RenderPass.js\r\n this.pass_render_ = new three_examples_jsm_postprocessing_RenderPass__WEBPACK_IMPORTED_MODULE_2__.RenderPass(this.scene_, this.camera_)\r\n this.pass_render_.renderToScreen = false\r\n this.composer1_.addPass(this.pass_render_)\r\n\r\n this.pass_frost_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_3__.ShaderPass(_FrostShader__WEBPACK_IMPORTED_MODULE_6__.FrostShader)\r\n let rv = this.pass_frost_.uniforms.iResolution.value\r\n rv.x = size.w\r\n rv.y = size.h\r\n this.composer1_.addPass(this.pass_frost_)\r\n\r\n this.pass_lumi_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_3__.ShaderPass(_GrayTendShader__WEBPACK_IMPORTED_MODULE_5__.GrayTendShader)\r\n this.pass_lumi_.uniforms.grayTend = this.gray_tend_\r\n this.composer1_.addPass(this.pass_lumi_)\r\n\r\n this.pass_gamma_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_3__.ShaderPass(three_examples_jsm_shaders_GammaCorrectionShader__WEBPACK_IMPORTED_MODULE_4__.GammaCorrectionShader)\r\n this.composer1_.addPass(this.pass_gamma_)\r\n\r\n }\r\n\r\n setSize(w, h) {\r\n super.setSize(w, h)\r\n\r\n let v = this.viewer_\r\n let size = v.size_\r\n // if (this.pass_outline_) {\r\n // this.pass_outline_.setSize(size.w, size.h)\r\n // }\r\n\r\n if (this.composer1_) {\r\n // console.log('this.composer1_.setSize', size)\r\n this.composer1_.setSize(size.w, size.h)\r\n }\r\n\r\n if (this.pass_frost_) {\r\n let rv = this.pass_frost_.uniforms.iResolution.value\r\n rv.x = size.w\r\n rv.y = size.h\r\n }\r\n\r\n }\r\n\r\n render() {\r\n //\r\n if (this.pass1__ && this.pass2__) {\r\n this.pass1__()\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n this.scene_.autoClear = true\r\n this.composer1_.render()\r\n\r\n this.pass2__()\r\n this.renderer_.autoClear = false\r\n this.renderer_.clearDepth()\r\n this.renderer_.render(this.scene_, this.camera_)\r\n } else {\r\n if (this.default_frost_) {\r\n this.composer1_.render()\r\n } else {\r\n this.renderer_.render(this.scene_, this.camera_)\r\n }\r\n }\r\n }\r\n\r\n // begin 2 pass scene\r\n beginPass(pass1, pass2) {\r\n this.scene_.background = null\r\n this.pass1__ = pass1\r\n this.pass2__ = pass2\r\n }\r\n\r\n endPass() {\r\n this.pass1__ = null\r\n this.pass2__ = null\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/pp/FrostFar_pp.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"FrostFar_pp\": () => (/* binding */ FrostFar_pp)\n/* harmony export */ });\n/* harmony import */ var kutsi_pp_Base_pp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/pp/Base_pp */ \"./src-kutsi/crossyo/kutsi/pp/Base_pp.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_EffectComposer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/postprocessing/EffectComposer */ \"./node_modules/_three@0.146.0@three/examples/jsm/postprocessing/EffectComposer.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_RenderPass__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three/examples/jsm/postprocessing/RenderPass */ \"./node_modules/_three@0.146.0@three/examples/jsm/postprocessing/RenderPass.js\");\n/* harmony import */ var three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three/examples/jsm/postprocessing/ShaderPass */ \"./node_modules/_three@0.146.0@three/examples/jsm/postprocessing/ShaderPass.js\");\n/* harmony import */ var three_examples_jsm_shaders_GammaCorrectionShader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! three/examples/jsm/shaders/GammaCorrectionShader */ \"./node_modules/_three@0.146.0@three/examples/jsm/shaders/GammaCorrectionShader.js\");\n/* harmony import */ var _GrayTendShader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./GrayTendShader */ \"./src-kutsi-shelves/crossyo/kutsi/pp/GrayTendShader.js\");\n/* harmony import */ var _FrostShader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./FrostShader */ \"./src-kutsi-shelves/crossyo/kutsi/pp/FrostShader.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// #20221115, FrostFar\r\nclass FrostFar_pp extends kutsi_pp_Base_pp__WEBPACK_IMPORTED_MODULE_0__.Base_pp {\r\n\r\n constructor() {\r\n super()\r\n this.pass1__ = null\r\n this.pass2__ = null\r\n\r\n this.default_frost_ = true // false\r\n this.gray_tend_ = {\r\n value: .5 // 0 ~ 1, 0 forbit !\r\n }\r\n }\r\n\r\n get grayTend() {\r\n return this.gray_tend_.value\r\n }\r\n\r\n set grayTend(v) {\r\n this.gray_tend_.value = v\r\n if (v == 0) {\r\n if (this.pass_lumi_) {\r\n this.pass_lumi_.enabled = false\r\n }\r\n }\r\n }\r\n\r\n use() {\r\n\r\n let v = this.viewer_\r\n let size = v.size_\r\n // https://github.com/mrdoob/three.js/blob/dev/examples/js/postprocessing/EffectComposer.js\r\n\r\n this.composer1_ = new three_examples_jsm_postprocessing_EffectComposer__WEBPACK_IMPORTED_MODULE_3__.EffectComposer(this.renderer_)\r\n // this.composer1_.renderTarget1.samples = this.composer1_.renderTarget2.samples = 4\r\n // this.composer1_.setPixelRatio(v.pixelRatio_)\r\n this.composer1_.setSize(size.w, size.h)\r\n\r\n // https://github.com/mrdoob/three.js/blob/dev/examples/jsm/postprocessing/RenderPass.js\r\n this.pass_render_ = new three_examples_jsm_postprocessing_RenderPass__WEBPACK_IMPORTED_MODULE_4__.RenderPass(this.scene_, this.camera_)\r\n this.pass_render_.renderToScreen = false\r\n this.composer1_.addPass(this.pass_render_)\r\n\r\n this.pass_frost_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_5__.ShaderPass(_FrostShader__WEBPACK_IMPORTED_MODULE_2__.FrostShader)\r\n let rv = this.pass_frost_.uniforms.iResolution.value\r\n rv.x = size.w\r\n rv.y = size.h\r\n this.composer1_.addPass(this.pass_frost_)\r\n\r\n this.pass_lumi_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_5__.ShaderPass(_GrayTendShader__WEBPACK_IMPORTED_MODULE_1__.GrayTendShader)\r\n this.pass_lumi_.uniforms.grayTend = this.gray_tend_\r\n this.composer1_.addPass(this.pass_lumi_)\r\n\r\n this.pass_gamma_ = new three_examples_jsm_postprocessing_ShaderPass__WEBPACK_IMPORTED_MODULE_5__.ShaderPass(three_examples_jsm_shaders_GammaCorrectionShader__WEBPACK_IMPORTED_MODULE_6__.GammaCorrectionShader)\r\n this.composer1_.addPass(this.pass_gamma_)\r\n\r\n }\r\n\r\n setSize(w, h) {\r\n super.setSize(w, h)\r\n\r\n let v = this.viewer_\r\n let size = v.size_\r\n // if (this.pass_outline_) {\r\n // this.pass_outline_.setSize(size.w, size.h)\r\n // }\r\n\r\n if (this.composer1_) {\r\n // console.log('this.composer1_.setSize', size)\r\n this.composer1_.setSize(size.w, size.h)\r\n }\r\n\r\n if (this.pass_frost_) {\r\n let rv = this.pass_frost_.uniforms.iResolution.value\r\n rv.x = size.w\r\n rv.y = size.h\r\n }\r\n\r\n }\r\n\r\n render() {\r\n //\r\n if (this.pass1__ && this.pass2__) {\r\n this.pass1__()\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n this.scene_.autoClear = true\r\n this.composer1_.render()\r\n\r\n this.pass2__()\r\n this.renderer_.autoClear = false\r\n this.renderer_.clearDepth()\r\n this.renderer_.render(this.scene_, this.camera_)\r\n } else {\r\n if (this.default_frost_) {\r\n this.composer1_.render()\r\n } else {\r\n this.renderer_.render(this.scene_, this.camera_)\r\n }\r\n }\r\n }\r\n\r\n // begin 2 pass scene\r\n beginPass(pass1, pass2) {\r\n this.scene_.background = null\r\n this.pass1__ = pass1\r\n this.pass2__ = pass2\r\n }\r\n\r\n endPass() {\r\n this.pass1__ = null\r\n this.pass2__ = null\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/pp/FrostFar_pp.js?");
/***/ }),
@@ -179,7 +179,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"FrostShader\": () => (/* binding */ FrostShader)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\n\r\nconst FrostShader = {\r\n\r\n uniforms: {\r\n 'tDiffuse': { value: null },\r\n 'opacity': { value: 1.0 },\r\n 'iResolution': { value: new three__WEBPACK_IMPORTED_MODULE_0__.Vector2(100, 100) },\r\n },\r\n\r\n vertexShader: /* glsl */`\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvUv = uv;\r\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\r\n\t\t}`,\r\n\r\n fragmentShader: /* glsl */`\r\n\t\tuniform float opacity;\r\n\t\tuniform sampler2D tDiffuse;\r\n uniform vec2 iResolution;\r\n\t\tvarying vec2 vUv;\r\n\r\n void mainImage( out vec4 fragColor, in vec2 fragCoord )\r\n {\r\n float Pi = 6.28318530718; // Pi*2\r\n \r\n // GAUSSIAN BLUR SETTINGS {{{\r\n float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)\r\n float Quality = 3.0; // BLUR QUALITY (Default 4.0 - More is better but slower)\r\n float Size = 8.0; // BLUR SIZE (Radius)\r\n // GAUSSIAN BLUR SETTINGS }}}\r\n \r\n vec2 Radius = Size/iResolution.xy;\r\n \r\n // Normalized pixel coordinates (from 0 to 1)\r\n vec2 uv = fragCoord/iResolution.xy;\r\n // Pixel colour\r\n vec4 Color = texture(tDiffuse, uv);\r\n\r\n // Blur calculations\r\n for( float d=0.0; d (/* binding */ FrostShader)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\n\r\nconst FrostShader = {\r\n\r\n uniforms: {\r\n 'tDiffuse': { value: null },\r\n 'opacity': { value: 1.0 },\r\n 'iResolution': { value: new three__WEBPACK_IMPORTED_MODULE_0__.Vector2(100, 100) },\r\n },\r\n\r\n vertexShader: /* glsl */`\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvUv = uv;\r\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\r\n\t\t}`,\r\n\r\n fragmentShader: /* glsl */`\r\n\t\tuniform float opacity;\r\n\t\tuniform sampler2D tDiffuse;\r\n uniform vec2 iResolution;\r\n\t\tvarying vec2 vUv;\r\n\r\n void mainImage( out vec4 fragColor, in vec2 fragCoord )\r\n {\r\n float Pi = 6.28318530718; // Pi*2\r\n \r\n // GAUSSIAN BLUR SETTINGS {{{\r\n float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)\r\n float Quality = 3.0; // BLUR QUALITY (Default 4.0 - More is better but slower)\r\n float Size = 8.0; // BLUR SIZE (Radius)\r\n // GAUSSIAN BLUR SETTINGS }}}\r\n \r\n vec2 Radius = Size/iResolution.xy;\r\n \r\n // Normalized pixel coordinates (from 0 to 1)\r\n vec2 uv = fragCoord/iResolution.xy;\r\n // Pixel colour\r\n vec4 Color = texture(tDiffuse, uv);\r\n\r\n // Blur calculations\r\n for( float d=0.0; d {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"GrayTendShader\": () => (/* binding */ GrayTendShader)\n/* harmony export */ });\nconst GrayTendShader = {\r\n\r\n uniforms: {\r\n 'tDiffuse': { value: null },\r\n 'grayTend': { value: .5 }\r\n },\r\n\r\n vertexShader: /* glsl */`\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvUv = uv;\r\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\r\n\t\t}`,\r\n\r\n fragmentShader: /* glsl */`\r\n\t\t#include \r\n\t\tuniform sampler2D tDiffuse;\r\n uniform float grayTend;\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvec4 texel = texture2D( tDiffuse, vUv );\r\n\t\t\t// float l = luminance( texel.rgb ); // at least v145\r\n float l = linearToRelativeLuminance( texel.rgb ); // at least for v139\r\n\t\t\tgl_FragColor = vec4( mix(texel.rgb, vec3(l,l,l), grayTend), texel.w );\r\n\t\t}`\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/pp/GrayTendShader.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"GrayTendShader\": () => (/* binding */ GrayTendShader)\n/* harmony export */ });\nconst GrayTendShader = {\r\n\r\n uniforms: {\r\n 'tDiffuse': { value: null },\r\n 'grayTend': { value: .5 }\r\n },\r\n\r\n vertexShader: /* glsl */`\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvUv = uv;\r\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\r\n\t\t}`,\r\n\r\n fragmentShader: /* glsl */`\r\n\t\t#include \r\n\t\tuniform sampler2D tDiffuse;\r\n uniform float grayTend;\r\n\t\tvarying vec2 vUv;\r\n\t\tvoid main() {\r\n\t\t\tvec4 texel = texture2D( tDiffuse, vUv );\r\n\t\t\tfloat l = luminance( texel.rgb ); // at least v145\r\n // float l = linearToRelativeLuminance( texel.rgb ); // at least for v139\r\n\t\t\tgl_FragColor = vec4( mix(texel.rgb, vec3(l,l,l), grayTend), texel.w );\r\n\t\t}`\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi-shelves/crossyo/kutsi/pp/GrayTendShader.js?");
/***/ }),
@@ -201,7 +201,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BaseViewer),\n/* harmony export */ \"registerClass\": () => (/* binding */ registerClass)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.139.2@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! gsap */ \"./node_modules/_gsap@3.11.3@gsap/index.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _util_Builder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/Builder */ \"./src-kutsi/crossyo/kutsi/util/Builder.js\");\n/* harmony import */ var _util_Picker__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/Picker */ \"./src-kutsi/crossyo/kutsi/util/Picker.js\");\n/* harmony import */ var _pp_PPRenderer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./pp/PPRenderer */ \"./src-kutsi/crossyo/kutsi/pp/PPRenderer.js\");\n/* harmony import */ var _util_frame_caches__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/frame/caches */ \"./src-kutsi/crossyo/kutsi/util/frame/caches.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst registerClass = {\r\n // import { GUI } from 'three/examples/jsm/libs/dat.gui.module'\r\n GUI: null, // from r135, be removed!\r\n}\r\n\r\nclass BaseViewer extends (events__WEBPACK_IMPORTED_MODULE_1___default()) {\r\n\r\n constructor(opts) {\r\n\r\n super()\r\n\r\n this.is_wx_ = false\r\n // this.pixelRatio_ = window.devicePixelRatio // 兼容 wx base view 写法\r\n\r\n // #20220504, for mobile performance!\r\n this.pixelRatio_ = Math.min(2, window.devicePixelRatio)\r\n\r\n this.opts_ = Object.assign({\r\n trend: {\r\n // hdr: true,\r\n hdr: false,\r\n },\r\n picker: {\r\n useHitVisible: true, // material-account\r\n useHitsArray: false, // metro-l6 use assigned hits, even don't use it, set true for best performance\r\n useMeshGroup: false, // material-account mesh group\r\n useMove: false, // red-valley only use move, set true for move/over event\r\n },\r\n manually_start_animate: false, // red-valley\r\n clzControls: three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_0__.OrbitControls,\r\n fov0: 40, // #20220225, shelves, init fov\r\n\r\n clzBuilder: _util_Builder__WEBPACK_IMPORTED_MODULE_2__.Builder, // #20220314, vlab3-lab\r\n\r\n clzPostProcessing: null, // #20220703, shelves v3 + FXAA\r\n\r\n }, opts)\r\n\r\n this.container_ = this.opts_.container\r\n this.prefixAsset_ = this.opts_.prefixAsset || './asset'\r\n\r\n // gsap.ticker.remove(gsap.updateRoot)\r\n this.disposed_ = false\r\n\r\n this.size_ = {\r\n w: 0,\r\n h: 0,\r\n pw: 0,\r\n ph: 0,\r\n }\r\n\r\n // this.builder_ = new Builder(this.opts_, this)\r\n this.builder_ = new this.opts_.clzBuilder(this.opts_, this)\r\n\r\n this.clock_ = new three__WEBPACK_IMPORTED_MODULE_6__.Clock()\r\n\r\n // for uniform\r\n this.u_time_ = {\r\n value: 0\r\n }\r\n\r\n }\r\n\r\n startup() {\r\n\r\n // #20220207\r\n // #20220724, unsafe\r\n // window['prefab-tool-0207029'] = {\r\n // viewer: this,\r\n // THREE\r\n // }\r\n\r\n this.calc_size__()\r\n\r\n // this.renderer_ = new THREE.WebGLRenderer({ antialias: true })\r\n // this.opts_.clzPostProcessing ? false : true\r\n this.renderer_ = new _pp_PPRenderer__WEBPACK_IMPORTED_MODULE_4__.PPRenderer({ antialias: true, alpha: true })\r\n this.renderer_.setPixelRatio(this.pixelRatio_)\r\n this.renderer_.setSize(this.size_.w, this.size_.h)\r\n\r\n if (this.opts_.trend.hdr) {\r\n this.renderer_.outputEncoding = three__WEBPACK_IMPORTED_MODULE_6__.sRGBEncoding\r\n //\r\n // this.renderer_.toneMapping = THREE.ReinhardToneMapping\r\n // this.renderer_.toneMapping = THREE.CineonToneMapping\r\n this.renderer_.toneMapping = three__WEBPACK_IMPORTED_MODULE_6__.ACESFilmicToneMapping\r\n this.renderer_.toneMappingExposure = 1.2\r\n } else {\r\n this.renderer_.toneMapping = three__WEBPACK_IMPORTED_MODULE_6__.LinearToneMapping\r\n }\r\n\r\n this.opts_.container.appendChild(this.renderer_.domElement)\r\n\r\n this.camera_ = new three__WEBPACK_IMPORTED_MODULE_6__.PerspectiveCamera(this.opts_.fov0, this.size_.w / this.size_.h, .1, 1000)\r\n this.camera_.position.set(0, 0, 20);\r\n\r\n this.scene_ = new three__WEBPACK_IMPORTED_MODULE_6__.Scene()\r\n // this.scene_.background = new THREE.Color(0xbfe3dd)\r\n // this.scene_.background = new THREE.Color(0xeeeeee)\r\n\r\n this.renderer_.setup__(this, this.scene_, this.camera_)\r\n if (this.opts_.clzPostProcessing) {\r\n this.renderer_.use_pp__(new this.opts_.clzPostProcessing())\r\n }\r\n\r\n // {\r\n // const renderScene = new RenderPass(this.scene_, this.camera_)\r\n // const bloomPass = new UnrealBloomPass(new THREE.Vector2(w, h), 1.5, 0.4, 0.85)\r\n // const composer = new EffectComposer(this.renderer_)\r\n // composer.addPass(renderScene)\r\n // composer.addPass(bloomPass)\r\n // this.bloom__ = {\r\n // composer\r\n // }\r\n // }\r\n\r\n window.onresize = () => {\r\n this.resize_()\r\n }\r\n this.resize_()\r\n\r\n // this.controls_ = new OrbitControls(this.camera_, this.renderer_.domElement)\r\n this.controls_ = new this.opts_.clzControls(this.camera_, this.renderer_.domElement)\r\n // this.controls_.target.set()\r\n // this.controls_.update()\r\n this.controls_.enableDamping = true\r\n this.controls_.enablePan = false\r\n\r\n this.controls_distance_ = new _util_frame_caches__WEBPACK_IMPORTED_MODULE_5__.ControlsDistance(this)\r\n\r\n this.picker_ = new _util_Picker__WEBPACK_IMPORTED_MODULE_3__.Picker(Object.assign({\r\n domElement: this.renderer_.domElement,\r\n viewer: this,\r\n }, this.opts_.picker))\r\n\r\n if (!this.opts_.manually_start_animate) { // use loading\r\n this.animate_()\r\n }\r\n\r\n // this.beginLoadSpecs().reduce((p, spec) =>\r\n // p.then(() => new Promise(resolve => {\r\n // // hook prefab?\r\n // this.builder_[spec.func](spec.param, () => {\r\n // resolve()\r\n // })\r\n // })),\r\n // Promise.resolve()\r\n // ).then(() => {\r\n // this.endLoadSpecs()\r\n // })\r\n\r\n this.build_specs__(this.beginLoadSpecs()).then(() => {\r\n this.endLoadSpecs()\r\n })\r\n\r\n this.dump_keydown__ = evt => {\r\n const dump_vec3_ = v => {\r\n // return `new THREE.Vector3(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`\r\n return `new Vector3(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`\r\n }\r\n // console.log(evt)\r\n if (evt.altKey && evt.key == 'p') {\r\n // console.log(this.camera_)\r\n console.log(this.renderer_.info)\r\n console.log(`\r\n\t\t\t\t\tposition:${dump_vec3_(this.controls_.object.position)},\r\n\t\t\t\t\ttarget:${dump_vec3_(this.controls_.target)},\r\n direction:${dump_vec3_(this.controls_.object.getWorldDirection(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3()))},\r\n\t\t\t\t`)\r\n\r\n if (this.dump_keydown_after__) {\r\n this.dump_keydown_after__()\r\n }\r\n }\r\n }\r\n window.addEventListener('keydown', this.dump_keydown__)\r\n\r\n // this.distanceDetector_ = \r\n }\r\n\r\n build_specs__(arr) {\r\n return arr.reduce((p, spec) =>\r\n p.then(() => new Promise(resolve => {\r\n // hook prefab?\r\n this.builder_[spec.func](spec.param, resolve)\r\n })),\r\n Promise.resolve()\r\n )\r\n }\r\n\r\n calc_size__() {\r\n let w = this.container_.clientWidth\r\n let h = this.container_.clientHeight\r\n\r\n this.size_.w = w\r\n this.size_.h = h\r\n this.size_.pw = w * this.pixelRatio_\r\n this.size_.ph = h * this.pixelRatio_\r\n // console.log('calc_size__', this.size_)\r\n }\r\n\r\n resize_() {\r\n\r\n this.calc_size__()\r\n\r\n let aspect = this.size_.w / this.size_.h\r\n let cam = this.camera_\r\n if (cam instanceof three__WEBPACK_IMPORTED_MODULE_6__.PerspectiveCamera) {\r\n cam.aspect = aspect\r\n cam.updateProjectionMatrix()\r\n } else if (cam instanceof three__WEBPACK_IMPORTED_MODULE_6__.OrthographicCamera) {\r\n cam.left = - cam.frustum_size_ * aspect / 2\r\n cam.right = cam.frustum_size_ * aspect / 2\r\n cam.top = cam.frustum_size_ / 2\r\n cam.bottom = - cam.frustum_size_ / 2\r\n cam.near = cam.frustum_size_ / 1000\r\n cam.far = cam.frustum_size_ * 2\r\n cam.updateProjectionMatrix()\r\n } else {\r\n console.warn('unknow camera when resize_()', this.camera_)\r\n }\r\n\r\n this.renderer_.setSize__(this.size_.w, this.size_.h)\r\n\r\n }\r\n\r\n before_update_(time, delta) { }\r\n\r\n before_render_(time, delta) { }\r\n\r\n after_render_(time, delta) { }\r\n\r\n animate_() {\r\n if (!this.disposed_) {\r\n requestAnimationFrame(() => { this.animate_() })\r\n\r\n // let time = performance.now() / 1000\r\n let delta = this.clock_.getDelta()\r\n let time = this.clock_.elapsedTime\r\n this.u_time_.value = time\r\n\r\n this.before_update_(time, delta)\r\n\r\n if (this.controls_.enabled) {\r\n this.controls_.update(delta) // for material-accounting/FlyControls\r\n }\r\n this.controls_distance_.invalid() // 即使没有enabled也需要更新,例如动画\r\n\r\n this.picker_.update()\r\n\r\n this.before_render_(time, delta)\r\n\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n this.renderer_.render__()\r\n\r\n this.after_render_(time, delta)\r\n }\r\n\r\n }\r\n\r\n // #20220228, for shelves\r\n changeControls(controls) {\r\n this.controls_.dispose()\r\n this.controls_ = controls\r\n }\r\n\r\n // #20221030, for shelves\r\n dispose_resource_() {\r\n\r\n let geos = {}\r\n let mats = {}\r\n let texs = {}\r\n\r\n this.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n let gid = c.geometry.uuid\r\n let fg = geos[gid]\r\n if (!fg) {\r\n geos[gid] = c.geometry\r\n\r\n }\r\n let mid = c.material.uuid\r\n let fm = mats[mid]\r\n if (!fm) {\r\n mats[mid] = c.material\r\n Object.entries(c.material).forEach(([k, v]) => {\r\n if (v && v.isTexture) {\r\n let tid = v.uuid\r\n let ft = texs[tid]\r\n if (!ft) {\r\n texs[tid] = v\r\n }\r\n }\r\n })\r\n }\r\n\r\n }\r\n })\r\n\r\n // console.log(geos, mats, texs)\r\n // console.log(JSON.stringify(this.renderer_.info.memory))\r\n\r\n Object.values(geos).forEach(geo => geo.dispose())\r\n Object.values(mats).forEach(mat => mat.dispose())\r\n Object.values(texs).forEach(tex => tex.dispose())\r\n\r\n // setTimeout(() => {\r\n // console.log(JSON.stringify(this.renderer_.info.memory))\r\n // }, 0)\r\n }\r\n\r\n dispose(force_dispose_resource = true) {\r\n\r\n if (force_dispose_resource) {\r\n this.dispose_resource_()\r\n }\r\n\r\n this.disposed_ = true\r\n this.controls_.dispose()\r\n this.picker_.dispose()\r\n window.removeEventListener('keydown', this.dump_keydown__)\r\n\r\n this.renderer_.dispose()\r\n }\r\n\r\n update_camera_near_far_(len) {\r\n let log = Math.log10(len)\r\n let log1 = Math.floor(log) - 2\r\n let log2 = Math.ceil(log) + 2\r\n let near = Math.pow(10, log1)\r\n let far = Math.pow(10, log2)\r\n // console.log(cnt, size, len)\r\n console.log('near', near, 'far', far)\r\n this.camera_.near = near\r\n this.camera_.far = far\r\n this.camera_.updateProjectionMatrix()\r\n }\r\n\r\n // #20210622, new Box3().expandByObject(o3d)\r\n updateViewerByBoundingBox(bb, scale = 1) {\r\n let cnt = bb.getCenter(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3())\r\n let size = bb.getSize(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3())\r\n let len = size.length() * scale\r\n this.update_camera_near_far_(len)\r\n this.controls_.target0 = cnt\r\n this.controls_.position0 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3(-len, len, len).add(cnt)\r\n this.controls_.reset()\r\n\r\n this.latest_bb__ = bb\r\n }\r\n\r\n // #20211122 metro-l6\r\n // #20211225 updateViwerFromTo to updateViewerLookat for jx-map\r\n updateViewerLookat({ position, target = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3(0, 0, 0), forceUpdateNearFar = false }) {\r\n this.controls_.target0 = target.clone()\r\n this.controls_.position0 = position.clone()\r\n this.controls_.reset()\r\n if (forceUpdateNearFar) {\r\n this.update_camera_near_far_(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(position, target).length())\r\n }\r\n }\r\n\r\n // #20211030\r\n beginLoadSpecs() {\r\n return []\r\n }\r\n\r\n endLoadSpecs() {\r\n\r\n }\r\n\r\n // #20211126, red-valley\r\n // #20220604, kiwi, add duration\r\n // #20220616, floor-deco, fov\r\n // #20221104, vmap, closeShorterTime for cinematic SquatZoom\r\n flyTo({ position, target, duration = .8, fov = NaN, closeShorterTime = true }, completion = () => { }) {\r\n // console.log('## flyTo begin', position, target)\r\n this.controls_.enabled = false\r\n let controls = this.controls_\r\n let obj = Object.defineProperty((() => {\r\n let o = {\r\n t_: 0,\r\n pos0: controls.object.position.clone(),\r\n tgt0: controls.target.clone(),\r\n pos1: position.clone(),\r\n tgt1: target.clone(),\r\n }\r\n if (!isNaN(fov)) {\r\n o.fov0 = controls.object.fov\r\n o.fov1 = fov\r\n // console.log('flyTo use fov', o.fov0, o.fov1)\r\n }\r\n return o\r\n })(), 't', {\r\n get() {\r\n return this.t_\r\n },\r\n set(v) {\r\n this.t_ = v\r\n // \r\n let cam = controls.object\r\n cam.position.copy(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().lerpVectors(this.pos0, this.pos1, this.t_))\r\n cam.lookAt(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().lerpVectors(this.tgt0, this.tgt1, this.t_))\r\n if (!isNaN(fov)) {\r\n // let ut = this.t_\r\n let ut = Math.sqrt(this.t_)\r\n cam.fov = this.fov0 + (this.fov1 - this.fov0) * ut\r\n cam.updateProjectionMatrix()\r\n }\r\n }\r\n })\r\n\r\n // #20220121, smart-farm, 没有变化时,可以取消操作!\r\n let real_duration = duration\r\n if (closeShorterTime) { // #20221104, vmap, cinematic SquatZoom\r\n let dpos2 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(obj.pos0, obj.pos1).lengthSq()\r\n let dtgt2 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(obj.tgt0, obj.tgt1).lengthSq()\r\n if (dpos2 > 1e-8 || dtgt2 > 1e-8) {\r\n } else {\r\n // #20220822, for hospital-hvac, BIM\r\n // 不执行 gsap.to 会出错,所以把duration改短即可\r\n real_duration = duration / 10\r\n }\r\n }\r\n\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(obj, {\r\n t: 1, duration: real_duration, onComplete: () => {\r\n controls.enabled = true\r\n controls.position0.copy(obj.pos1)\r\n controls.target0.copy(obj.tgt1)\r\n controls.reset()\r\n // console.log('#### flyTo end')\r\n completion()\r\n }\r\n })\r\n\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/BaseViewer.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BaseViewer),\n/* harmony export */ \"registerClass\": () => (/* binding */ registerClass)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.146.0@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! gsap */ \"./node_modules/_gsap@3.11.3@gsap/index.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _util_Builder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/Builder */ \"./src-kutsi/crossyo/kutsi/util/Builder.js\");\n/* harmony import */ var _util_Picker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/Picker */ \"./src-kutsi/crossyo/kutsi/util/Picker.js\");\n/* harmony import */ var _pp_PPRenderer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pp/PPRenderer */ \"./src-kutsi/crossyo/kutsi/pp/PPRenderer.js\");\n/* harmony import */ var _util_frame_caches__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./util/frame/caches */ \"./src-kutsi/crossyo/kutsi/util/frame/caches.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst registerClass = {\r\n // import { GUI } from 'three/examples/jsm/libs/dat.gui.module'\r\n GUI: null, // from r135, be removed!\r\n}\r\n\r\nclass BaseViewer extends (events__WEBPACK_IMPORTED_MODULE_0___default()) {\r\n\r\n constructor(opts) {\r\n\r\n super()\r\n\r\n this.is_wx_ = false\r\n // this.pixelRatio_ = window.devicePixelRatio // 兼容 wx base view 写法\r\n\r\n // #20220504, for mobile performance!\r\n this.pixelRatio_ = Math.min(2, window.devicePixelRatio)\r\n\r\n this.opts_ = Object.assign({\r\n trend: {\r\n // hdr: true,\r\n hdr: false,\r\n },\r\n picker: {\r\n useHitVisible: true, // material-account\r\n useHitsArray: false, // metro-l6 use assigned hits, even don't use it, set true for best performance\r\n useMeshGroup: false, // material-account mesh group\r\n useMove: false, // red-valley only use move, set true for move/over event\r\n },\r\n manually_start_animate: false, // red-valley\r\n clzControls: three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_5__.OrbitControls,\r\n fov0: 40, // #20220225, shelves, init fov\r\n\r\n clzBuilder: _util_Builder__WEBPACK_IMPORTED_MODULE_1__.Builder, // #20220314, vlab3-lab\r\n\r\n clzPostProcessing: null, // #20220703, shelves v3 + FXAA\r\n\r\n }, opts)\r\n\r\n this.container_ = this.opts_.container\r\n this.prefixAsset_ = this.opts_.prefixAsset || './asset'\r\n\r\n // gsap.ticker.remove(gsap.updateRoot)\r\n this.disposed_ = false\r\n\r\n this.size_ = {\r\n w: 0,\r\n h: 0,\r\n pw: 0,\r\n ph: 0,\r\n }\r\n\r\n // this.builder_ = new Builder(this.opts_, this)\r\n this.builder_ = new this.opts_.clzBuilder(this.opts_, this)\r\n\r\n this.clock_ = new three__WEBPACK_IMPORTED_MODULE_6__.Clock()\r\n\r\n // for uniform\r\n this.u_time_ = {\r\n value: 0\r\n }\r\n\r\n }\r\n\r\n startup() {\r\n\r\n // #20220207\r\n // #20220724, unsafe\r\n // window['prefab-tool-0207029'] = {\r\n // viewer: this,\r\n // THREE\r\n // }\r\n\r\n this.calc_size__()\r\n\r\n // this.renderer_ = new THREE.WebGLRenderer({ antialias: true })\r\n // this.opts_.clzPostProcessing ? false : true\r\n this.renderer_ = new _pp_PPRenderer__WEBPACK_IMPORTED_MODULE_3__.PPRenderer({ antialias: true, alpha: true })\r\n this.renderer_.setPixelRatio(this.pixelRatio_)\r\n this.renderer_.setSize(this.size_.w, this.size_.h)\r\n\r\n if (this.opts_.trend.hdr) {\r\n this.renderer_.outputEncoding = three__WEBPACK_IMPORTED_MODULE_6__.sRGBEncoding\r\n //\r\n // this.renderer_.toneMapping = THREE.ReinhardToneMapping\r\n // this.renderer_.toneMapping = THREE.CineonToneMapping\r\n this.renderer_.toneMapping = three__WEBPACK_IMPORTED_MODULE_6__.ACESFilmicToneMapping\r\n this.renderer_.toneMappingExposure = 1.2\r\n } else {\r\n this.renderer_.toneMapping = three__WEBPACK_IMPORTED_MODULE_6__.LinearToneMapping\r\n }\r\n\r\n this.opts_.container.appendChild(this.renderer_.domElement)\r\n\r\n this.camera_ = new three__WEBPACK_IMPORTED_MODULE_6__.PerspectiveCamera(this.opts_.fov0, this.size_.w / this.size_.h, .1, 1000)\r\n this.camera_.position.set(0, 0, 20);\r\n\r\n this.scene_ = new three__WEBPACK_IMPORTED_MODULE_6__.Scene()\r\n // this.scene_.background = new THREE.Color(0xbfe3dd)\r\n // this.scene_.background = new THREE.Color(0xeeeeee)\r\n\r\n this.renderer_.setup__(this, this.scene_, this.camera_)\r\n if (this.opts_.clzPostProcessing) {\r\n this.renderer_.use_pp__(new this.opts_.clzPostProcessing())\r\n }\r\n\r\n // {\r\n // const renderScene = new RenderPass(this.scene_, this.camera_)\r\n // const bloomPass = new UnrealBloomPass(new THREE.Vector2(w, h), 1.5, 0.4, 0.85)\r\n // const composer = new EffectComposer(this.renderer_)\r\n // composer.addPass(renderScene)\r\n // composer.addPass(bloomPass)\r\n // this.bloom__ = {\r\n // composer\r\n // }\r\n // }\r\n\r\n window.onresize = () => {\r\n this.resize_()\r\n }\r\n this.resize_()\r\n\r\n // this.controls_ = new OrbitControls(this.camera_, this.renderer_.domElement)\r\n this.controls_ = new this.opts_.clzControls(this.camera_, this.renderer_.domElement)\r\n // this.controls_.target.set()\r\n // this.controls_.update()\r\n this.controls_.enableDamping = true\r\n this.controls_.enablePan = false\r\n\r\n this.controls_distance_ = new _util_frame_caches__WEBPACK_IMPORTED_MODULE_4__.ControlsDistance(this)\r\n\r\n this.picker_ = new _util_Picker__WEBPACK_IMPORTED_MODULE_2__.Picker(Object.assign({\r\n domElement: this.renderer_.domElement,\r\n viewer: this,\r\n }, this.opts_.picker))\r\n\r\n if (!this.opts_.manually_start_animate) { // use loading\r\n this.animate_()\r\n }\r\n\r\n // this.beginLoadSpecs().reduce((p, spec) =>\r\n // p.then(() => new Promise(resolve => {\r\n // // hook prefab?\r\n // this.builder_[spec.func](spec.param, () => {\r\n // resolve()\r\n // })\r\n // })),\r\n // Promise.resolve()\r\n // ).then(() => {\r\n // this.endLoadSpecs()\r\n // })\r\n\r\n this.build_specs__(this.beginLoadSpecs()).then(() => {\r\n this.endLoadSpecs()\r\n })\r\n\r\n this.dump_keydown__ = evt => {\r\n const dump_vec3_ = v => {\r\n // return `new THREE.Vector3(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`\r\n return `new Vector3(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`\r\n }\r\n // console.log(evt)\r\n if (evt.altKey && evt.key == 'p') {\r\n // console.log(this.camera_)\r\n console.log(this.renderer_.info)\r\n console.log(`\r\n\t\t\t\t\tposition:${dump_vec3_(this.controls_.object.position)},\r\n\t\t\t\t\ttarget:${dump_vec3_(this.controls_.target)},\r\n direction:${dump_vec3_(this.controls_.object.getWorldDirection(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3()))},\r\n\t\t\t\t`)\r\n\r\n if (this.dump_keydown_after__) {\r\n this.dump_keydown_after__()\r\n }\r\n }\r\n }\r\n window.addEventListener('keydown', this.dump_keydown__)\r\n\r\n // this.distanceDetector_ = \r\n }\r\n\r\n build_specs__(arr) {\r\n return arr.reduce((p, spec) =>\r\n p.then(() => new Promise(resolve => {\r\n // hook prefab?\r\n this.builder_[spec.func](spec.param, resolve)\r\n })),\r\n Promise.resolve()\r\n )\r\n }\r\n\r\n calc_size__() {\r\n let w = this.container_.clientWidth\r\n let h = this.container_.clientHeight\r\n\r\n this.size_.w = w\r\n this.size_.h = h\r\n this.size_.pw = w * this.pixelRatio_\r\n this.size_.ph = h * this.pixelRatio_\r\n // console.log('calc_size__', this.size_)\r\n }\r\n\r\n resize_() {\r\n\r\n this.calc_size__()\r\n\r\n let aspect = this.size_.w / this.size_.h\r\n let cam = this.camera_\r\n if (cam instanceof three__WEBPACK_IMPORTED_MODULE_6__.PerspectiveCamera) {\r\n cam.aspect = aspect\r\n cam.updateProjectionMatrix()\r\n } else if (cam instanceof three__WEBPACK_IMPORTED_MODULE_6__.OrthographicCamera) {\r\n cam.left = - cam.frustum_size_ * aspect / 2\r\n cam.right = cam.frustum_size_ * aspect / 2\r\n cam.top = cam.frustum_size_ / 2\r\n cam.bottom = - cam.frustum_size_ / 2\r\n cam.near = cam.frustum_size_ / 1000\r\n cam.far = cam.frustum_size_ * 2\r\n cam.updateProjectionMatrix()\r\n } else {\r\n console.warn('unknow camera when resize_()', this.camera_)\r\n }\r\n\r\n this.renderer_.setSize__(this.size_.w, this.size_.h)\r\n\r\n }\r\n\r\n before_update_(time, delta) { }\r\n\r\n before_render_(time, delta) { }\r\n\r\n after_render_(time, delta) { }\r\n\r\n animate_() {\r\n if (!this.disposed_) {\r\n requestAnimationFrame(() => { this.animate_() })\r\n\r\n // let time = performance.now() / 1000\r\n let delta = this.clock_.getDelta()\r\n let time = this.clock_.elapsedTime\r\n this.u_time_.value = time\r\n\r\n this.before_update_(time, delta)\r\n\r\n if (this.controls_.enabled) {\r\n this.controls_.update(delta) // for material-accounting/FlyControls\r\n }\r\n this.controls_distance_.invalid() // 即使没有enabled也需要更新,例如动画\r\n\r\n this.picker_.update()\r\n\r\n this.before_render_(time, delta)\r\n\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n this.renderer_.render__()\r\n\r\n this.after_render_(time, delta)\r\n }\r\n\r\n }\r\n\r\n // #20220228, for shelves\r\n changeControls(controls) {\r\n this.controls_.dispose()\r\n this.controls_ = controls\r\n }\r\n\r\n // #20221030, for shelves\r\n dispose_resource_() {\r\n\r\n let geos = {}\r\n let mats = {}\r\n let texs = {}\r\n\r\n this.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n let gid = c.geometry.uuid\r\n let fg = geos[gid]\r\n if (!fg) {\r\n geos[gid] = c.geometry\r\n\r\n }\r\n let mid = c.material.uuid\r\n let fm = mats[mid]\r\n if (!fm) {\r\n mats[mid] = c.material\r\n Object.entries(c.material).forEach(([k, v]) => {\r\n if (v && v.isTexture) {\r\n let tid = v.uuid\r\n let ft = texs[tid]\r\n if (!ft) {\r\n texs[tid] = v\r\n }\r\n }\r\n })\r\n }\r\n\r\n }\r\n })\r\n\r\n // console.log(geos, mats, texs)\r\n // console.log(JSON.stringify(this.renderer_.info.memory))\r\n\r\n Object.values(geos).forEach(geo => geo.dispose())\r\n Object.values(mats).forEach(mat => mat.dispose())\r\n Object.values(texs).forEach(tex => tex.dispose())\r\n\r\n // setTimeout(() => {\r\n // console.log(JSON.stringify(this.renderer_.info.memory))\r\n // }, 0)\r\n }\r\n\r\n dispose(force_dispose_resource = true) {\r\n\r\n if (force_dispose_resource) {\r\n this.dispose_resource_()\r\n }\r\n\r\n this.disposed_ = true\r\n this.controls_.dispose()\r\n this.picker_.dispose()\r\n window.removeEventListener('keydown', this.dump_keydown__)\r\n\r\n this.renderer_.dispose()\r\n }\r\n\r\n update_camera_near_far_(len) {\r\n let log = Math.log10(len)\r\n let log1 = Math.floor(log) - 2\r\n let log2 = Math.ceil(log) + 2\r\n let near = Math.pow(10, log1)\r\n let far = Math.pow(10, log2)\r\n // console.log(cnt, size, len)\r\n console.log('near', near, 'far', far)\r\n this.camera_.near = near\r\n this.camera_.far = far\r\n this.camera_.updateProjectionMatrix()\r\n }\r\n\r\n // #20210622, new Box3().expandByObject(o3d)\r\n updateViewerByBoundingBox(bb, scale = 1) {\r\n let cnt = bb.getCenter(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3())\r\n let size = bb.getSize(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3())\r\n let len = size.length() * scale\r\n this.update_camera_near_far_(len)\r\n this.controls_.target0 = cnt\r\n this.controls_.position0 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3(-len, len, len).add(cnt)\r\n this.controls_.reset()\r\n\r\n this.latest_bb__ = bb\r\n }\r\n\r\n // #20211122 metro-l6\r\n // #20211225 updateViwerFromTo to updateViewerLookat for jx-map\r\n updateViewerLookat({ position, target = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3(0, 0, 0), forceUpdateNearFar = false }) {\r\n this.controls_.target0 = target.clone()\r\n this.controls_.position0 = position.clone()\r\n this.controls_.reset()\r\n if (forceUpdateNearFar) {\r\n this.update_camera_near_far_(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(position, target).length())\r\n }\r\n }\r\n\r\n // #20211030\r\n beginLoadSpecs() {\r\n return []\r\n }\r\n\r\n endLoadSpecs() {\r\n\r\n }\r\n\r\n // #20211126, red-valley\r\n // #20220604, kiwi, add duration\r\n // #20220616, floor-deco, fov\r\n // #20221104, vmap, closeShorterTime for cinematic SquatZoom\r\n flyTo({ position, target, duration = .8, fov = NaN, closeShorterTime = true }, completion = () => { }) {\r\n // console.log('## flyTo begin', position, target)\r\n this.controls_.enabled = false\r\n let controls = this.controls_\r\n let obj = Object.defineProperty((() => {\r\n let o = {\r\n t_: 0,\r\n pos0: controls.object.position.clone(),\r\n tgt0: controls.target.clone(),\r\n pos1: position.clone(),\r\n tgt1: target.clone(),\r\n }\r\n if (!isNaN(fov)) {\r\n o.fov0 = controls.object.fov\r\n o.fov1 = fov\r\n // console.log('flyTo use fov', o.fov0, o.fov1)\r\n }\r\n return o\r\n })(), 't', {\r\n get() {\r\n return this.t_\r\n },\r\n set(v) {\r\n this.t_ = v\r\n // \r\n let cam = controls.object\r\n cam.position.copy(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().lerpVectors(this.pos0, this.pos1, this.t_))\r\n cam.lookAt(new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().lerpVectors(this.tgt0, this.tgt1, this.t_))\r\n if (!isNaN(fov)) {\r\n // let ut = this.t_\r\n let ut = Math.sqrt(this.t_)\r\n cam.fov = this.fov0 + (this.fov1 - this.fov0) * ut\r\n cam.updateProjectionMatrix()\r\n }\r\n }\r\n })\r\n\r\n // #20220121, smart-farm, 没有变化时,可以取消操作!\r\n let real_duration = duration\r\n if (closeShorterTime) { // #20221104, vmap, cinematic SquatZoom\r\n let dpos2 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(obj.pos0, obj.pos1).lengthSq()\r\n let dtgt2 = new three__WEBPACK_IMPORTED_MODULE_6__.Vector3().subVectors(obj.tgt0, obj.tgt1).lengthSq()\r\n if (dpos2 > 1e-8 || dtgt2 > 1e-8) {\r\n } else {\r\n // #20220822, for hospital-hvac, BIM\r\n // 不执行 gsap.to 会出错,所以把duration改短即可\r\n real_duration = duration / 10\r\n }\r\n }\r\n\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(obj, {\r\n t: 1, duration: real_duration, onComplete: () => {\r\n controls.enabled = true\r\n controls.position0.copy(obj.pos1)\r\n controls.target0.copy(obj.tgt1)\r\n controls.reset()\r\n // console.log('#### flyTo end')\r\n completion()\r\n }\r\n })\r\n\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/BaseViewer.js?");
/***/ }),
@@ -212,7 +212,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"STATE\": () => (/* binding */ STATE),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\n\r\n\r\nconst STATE = {\r\n NONE: 0x00,\r\n PAN: 0x01,\r\n ROTATION: 0x02,\r\n ZOOM: 0x04,\r\n MOVE: 0x08,\r\n LOOK: 0x10,\r\n}\r\n\r\n/**\r\n * @class\r\n * @memberof module:pamir_base\r\n */\r\nclass BaseControls extends (events__WEBPACK_IMPORTED_MODULE_0___default()) {\r\n\r\n constructor(object, domElement, opts) {\r\n super()\r\n this.object_ = object\r\n this.domElement_ = domElement\r\n this.opts_ = opts || {}\r\n\r\n // for reset!\r\n // this.position0\r\n // this.target0\r\n\r\n this.state_ = STATE.NONE\r\n\r\n this.enabled_ = true\r\n this.update_enabled_() // call by extended class\r\n\r\n // #20220610, 兼容 orbit\r\n this.position0 = new three__WEBPACK_IMPORTED_MODULE_1__.Vector3()\r\n this.target0 = new three__WEBPACK_IMPORTED_MODULE_1__.Vector3()\r\n }\r\n\r\n set object(v) {\r\n this.object_ = v\r\n }\r\n\r\n get object() {\r\n return this.object_\r\n }\r\n\r\n get enabled() {\r\n return this.enabled_\r\n }\r\n\r\n set enabled(v) {\r\n if (v != this.enabled_) {\r\n this.enabled_ = v\r\n this.update_enabled_()\r\n }\r\n }\r\n\r\n // #20220610, 兼容 orbit\r\n reset() {\r\n // use position0, target0\r\n }\r\n\r\n update_enabled_() {\r\n }\r\n\r\n reset() {\r\n // ref to orbit!\r\n if (this.position0) {\r\n this.object_.position.copy(this.position0)\r\n }\r\n }\r\n\r\n dispose() {\r\n this.enabled = false\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n\r\n get state() {\r\n return this.state_\r\n }\r\n\r\n hasState(def_s) {\r\n return (this.state_ & def_s) > 0\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BaseControls);\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/controls/BaseControls.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"STATE\": () => (/* binding */ STATE),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\n\r\n\r\nconst STATE = {\r\n NONE: 0x00,\r\n PAN: 0x01,\r\n ROTATION: 0x02,\r\n ZOOM: 0x04,\r\n MOVE: 0x08,\r\n LOOK: 0x10,\r\n}\r\n\r\n/**\r\n * @class\r\n * @memberof module:pamir_base\r\n */\r\nclass BaseControls extends (events__WEBPACK_IMPORTED_MODULE_0___default()) {\r\n\r\n constructor(object, domElement, opts) {\r\n super()\r\n this.object_ = object\r\n this.domElement_ = domElement\r\n this.opts_ = opts || {}\r\n\r\n // for reset!\r\n // this.position0\r\n // this.target0\r\n\r\n this.state_ = STATE.NONE\r\n\r\n this.enabled_ = true\r\n this.update_enabled_() // call by extended class\r\n\r\n // #20220610, 兼容 orbit\r\n this.position0 = new three__WEBPACK_IMPORTED_MODULE_1__.Vector3()\r\n this.target0 = new three__WEBPACK_IMPORTED_MODULE_1__.Vector3()\r\n }\r\n\r\n set object(v) {\r\n this.object_ = v\r\n }\r\n\r\n get object() {\r\n return this.object_\r\n }\r\n\r\n get enabled() {\r\n return this.enabled_\r\n }\r\n\r\n set enabled(v) {\r\n if (v != this.enabled_) {\r\n this.enabled_ = v\r\n this.update_enabled_()\r\n }\r\n }\r\n\r\n // #20220610, 兼容 orbit\r\n reset() {\r\n // use position0, target0\r\n }\r\n\r\n update_enabled_() {\r\n }\r\n\r\n reset() {\r\n // ref to orbit!\r\n if (this.position0) {\r\n this.object_.position.copy(this.position0)\r\n }\r\n }\r\n\r\n dispose() {\r\n this.enabled = false\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n\r\n get state() {\r\n return this.state_\r\n }\r\n\r\n hasState(def_s) {\r\n return (this.state_ & def_s) > 0\r\n }\r\n\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BaseControls);\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/controls/BaseControls.js?");
/***/ }),
@@ -223,7 +223,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseEnvironment\": () => (/* binding */ BaseEnvironment),\n/* harmony export */ \"SkyType\": () => (/* binding */ SkyType),\n/* harmony export */ \"disable_gui_field\": () => (/* binding */ disable_gui_field)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_objects_Sky__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/objects/Sky */ \"./node_modules/_three@0.139.2@three/examples/jsm/objects/Sky.js\");\n/* harmony import */ var _util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n\r\n\r\n\r\n\r\nconst SkyType = {\r\n None: 0,\r\n // TwoColor: 1,\r\n Atmosphere: 2,\r\n}\r\n\r\nconst toneMappingOptions = {\r\n None: three__WEBPACK_IMPORTED_MODULE_2__.NoToneMapping,\r\n Linear: three__WEBPACK_IMPORTED_MODULE_2__.LinearToneMapping,\r\n Reinhard: three__WEBPACK_IMPORTED_MODULE_2__.ReinhardToneMapping,\r\n Cineon: three__WEBPACK_IMPORTED_MODULE_2__.CineonToneMapping,\r\n ACESFilmic: three__WEBPACK_IMPORTED_MODULE_2__.ACESFilmicToneMapping,\r\n // Custom: CustomToneMapping\r\n}\r\n\r\nconst disable_gui_field = f => {\r\n if (f) {\r\n if (f.disable) {\r\n f.disable()\r\n } else if (f.domElement) {\r\n let style = f.domElement.style\r\n style.pointerEvents = 'none'\r\n // style.transform = 'scale(0.5)'\r\n style.opacity = '0.33'\r\n }\r\n }\r\n}\r\n\r\nclass BaseEnvironment {\r\n\r\n constructor(viewer, opts) {\r\n this.viewer_ = viewer\r\n\r\n let skyAtmosphere = Object.assign({\r\n turbidity: 10,\r\n rayleigh: 3,\r\n mieCoefficient: 0.05, // 0.005,\r\n mieDirectionalG: 0.23, // 0.7,\r\n // 可能被 hour env 覆盖的参数\r\n elevation: 15,\r\n // azimuth: 90, //正东\r\n azimuth: 80, // 偏东南\r\n }, opts && opts.skyAtmosphere)\r\n\r\n this.opts_ = Object.assign({\r\n debug: false,\r\n skyType: SkyType.Atmosphere,\r\n // default NoToneMapping\r\n toneMapping: this.viewer_.renderer_.toneMapping,\r\n exposure: this.viewer_.renderer_.toneMappingExposure,\r\n // outputEncoding: // LinearEncoding\r\n }, opts)\r\n\r\n this.opts_.skyAtmosphere = skyAtmosphere\r\n\r\n }\r\n\r\n setup() {\r\n return new Promise(resolve => {\r\n\r\n console.log('setup base env!', this.opts_, this.viewer_.renderer_.outputEncoding)\r\n\r\n this.renderer_exp_0_ = this.viewer_.renderer_.toneMappingExposure\r\n\r\n if (this.opts_.skyType == SkyType.Atmosphere) {\r\n let sky = new three_examples_jsm_objects_Sky__WEBPACK_IMPORTED_MODULE_0__.Sky()\r\n sky.scale.setScalar(450000)\r\n this.viewer_.scene_.add(sky)\r\n this.skyAtmosphere_ = sky\r\n }\r\n\r\n // GUI\r\n const c_root = this.opts_\r\n const c_root_proxy = {\r\n toneMapping: Object.entries(toneMappingOptions).filter(([k, v]) => v == this.opts_.toneMapping)[0][0]\r\n }\r\n // console.log('c_root_proxy', c_root_proxy)\r\n const c_skyAtmosphere = this.opts_.skyAtmosphere\r\n\r\n // debug field!\r\n let f_elevation = null\r\n let f_azimuth = null\r\n\r\n this.sunDelta__ = {\r\n hold: 'base', // hold by base or other (ex. hour env)\r\n value: new three__WEBPACK_IMPORTED_MODULE_2__.Vector3()\r\n }\r\n\r\n const guiChanged = () => {\r\n\r\n if (this.sunDelta__.hold == 'base') {\r\n const phi = three__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(90 - c_skyAtmosphere.elevation)\r\n const theta = three__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(c_skyAtmosphere.azimuth)\r\n\r\n this.sunDelta__.value.setFromSphericalCoords(100, phi, theta)\r\n } else {\r\n // console.log(f_elevation)\r\n disable_gui_field(f_elevation)\r\n disable_gui_field(f_azimuth)\r\n }\r\n\r\n if (this.skyAtmosphere_) {\r\n const uniforms = this.skyAtmosphere_.material.uniforms\r\n uniforms['turbidity'].value = c_skyAtmosphere.turbidity\r\n uniforms['rayleigh'].value = 0 // c_skyAtmosphere.rayleigh\r\n uniforms['mieCoefficient'].value = c_skyAtmosphere.mieCoefficient\r\n uniforms['mieDirectionalG'].value = c_skyAtmosphere.mieDirectionalG\r\n // uniforms['sunPosition'].value.copy(this.sunDelta__.value)\r\n this.update_sun_delta_()\r\n }\r\n\r\n let v_tm = toneMappingOptions[c_root_proxy.toneMapping]\r\n if (v_tm != this.viewer_.renderer_.toneMapping) {\r\n this.viewer_.renderer_.toneMapping = v_tm\r\n if (three__WEBPACK_IMPORTED_MODULE_2__.REVISION <= 135) {\r\n this.viewer_.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n c.material.needsUpdate = true\r\n }\r\n })\r\n }\r\n }\r\n\r\n // this.viewer_.renderer_.toneMappingExposure = c_root.exposure\r\n this.renderer_exp_0_ = c_root.exposure\r\n this.update_light1_i_()\r\n\r\n }\r\n this.base_update__ = guiChanged\r\n\r\n if (this.opts_.debug && (0,_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_1__.getTuning)().gui) {\r\n const gui = (0,_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_1__.getTuning)().gui\r\n\r\n gui.add(c_root_proxy, 'toneMapping', Object.keys(toneMappingOptions)).onChange(guiChanged)\r\n gui.add(c_root, 'exposure', 0, 4, 0.0001).onChange(guiChanged)\r\n\r\n if (this.skyAtmosphere_) {\r\n let fsa = gui.addFolder('skyAtmosphere')\r\n fsa.add(c_skyAtmosphere, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged)\r\n //\r\n f_elevation = fsa.add(c_skyAtmosphere, 'elevation', -15, 90, 0.1).onChange(guiChanged)\r\n f_azimuth = fsa.add(c_skyAtmosphere, 'azimuth', - 180, 180, 0.1).onChange(guiChanged)\r\n }\r\n\r\n this.gui__ = gui\r\n }\r\n\r\n guiChanged()\r\n\r\n resolve()\r\n })\r\n }\r\n\r\n // to be override!\r\n update_light1_i_() {\r\n this.viewer_.renderer_.toneMappingExposure = this.renderer_exp_0_\r\n }\r\n\r\n // to be override!\r\n update_sun_delta_() {\r\n if (this.skyAtmosphere_) {\r\n const uniforms = this.skyAtmosphere_.material.uniforms\r\n uniforms['sunPosition'].value.copy(this.sunDelta__.value)\r\n }\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/environment/BaseEnvironment.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseEnvironment\": () => (/* binding */ BaseEnvironment),\n/* harmony export */ \"SkyType\": () => (/* binding */ SkyType),\n/* harmony export */ \"disable_gui_field\": () => (/* binding */ disable_gui_field)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_objects_Sky__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/objects/Sky */ \"./node_modules/_three@0.146.0@three/examples/jsm/objects/Sky.js\");\n/* harmony import */ var _util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n\r\n\r\n\r\n\r\nconst SkyType = {\r\n None: 0,\r\n // TwoColor: 1,\r\n Atmosphere: 2,\r\n}\r\n\r\nconst toneMappingOptions = {\r\n None: three__WEBPACK_IMPORTED_MODULE_1__.NoToneMapping,\r\n Linear: three__WEBPACK_IMPORTED_MODULE_1__.LinearToneMapping,\r\n Reinhard: three__WEBPACK_IMPORTED_MODULE_1__.ReinhardToneMapping,\r\n Cineon: three__WEBPACK_IMPORTED_MODULE_1__.CineonToneMapping,\r\n ACESFilmic: three__WEBPACK_IMPORTED_MODULE_1__.ACESFilmicToneMapping,\r\n // Custom: CustomToneMapping\r\n}\r\n\r\nconst disable_gui_field = f => {\r\n if (f) {\r\n if (f.disable) {\r\n f.disable()\r\n } else if (f.domElement) {\r\n let style = f.domElement.style\r\n style.pointerEvents = 'none'\r\n // style.transform = 'scale(0.5)'\r\n style.opacity = '0.33'\r\n }\r\n }\r\n}\r\n\r\nclass BaseEnvironment {\r\n\r\n constructor(viewer, opts) {\r\n this.viewer_ = viewer\r\n\r\n let skyAtmosphere = Object.assign({\r\n turbidity: 10,\r\n rayleigh: 3,\r\n mieCoefficient: 0.05, // 0.005,\r\n mieDirectionalG: 0.23, // 0.7,\r\n // 可能被 hour env 覆盖的参数\r\n elevation: 15,\r\n // azimuth: 90, //正东\r\n azimuth: 80, // 偏东南\r\n }, opts && opts.skyAtmosphere)\r\n\r\n this.opts_ = Object.assign({\r\n debug: false,\r\n skyType: SkyType.Atmosphere,\r\n // default NoToneMapping\r\n toneMapping: this.viewer_.renderer_.toneMapping,\r\n exposure: this.viewer_.renderer_.toneMappingExposure,\r\n // outputEncoding: // LinearEncoding\r\n }, opts)\r\n\r\n this.opts_.skyAtmosphere = skyAtmosphere\r\n\r\n }\r\n\r\n setup() {\r\n return new Promise(resolve => {\r\n\r\n console.log('setup base env!', this.opts_, this.viewer_.renderer_.outputEncoding)\r\n\r\n this.renderer_exp_0_ = this.viewer_.renderer_.toneMappingExposure\r\n\r\n if (this.opts_.skyType == SkyType.Atmosphere) {\r\n let sky = new three_examples_jsm_objects_Sky__WEBPACK_IMPORTED_MODULE_2__.Sky()\r\n sky.scale.setScalar(450000)\r\n this.viewer_.scene_.add(sky)\r\n this.skyAtmosphere_ = sky\r\n }\r\n\r\n // GUI\r\n const c_root = this.opts_\r\n const c_root_proxy = {\r\n toneMapping: Object.entries(toneMappingOptions).filter(([k, v]) => v == this.opts_.toneMapping)[0][0]\r\n }\r\n // console.log('c_root_proxy', c_root_proxy)\r\n const c_skyAtmosphere = this.opts_.skyAtmosphere\r\n\r\n // debug field!\r\n let f_elevation = null\r\n let f_azimuth = null\r\n\r\n this.sunDelta__ = {\r\n hold: 'base', // hold by base or other (ex. hour env)\r\n value: new three__WEBPACK_IMPORTED_MODULE_1__.Vector3()\r\n }\r\n\r\n const guiChanged = () => {\r\n\r\n if (this.sunDelta__.hold == 'base') {\r\n const phi = three__WEBPACK_IMPORTED_MODULE_1__.MathUtils.degToRad(90 - c_skyAtmosphere.elevation)\r\n const theta = three__WEBPACK_IMPORTED_MODULE_1__.MathUtils.degToRad(c_skyAtmosphere.azimuth)\r\n\r\n this.sunDelta__.value.setFromSphericalCoords(100, phi, theta)\r\n } else {\r\n // console.log(f_elevation)\r\n disable_gui_field(f_elevation)\r\n disable_gui_field(f_azimuth)\r\n }\r\n\r\n if (this.skyAtmosphere_) {\r\n const uniforms = this.skyAtmosphere_.material.uniforms\r\n uniforms['turbidity'].value = c_skyAtmosphere.turbidity\r\n uniforms['rayleigh'].value = 0 // c_skyAtmosphere.rayleigh\r\n uniforms['mieCoefficient'].value = c_skyAtmosphere.mieCoefficient\r\n uniforms['mieDirectionalG'].value = c_skyAtmosphere.mieDirectionalG\r\n // uniforms['sunPosition'].value.copy(this.sunDelta__.value)\r\n this.update_sun_delta_()\r\n }\r\n\r\n let v_tm = toneMappingOptions[c_root_proxy.toneMapping]\r\n if (v_tm != this.viewer_.renderer_.toneMapping) {\r\n this.viewer_.renderer_.toneMapping = v_tm\r\n if (three__WEBPACK_IMPORTED_MODULE_1__.REVISION <= 135) {\r\n this.viewer_.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n c.material.needsUpdate = true\r\n }\r\n })\r\n }\r\n }\r\n\r\n // this.viewer_.renderer_.toneMappingExposure = c_root.exposure\r\n this.renderer_exp_0_ = c_root.exposure\r\n this.update_light1_i_()\r\n\r\n }\r\n this.base_update__ = guiChanged\r\n\r\n if (this.opts_.debug && (0,_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_0__.getTuning)().gui) {\r\n const gui = (0,_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_0__.getTuning)().gui\r\n\r\n gui.add(c_root_proxy, 'toneMapping', Object.keys(toneMappingOptions)).onChange(guiChanged)\r\n gui.add(c_root, 'exposure', 0, 4, 0.0001).onChange(guiChanged)\r\n\r\n if (this.skyAtmosphere_) {\r\n let fsa = gui.addFolder('skyAtmosphere')\r\n fsa.add(c_skyAtmosphere, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged)\r\n fsa.add(c_skyAtmosphere, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged)\r\n //\r\n f_elevation = fsa.add(c_skyAtmosphere, 'elevation', -15, 90, 0.1).onChange(guiChanged)\r\n f_azimuth = fsa.add(c_skyAtmosphere, 'azimuth', - 180, 180, 0.1).onChange(guiChanged)\r\n }\r\n\r\n this.gui__ = gui\r\n }\r\n\r\n guiChanged()\r\n\r\n resolve()\r\n })\r\n }\r\n\r\n // to be override!\r\n update_light1_i_() {\r\n this.viewer_.renderer_.toneMappingExposure = this.renderer_exp_0_\r\n }\r\n\r\n // to be override!\r\n update_sun_delta_() {\r\n if (this.skyAtmosphere_) {\r\n const uniforms = this.skyAtmosphere_.material.uniforms\r\n uniforms['sunPosition'].value.copy(this.sunDelta__.value)\r\n }\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/environment/BaseEnvironment.js?");
/***/ }),
@@ -245,7 +245,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"PPRenderer\": () => (/* binding */ PPRenderer)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _Base_pp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Base_pp */ \"./src-kutsi/crossyo/kutsi/pp/Base_pp.js\");\n\r\n\r\n\r\n\r\nconst DEFAULT_PP = new _Base_pp__WEBPACK_IMPORTED_MODULE_0__.Base_pp()\r\n\r\nclass PPRenderer extends three__WEBPACK_IMPORTED_MODULE_1__.WebGLRenderer {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n this.pp_ = null\r\n }\r\n\r\n setup__(viewer, scene, camera) {\r\n this.viewer_ = viewer\r\n this.scene_ = scene\r\n this.camera_ = camera\r\n this.use_pp__(DEFAULT_PP)\r\n }\r\n\r\n use_pp__(pp) {\r\n this.pp_ = pp\r\n this.pp_.renderer_ = this\r\n this.pp_.viewer_ = this.viewer_\r\n this.pp_.scene_ = this.scene_\r\n this.pp_.camera_ = this.camera_\r\n this.pp_.use()\r\n }\r\n\r\n use_pp_default__(){\r\n this.use_pp__(DEFAULT_PP)\r\n }\r\n\r\n setSize__(w, h) {\r\n this.setSize(w, h)\r\n \r\n this.pp_.setSize(w, h)\r\n }\r\n\r\n render__() {\r\n this.pp_.render()\r\n }\r\n\r\n\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/pp/PPRenderer.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"PPRenderer\": () => (/* binding */ PPRenderer)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _Base_pp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Base_pp */ \"./src-kutsi/crossyo/kutsi/pp/Base_pp.js\");\n\r\n\r\n\r\n\r\nconst DEFAULT_PP = new _Base_pp__WEBPACK_IMPORTED_MODULE_0__.Base_pp()\r\n\r\nclass PPRenderer extends three__WEBPACK_IMPORTED_MODULE_1__.WebGLRenderer {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n this.pp_ = null\r\n }\r\n\r\n setup__(viewer, scene, camera) {\r\n this.viewer_ = viewer\r\n this.scene_ = scene\r\n this.camera_ = camera\r\n this.use_pp__(DEFAULT_PP)\r\n }\r\n\r\n use_pp__(pp) {\r\n this.pp_ = pp\r\n this.pp_.renderer_ = this\r\n this.pp_.viewer_ = this.viewer_\r\n this.pp_.scene_ = this.scene_\r\n this.pp_.camera_ = this.camera_\r\n this.pp_.use()\r\n }\r\n\r\n use_pp_default__(){\r\n this.use_pp__(DEFAULT_PP)\r\n }\r\n\r\n setSize__(w, h) {\r\n this.setSize(w, h)\r\n \r\n this.pp_.setSize(w, h)\r\n }\r\n\r\n render__() {\r\n this.pp_.render()\r\n }\r\n\r\n\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/pp/PPRenderer.js?");
/***/ }),
@@ -256,7 +256,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Builder\": () => (/* binding */ Builder)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.139.2@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../environment/BaseEnvironment */ \"./src-kutsi/crossyo/kutsi/environment/BaseEnvironment.js\");\n/* harmony import */ var _BuilderModel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BuilderModel */ \"./src-kutsi/crossyo/kutsi/util/BuilderModel.js\");\n/* harmony import */ var _BuilderTimeline__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./BuilderTimeline */ \"./src-kutsi/crossyo/kutsi/util/BuilderTimeline.js\");\n/* harmony import */ var _SceneTuningUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n\r\n\r\n\r\n/*\r\nimport { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'\r\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'\r\n*/\r\n\r\n\r\n\r\n// import { Sky } from 'three/examples/jsm/objects/Sky'\r\n\r\n// import { GUI } from 'three/examples/jsm/libs/dat.gui.module'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass Builder {\r\n\r\n constructor(opts, viewer) {\r\n this.opts_ = opts\r\n this.viewer_ = viewer\r\n }\r\n\r\n get renderer_() {\r\n if (!this.renderer__) {\r\n this.renderer__ = this.viewer_.renderer_\r\n }\r\n return this.renderer__\r\n }\r\n\r\n get scene_() {\r\n if (!this.scene__) {\r\n this.scene__ = this.viewer_.scene_\r\n }\r\n return this.scene__\r\n }\r\n\r\n get camera_() {\r\n if (!this.camera__) {\r\n this.camera__ = this.viewer_.camera_\r\n }\r\n return this.camera__\r\n }\r\n\r\n // from jx-map\r\n setupTimeline(param, next) {\r\n let timeline = new _BuilderTimeline__WEBPACK_IMPORTED_MODULE_3__.BuilderTimeline({\r\n viewer: this.viewer_,\r\n data: param.data,\r\n trackObjects: param.trackObjects,\r\n })\r\n if (param.onAfter) {\r\n param.onAfter(timeline)\r\n }\r\n next()\r\n }\r\n\r\n setupCustomization(param, next) {\r\n if (param.onDoing) {\r\n param.onDoing(next)\r\n } else {\r\n console.warning('setupCustomization require onDoing()!')\r\n }\r\n }\r\n\r\n setupEnvEquirect(param, next) {\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_5__.TextureLoader().load(param.url)\r\n tex.mapping = three__WEBPACK_IMPORTED_MODULE_5__.EquirectangularReflectionMapping\r\n if (this.opts_.trend.hdr) {\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_5__.sRGBEncoding\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n next()\r\n }\r\n\r\n setupEnvironment(param, next) {\r\n let env = new (param.clzEnvironment || _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_1__.BaseEnvironment)(this.viewer_, param)\r\n // console.log('setupEnvironment', env, param)\r\n env.setup().then(() => {\r\n if (param.onAfter) {\r\n param.onAfter(env) // #20220820, for hospital-hvac\r\n }\r\n next()\r\n })\r\n }\r\n\r\n // #20211123 from red-valley\r\n // #20220624 deprecated, recommend use setup environment instead\r\n setupSky(param, next) { // for compatible\r\n let param2 = {}\r\n if (param.useSky == true) {\r\n param2.skyType = _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_1__.SkyType.Atmosphere\r\n } else {\r\n param2.skyType = _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_1__.SkyType.None\r\n }\r\n\r\n new Array('debug', 'exposure', 'toneMapping').forEach(n => {\r\n if (param[n]) {\r\n param2[n] = param[n]\r\n }\r\n })\r\n\r\n let skyAtmosphere = new Array('turbidity', 'rayleigh', 'mieCoefficient', 'mieDirectionalG', 'elevation', 'azimuth').reduce((prev, n) => {\r\n if (param.hasOwnProperty(n)) {\r\n prev[n] = param[n]\r\n }\r\n return prev\r\n }, {})\r\n if (skyAtmosphere) {\r\n param2.skyAtmosphere = skyAtmosphere\r\n }\r\n\r\n console.log('use deprecated setupSky, transform param to prarm2', param2)\r\n\r\n // move to hour env!\r\n // useDirectionalLight: true,\r\n // directionalLightIntensity: 1,\r\n // useShadow: false,\r\n // shadowMapWidth: 2048,\r\n\r\n this.setupEnvironment(param2, next)\r\n }\r\n\r\n\r\n // setupSky_old(param, next) {\r\n\r\n // param = Object.assign({\r\n // debug: false,\r\n // useDirectionalLight: true,\r\n // directionalLightIntensity: 1,\r\n\r\n // useSky: true,\r\n // turbidity: .1, // 10,\r\n // rayleigh: .6, // 3,\r\n // mieCoefficient: 0.005,\r\n // mieDirectionalG: 0.7,\r\n // elevation: 15,\r\n // azimuth: 180,\r\n\r\n // exposure: this.renderer_.toneMappingExposure,\r\n\r\n // useShadow: false,\r\n // shadowMapWidth: 2048,\r\n\r\n // toneMapping: null,\r\n\r\n // }, param)\r\n\r\n // if (param.toneMapping) {\r\n // this.renderer_.toneMapping = param.toneMapping\r\n // }\r\n\r\n // let sky = null\r\n // if (param.useSky) {\r\n // sky = new Sky()\r\n // sky.scale.setScalar(450000)\r\n // this.scene_.add(sky)\r\n // }\r\n // //\r\n // let sun = new THREE.Vector3()\r\n // let light = null\r\n // if (param.useDirectionalLight) {\r\n\r\n // light = new THREE.DirectionalLight(0xffffff, param.directionalLightIntensity)\r\n // this.scene_.add(light)\r\n // }\r\n // //\r\n // if (param.useDirectionalLight && param.useShadow) {\r\n // this.renderer_.shadowMap.enabled = true\r\n // this.renderer_.shadowMap.type = PCFSoftShadowMap\r\n\r\n // light.castShadow = true\r\n // light.shadow.camera.near = 10\r\n // light.shadow.camera.far = 10000\r\n // let d = 200\r\n // light.shadow.camera.left = -d\r\n // light.shadow.camera.right = d\r\n // light.shadow.camera.top = d\r\n // light.shadow.camera.bottom = -d\r\n // light.shadow.mapSize.width = param.shadowMapWidth\r\n // light.shadow.mapSize.height = param.shadowMapWidth\r\n // }\r\n\r\n // /// GUI\r\n\r\n // const effectController = param\r\n\r\n // const guiChanged = () => {\r\n\r\n // const phi = THREE.MathUtils.degToRad(90 - effectController.elevation)\r\n // const theta = THREE.MathUtils.degToRad(effectController.azimuth)\r\n\r\n // sun.setFromSphericalCoords(100, phi, theta)\r\n\r\n // if (sky) {\r\n // const uniforms = sky.material.uniforms\r\n // uniforms['turbidity'].value = effectController.turbidity\r\n // uniforms['rayleigh'].value = effectController.rayleigh\r\n // uniforms['mieCoefficient'].value = effectController.mieCoefficient\r\n // uniforms['mieDirectionalG'].value = effectController.mieDirectionalG\r\n // uniforms['sunPosition'].value.copy(sun)\r\n // }\r\n\r\n // this.renderer_.toneMappingExposure = effectController.exposure\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n\r\n // if (light) {\r\n // light.position.copy(sun)\r\n // }\r\n\r\n // }\r\n\r\n // if (param.debug && registerClass.GUI) {\r\n // const gui = new registerClass.GUI()\r\n\r\n // if (sky) {\r\n // gui.add(effectController, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged)\r\n // gui.add(effectController, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged)\r\n // gui.add(effectController, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged)\r\n // }\r\n // gui.add(effectController, 'elevation', -15, 90, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'azimuth', - 180, 180, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'exposure', 0, 4, 0.0001).onChange(guiChanged)\r\n // }\r\n\r\n // guiChanged()\r\n\r\n // next()\r\n // }\r\n\r\n // #20220409, for modeling\r\n setupLight(param, next) {\r\n\r\n // scan lights\r\n\r\n let mats = {}\r\n this.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n let mid = c.material.uuid\r\n if (!mats[mid]) {\r\n mats[mid] = c.material\r\n }\r\n }\r\n })\r\n let arr_mats = Object.values(mats)\r\n\r\n let controller = Object.assign({\r\n lightMapIntensity: 1,\r\n envMapIntensity: 1,\r\n }, param)\r\n\r\n const guiChanged = () => {\r\n\r\n arr_mats.forEach(mat => {\r\n mat.lightMapIntensity = controller.lightMapIntensity\r\n mat.envMapIntensity = controller.envMapIntensity\r\n })\r\n\r\n }\r\n\r\n if ((0,_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_4__.getTuning)().gui) {\r\n const gui = (0,_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_4__.getTuning)().gui\r\n gui.add(controller, 'lightMapIntensity', 0, 20, .01).onChange(guiChanged)\r\n gui.add(controller, 'envMapIntensity', 0, 2, .01).onChange(guiChanged)\r\n }\r\n\r\n guiChanged()\r\n\r\n\r\n next()\r\n }\r\n\r\n // #20211124, from package-diy, for metro-l6\r\n // @deprecated 20220404\r\n // setupExpoLight(param, next) {\r\n // param = Object.assign({\r\n // debug: false,\r\n // intensity: 1,\r\n // }, param)\r\n\r\n // let r = 30\r\n // let dirs = [\r\n // { pos: new THREE.Vector3(0, r, 0), strength: 1 }\r\n // ]\r\n // for (let i = 0; i < 4; i++) {\r\n // let a = Math.PI * .125 + i * Math.PI * .5\r\n // dirs.push({ pos: new THREE.Vector3(r * Math.cos(a), r * .2, r * Math.sin(a)), strength: .75 })\r\n\r\n // }\r\n\r\n // dirs.push({ pos: new THREE.Vector3(0, -r, 0), strength: .75 })\r\n\r\n // // let rets = []\r\n // for (var dir of dirs) {\r\n // var dirLight = new THREE.DirectionalLight(0xffffff, dir.strength * param.intensity)\r\n // dirLight.position.copy(dir.pos)\r\n // this.scene_.add(dirLight)\r\n // // rets.push(dirLight)\r\n\r\n // if (param.debug) {\r\n // this.scene_.add(new THREE.DirectionalLightHelper(dirLight))\r\n // }\r\n\r\n // // let light = new THREE.PointLight(0xffffff, dir.strength)\r\n // // light.position.copy(dir.pos)\r\n // // this.scene_.add(light)\r\n // // rets.push(light)\r\n // }\r\n\r\n // next()\r\n\r\n // }\r\n\r\n setupTexture(param, next) {\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_5__.TextureLoader().load(param.url)\r\n if (this.opts_.trend.hdr) {\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_5__.sRGBEncoding\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n next()\r\n }\r\n\r\n // from material accounting\r\n setupTextures(param, next) {\r\n for (let key in param.objTextures) {\r\n let ot = param.objTextures[key]\r\n ot.texture = new three__WEBPACK_IMPORTED_MODULE_5__.TextureLoader().load(ot.url)\r\n if (this.opts_.trend.hdr) {\r\n ot.encoding = three__WEBPACK_IMPORTED_MODULE_5__.sRGBEncoding\r\n }\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(param.objTextures)\r\n }\r\n next()\r\n }\r\n\r\n /*\r\n setupModelMtlObj(param, next) {\r\n let mgr = new THREE.LoadingManager()\r\n new MTLLoader(mgr).setPath(param.path).load(`${param.name}.mtl`, mats => {\r\n mats.preload()\r\n new OBJLoader(mgr).setPath(path).setMaterials(mats).load(`${param.name}.obj`, obj => {\r\n if (param.onAfter) {\r\n param.onAfter(obj)\r\n }\r\n next()\r\n })\r\n })\r\n }\r\n */\r\n\r\n setupModelGltf(param, next) {\r\n console.log(param)\r\n if (param.url && (!param.path || !param.name)) { // #20220703, from actuator-1\r\n let url = param.url\r\n let ls = url.lastIndexOf('/')\r\n if (ls >= 0) {\r\n param.path = url.substring(0, ls + 1)\r\n param.name = url.substring(ls + 1)\r\n } else {\r\n param.path = './'\r\n param.name = url\r\n }\r\n }\r\n\r\n new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader().setPath(param.path).load(`${param.name}`, gltf => {\r\n // console.log(gltf)\r\n const after_predefined_ = () => {\r\n if (param.onAfter) {\r\n param.onAfter(gltf.scene)\r\n }\r\n next()\r\n }\r\n if (param.predefinedModel) { // from jx-map\r\n /**\r\n * {\r\n * aoMapLinearEncoding: false, // #20220603,for kiwi\r\n * depressWarning: false,\r\n * maps: {\r\n * 'map1': {url: '*.png'}\r\n * },\r\n * objects_isolate_material: true, // default false\r\n * objects_re: [ // 更低优先级!\r\n * {re: /^(?!.*(-ceiling|-wall|-floor|-socket)).*$/, lightMap: '', aoMap:'' }\r\n * ],\r\n * objects: {\r\n * 'obj-1': {\r\n * lightMap: '',\r\n * aoMap: '',\r\n * aoMapIntensity: 1,\r\n * color: new Color(0xff0000),\r\n * opacity: 1,\r\n * geo: {\r\n * swapUv:false|true, \r\n * uvToUv2:false|true\r\n * },\r\n * }\r\n * },\r\n * materials_re: [ // 更低优先级!\r\n * {}\r\n * ],\r\n * materials: {\r\n * '': {}\r\n * },\r\n * }\r\n * \r\n * 补充写法1)scan _bake_names ref to smart-farm\r\n */\r\n new _BuilderModel__WEBPACK_IMPORTED_MODULE_2__.BuilderModel({\r\n prefixAsset: this.viewer_.prefixAsset_,\r\n data: param.predefinedModel\r\n }).process(gltf.scene, after_predefined_)\r\n } else {\r\n after_predefined_()\r\n }\r\n })\r\n }\r\n\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/Builder.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Builder\": () => (/* binding */ Builder)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.146.0@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../environment/BaseEnvironment */ \"./src-kutsi/crossyo/kutsi/environment/BaseEnvironment.js\");\n/* harmony import */ var _BuilderModel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BuilderModel */ \"./src-kutsi/crossyo/kutsi/util/BuilderModel.js\");\n/* harmony import */ var _BuilderTimeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BuilderTimeline */ \"./src-kutsi/crossyo/kutsi/util/BuilderTimeline.js\");\n/* harmony import */ var _SceneTuningUtil__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n\r\n\r\n\r\n/*\r\nimport { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'\r\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'\r\n*/\r\n\r\n\r\n\r\n// import { Sky } from 'three/examples/jsm/objects/Sky'\r\n\r\n// import { GUI } from 'three/examples/jsm/libs/dat.gui.module'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass Builder {\r\n\r\n constructor(opts, viewer) {\r\n this.opts_ = opts\r\n this.viewer_ = viewer\r\n }\r\n\r\n get renderer_() {\r\n if (!this.renderer__) {\r\n this.renderer__ = this.viewer_.renderer_\r\n }\r\n return this.renderer__\r\n }\r\n\r\n get scene_() {\r\n if (!this.scene__) {\r\n this.scene__ = this.viewer_.scene_\r\n }\r\n return this.scene__\r\n }\r\n\r\n get camera_() {\r\n if (!this.camera__) {\r\n this.camera__ = this.viewer_.camera_\r\n }\r\n return this.camera__\r\n }\r\n\r\n // from jx-map\r\n setupTimeline(param, next) {\r\n let timeline = new _BuilderTimeline__WEBPACK_IMPORTED_MODULE_2__.BuilderTimeline({\r\n viewer: this.viewer_,\r\n data: param.data,\r\n trackObjects: param.trackObjects,\r\n })\r\n if (param.onAfter) {\r\n param.onAfter(timeline)\r\n }\r\n next()\r\n }\r\n\r\n setupCustomization(param, next) {\r\n if (param.onDoing) {\r\n param.onDoing(next)\r\n } else {\r\n console.warning('setupCustomization require onDoing()!')\r\n }\r\n }\r\n\r\n setupEnvEquirect(param, next) {\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_4__.TextureLoader().load(param.url)\r\n tex.mapping = three__WEBPACK_IMPORTED_MODULE_4__.EquirectangularReflectionMapping\r\n if (this.opts_.trend.hdr) {\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_4__.sRGBEncoding\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n next()\r\n }\r\n\r\n setupEnvironment(param, next) {\r\n let env = new (param.clzEnvironment || _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_0__.BaseEnvironment)(this.viewer_, param)\r\n // console.log('setupEnvironment', env, param)\r\n env.setup().then(() => {\r\n if (param.onAfter) {\r\n param.onAfter(env) // #20220820, for hospital-hvac\r\n }\r\n next()\r\n })\r\n }\r\n\r\n // #20211123 from red-valley\r\n // #20220624 deprecated, recommend use setup environment instead\r\n setupSky(param, next) { // for compatible\r\n let param2 = {}\r\n if (param.useSky == true) {\r\n param2.skyType = _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_0__.SkyType.Atmosphere\r\n } else {\r\n param2.skyType = _environment_BaseEnvironment__WEBPACK_IMPORTED_MODULE_0__.SkyType.None\r\n }\r\n\r\n new Array('debug', 'exposure', 'toneMapping').forEach(n => {\r\n if (param[n]) {\r\n param2[n] = param[n]\r\n }\r\n })\r\n\r\n let skyAtmosphere = new Array('turbidity', 'rayleigh', 'mieCoefficient', 'mieDirectionalG', 'elevation', 'azimuth').reduce((prev, n) => {\r\n if (param.hasOwnProperty(n)) {\r\n prev[n] = param[n]\r\n }\r\n return prev\r\n }, {})\r\n if (skyAtmosphere) {\r\n param2.skyAtmosphere = skyAtmosphere\r\n }\r\n\r\n console.log('use deprecated setupSky, transform param to prarm2', param2)\r\n\r\n // move to hour env!\r\n // useDirectionalLight: true,\r\n // directionalLightIntensity: 1,\r\n // useShadow: false,\r\n // shadowMapWidth: 2048,\r\n\r\n this.setupEnvironment(param2, next)\r\n }\r\n\r\n\r\n // setupSky_old(param, next) {\r\n\r\n // param = Object.assign({\r\n // debug: false,\r\n // useDirectionalLight: true,\r\n // directionalLightIntensity: 1,\r\n\r\n // useSky: true,\r\n // turbidity: .1, // 10,\r\n // rayleigh: .6, // 3,\r\n // mieCoefficient: 0.005,\r\n // mieDirectionalG: 0.7,\r\n // elevation: 15,\r\n // azimuth: 180,\r\n\r\n // exposure: this.renderer_.toneMappingExposure,\r\n\r\n // useShadow: false,\r\n // shadowMapWidth: 2048,\r\n\r\n // toneMapping: null,\r\n\r\n // }, param)\r\n\r\n // if (param.toneMapping) {\r\n // this.renderer_.toneMapping = param.toneMapping\r\n // }\r\n\r\n // let sky = null\r\n // if (param.useSky) {\r\n // sky = new Sky()\r\n // sky.scale.setScalar(450000)\r\n // this.scene_.add(sky)\r\n // }\r\n // //\r\n // let sun = new THREE.Vector3()\r\n // let light = null\r\n // if (param.useDirectionalLight) {\r\n\r\n // light = new THREE.DirectionalLight(0xffffff, param.directionalLightIntensity)\r\n // this.scene_.add(light)\r\n // }\r\n // //\r\n // if (param.useDirectionalLight && param.useShadow) {\r\n // this.renderer_.shadowMap.enabled = true\r\n // this.renderer_.shadowMap.type = PCFSoftShadowMap\r\n\r\n // light.castShadow = true\r\n // light.shadow.camera.near = 10\r\n // light.shadow.camera.far = 10000\r\n // let d = 200\r\n // light.shadow.camera.left = -d\r\n // light.shadow.camera.right = d\r\n // light.shadow.camera.top = d\r\n // light.shadow.camera.bottom = -d\r\n // light.shadow.mapSize.width = param.shadowMapWidth\r\n // light.shadow.mapSize.height = param.shadowMapWidth\r\n // }\r\n\r\n // /// GUI\r\n\r\n // const effectController = param\r\n\r\n // const guiChanged = () => {\r\n\r\n // const phi = THREE.MathUtils.degToRad(90 - effectController.elevation)\r\n // const theta = THREE.MathUtils.degToRad(effectController.azimuth)\r\n\r\n // sun.setFromSphericalCoords(100, phi, theta)\r\n\r\n // if (sky) {\r\n // const uniforms = sky.material.uniforms\r\n // uniforms['turbidity'].value = effectController.turbidity\r\n // uniforms['rayleigh'].value = effectController.rayleigh\r\n // uniforms['mieCoefficient'].value = effectController.mieCoefficient\r\n // uniforms['mieDirectionalG'].value = effectController.mieDirectionalG\r\n // uniforms['sunPosition'].value.copy(sun)\r\n // }\r\n\r\n // this.renderer_.toneMappingExposure = effectController.exposure\r\n // this.renderer_.render(this.scene_, this.camera_)\r\n\r\n // if (light) {\r\n // light.position.copy(sun)\r\n // }\r\n\r\n // }\r\n\r\n // if (param.debug && registerClass.GUI) {\r\n // const gui = new registerClass.GUI()\r\n\r\n // if (sky) {\r\n // gui.add(effectController, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged)\r\n // gui.add(effectController, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged)\r\n // gui.add(effectController, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged)\r\n // }\r\n // gui.add(effectController, 'elevation', -15, 90, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'azimuth', - 180, 180, 0.1).onChange(guiChanged)\r\n // gui.add(effectController, 'exposure', 0, 4, 0.0001).onChange(guiChanged)\r\n // }\r\n\r\n // guiChanged()\r\n\r\n // next()\r\n // }\r\n\r\n // #20220409, for modeling\r\n setupLight(param, next) {\r\n\r\n // scan lights\r\n\r\n let mats = {}\r\n this.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n let mid = c.material.uuid\r\n if (!mats[mid]) {\r\n mats[mid] = c.material\r\n }\r\n }\r\n })\r\n let arr_mats = Object.values(mats)\r\n\r\n let controller = Object.assign({\r\n lightMapIntensity: 1,\r\n envMapIntensity: 1,\r\n }, param)\r\n\r\n const guiChanged = () => {\r\n\r\n arr_mats.forEach(mat => {\r\n mat.lightMapIntensity = controller.lightMapIntensity\r\n mat.envMapIntensity = controller.envMapIntensity\r\n })\r\n\r\n }\r\n\r\n if ((0,_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_3__.getTuning)().gui) {\r\n const gui = (0,_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_3__.getTuning)().gui\r\n gui.add(controller, 'lightMapIntensity', 0, 20, .01).onChange(guiChanged)\r\n gui.add(controller, 'envMapIntensity', 0, 2, .01).onChange(guiChanged)\r\n }\r\n\r\n guiChanged()\r\n\r\n\r\n next()\r\n }\r\n\r\n // #20211124, from package-diy, for metro-l6\r\n // @deprecated 20220404\r\n // setupExpoLight(param, next) {\r\n // param = Object.assign({\r\n // debug: false,\r\n // intensity: 1,\r\n // }, param)\r\n\r\n // let r = 30\r\n // let dirs = [\r\n // { pos: new THREE.Vector3(0, r, 0), strength: 1 }\r\n // ]\r\n // for (let i = 0; i < 4; i++) {\r\n // let a = Math.PI * .125 + i * Math.PI * .5\r\n // dirs.push({ pos: new THREE.Vector3(r * Math.cos(a), r * .2, r * Math.sin(a)), strength: .75 })\r\n\r\n // }\r\n\r\n // dirs.push({ pos: new THREE.Vector3(0, -r, 0), strength: .75 })\r\n\r\n // // let rets = []\r\n // for (var dir of dirs) {\r\n // var dirLight = new THREE.DirectionalLight(0xffffff, dir.strength * param.intensity)\r\n // dirLight.position.copy(dir.pos)\r\n // this.scene_.add(dirLight)\r\n // // rets.push(dirLight)\r\n\r\n // if (param.debug) {\r\n // this.scene_.add(new THREE.DirectionalLightHelper(dirLight))\r\n // }\r\n\r\n // // let light = new THREE.PointLight(0xffffff, dir.strength)\r\n // // light.position.copy(dir.pos)\r\n // // this.scene_.add(light)\r\n // // rets.push(light)\r\n // }\r\n\r\n // next()\r\n\r\n // }\r\n\r\n setupTexture(param, next) {\r\n let tex = new three__WEBPACK_IMPORTED_MODULE_4__.TextureLoader().load(param.url)\r\n if (this.opts_.trend.hdr) {\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_4__.sRGBEncoding\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n next()\r\n }\r\n\r\n // from material accounting\r\n setupTextures(param, next) {\r\n for (let key in param.objTextures) {\r\n let ot = param.objTextures[key]\r\n ot.texture = new three__WEBPACK_IMPORTED_MODULE_4__.TextureLoader().load(ot.url)\r\n if (this.opts_.trend.hdr) {\r\n ot.encoding = three__WEBPACK_IMPORTED_MODULE_4__.sRGBEncoding\r\n }\r\n }\r\n if (param.onAfter) {\r\n param.onAfter(param.objTextures)\r\n }\r\n next()\r\n }\r\n\r\n /*\r\n setupModelMtlObj(param, next) {\r\n let mgr = new THREE.LoadingManager()\r\n new MTLLoader(mgr).setPath(param.path).load(`${param.name}.mtl`, mats => {\r\n mats.preload()\r\n new OBJLoader(mgr).setPath(path).setMaterials(mats).load(`${param.name}.obj`, obj => {\r\n if (param.onAfter) {\r\n param.onAfter(obj)\r\n }\r\n next()\r\n })\r\n })\r\n }\r\n */\r\n\r\n setupModelGltf(param, next) {\r\n console.log(param)\r\n if (param.url && (!param.path || !param.name)) { // #20220703, from actuator-1\r\n let url = param.url\r\n let ls = url.lastIndexOf('/')\r\n if (ls >= 0) {\r\n param.path = url.substring(0, ls + 1)\r\n param.name = url.substring(ls + 1)\r\n } else {\r\n param.path = './'\r\n param.name = url\r\n }\r\n }\r\n\r\n new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_5__.GLTFLoader().setPath(param.path).load(`${param.name}`, gltf => {\r\n // console.log(gltf)\r\n const after_predefined_ = () => {\r\n if (param.onAfter) {\r\n param.onAfter(gltf.scene)\r\n }\r\n next()\r\n }\r\n if (param.predefinedModel) { // from jx-map\r\n /**\r\n * {\r\n * aoMapLinearEncoding: false, // #20220603,for kiwi\r\n * depressWarning: false,\r\n * maps: {\r\n * 'map1': {url: '*.png'}\r\n * },\r\n * objects_isolate_material: true, // default false\r\n * objects_re: [ // 更低优先级!\r\n * {re: /^(?!.*(-ceiling|-wall|-floor|-socket)).*$/, lightMap: '', aoMap:'' }\r\n * ],\r\n * objects: {\r\n * 'obj-1': {\r\n * lightMap: '',\r\n * aoMap: '',\r\n * aoMapIntensity: 1,\r\n * color: new Color(0xff0000),\r\n * opacity: 1,\r\n * geo: {\r\n * swapUv:false|true, \r\n * uvToUv2:false|true\r\n * },\r\n * }\r\n * },\r\n * materials_re: [ // 更低优先级!\r\n * {}\r\n * ],\r\n * materials: {\r\n * '': {}\r\n * },\r\n * }\r\n * \r\n * 补充写法1)scan _bake_names ref to smart-farm\r\n */\r\n new _BuilderModel__WEBPACK_IMPORTED_MODULE_1__.BuilderModel({\r\n prefixAsset: this.viewer_.prefixAsset_,\r\n data: param.predefinedModel\r\n }).process(gltf.scene, after_predefined_)\r\n } else {\r\n after_predefined_()\r\n }\r\n })\r\n }\r\n\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/Builder.js?");
/***/ }),
@@ -267,7 +267,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BuilderEx\": () => (/* binding */ BuilderEx)\n/* harmony export */ });\n/* harmony import */ var _Builder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Builder */ \"./src-kutsi/crossyo/kutsi/util/Builder.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_RGBELoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three/examples/jsm/loaders/RGBELoader */ \"./node_modules/_three@0.139.2@three/examples/jsm/loaders/RGBELoader.js\");\n/* harmony import */ var three_examples_jsm_loaders_EXRLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/loaders/EXRLoader */ \"./node_modules/_three@0.139.2@three/examples/jsm/loaders/EXRLoader.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * 由于可能引用three examples扩展库,独立参数化,默认时,只用Builder,可以减少不必要的包大小\r\n */\r\nclass BuilderEx extends _Builder__WEBPACK_IMPORTED_MODULE_0__.Builder {\r\n\r\n constructor(opts, viewer) {\r\n super(opts, viewer)\r\n }\r\n\r\n setupEnvEquirect(param, next) {\r\n let is_hdr = /\\.hdr$/.test(param.url)\r\n let is_exr = /\\.exr$/.test(param.url)\r\n if (is_hdr || is_exr) { // #20220314, for vlab3-lab\r\n\r\n let pmrem_gen = new three__WEBPACK_IMPORTED_MODULE_3__.PMREMGenerator(this.viewer_.renderer_)\r\n pmrem_gen.compileEquirectangularShader()\r\n\r\n let clzLoader = is_hdr ? three_examples_jsm_loaders_RGBELoader__WEBPACK_IMPORTED_MODULE_1__.RGBELoader : three_examples_jsm_loaders_EXRLoader__WEBPACK_IMPORTED_MODULE_2__.EXRLoader\r\n\r\n new clzLoader()\r\n // .setDataType(UnsignedByteType)\r\n .load(param.url, hdr => {\r\n\r\n let tex = pmrem_gen.fromEquirectangular(hdr).texture\r\n pmrem_gen.dispose()\r\n hdr.dispose()\r\n\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n\r\n next()\r\n\r\n })\r\n\r\n } else {\r\n super.setupEnvEquirect(param, next)\r\n }\r\n }\r\n\r\n \r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/BuilderEx.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BuilderEx\": () => (/* binding */ BuilderEx)\n/* harmony export */ });\n/* harmony import */ var _Builder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Builder */ \"./src-kutsi/crossyo/kutsi/util/Builder.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_RGBELoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/loaders/RGBELoader */ \"./node_modules/_three@0.146.0@three/examples/jsm/loaders/RGBELoader.js\");\n/* harmony import */ var three_examples_jsm_loaders_EXRLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/loaders/EXRLoader */ \"./node_modules/_three@0.146.0@three/examples/jsm/loaders/EXRLoader.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * 由于可能引用three examples扩展库,独立参数化,默认时,只用Builder,可以减少不必要的包大小\r\n */\r\nclass BuilderEx extends _Builder__WEBPACK_IMPORTED_MODULE_0__.Builder {\r\n\r\n constructor(opts, viewer) {\r\n super(opts, viewer)\r\n }\r\n\r\n setupEnvEquirect(param, next) {\r\n let is_hdr = /\\.hdr$/.test(param.url)\r\n let is_exr = /\\.exr$/.test(param.url)\r\n if (is_hdr || is_exr) { // #20220314, for vlab3-lab\r\n\r\n let pmrem_gen = new three__WEBPACK_IMPORTED_MODULE_1__.PMREMGenerator(this.viewer_.renderer_)\r\n pmrem_gen.compileEquirectangularShader()\r\n\r\n let clzLoader = is_hdr ? three_examples_jsm_loaders_RGBELoader__WEBPACK_IMPORTED_MODULE_2__.RGBELoader : three_examples_jsm_loaders_EXRLoader__WEBPACK_IMPORTED_MODULE_3__.EXRLoader\r\n\r\n new clzLoader()\r\n // .setDataType(UnsignedByteType)\r\n .load(param.url, hdr => {\r\n\r\n let tex = pmrem_gen.fromEquirectangular(hdr).texture\r\n pmrem_gen.dispose()\r\n hdr.dispose()\r\n\r\n if (param.onAfter) {\r\n param.onAfter(tex)\r\n }\r\n\r\n next()\r\n\r\n })\r\n\r\n } else {\r\n super.setupEnvEquirect(param, next)\r\n }\r\n }\r\n\r\n \r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/BuilderEx.js?");
/***/ }),
@@ -278,7 +278,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BuilderModel\": () => (/* binding */ BuilderModel)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\nconst check_uv2_ = (meshes, depressWarning) => {\r\n if (!depressWarning) {\r\n if (meshes && meshes.length > 0) {\r\n meshes.forEach(m => {\r\n if (!m.geometry.attributes['uv2']) {\r\n console.warn('mesh', m, 'has no uv2!')\r\n }\r\n })\r\n }\r\n }\r\n}\r\n\r\n// #20220603, 通过string或者直接引用变量\r\nconst find_map__ = (maps, map) => {\r\n if (typeof map === 'string') {\r\n return maps[map]\r\n } else {\r\n return map\r\n }\r\n}\r\n\r\n// meshes for validate!\r\nconst process_def_material_ = (def, material, maps, meshes, data) => {\r\n\r\n if (def.hasOwnProperty('map')) {\r\n if (def.map == null) {\r\n material.map = null\r\n } else {\r\n // let fm = maps[def.map]\r\n let fm = find_map__(maps, def.map)\r\n if (fm) {\r\n material.map = fm.tex_\r\n } else {\r\n console.warn('map未發現(map)', def.map)\r\n }\r\n }\r\n }\r\n if (def.hasOwnProperty('lightMap')) {\r\n\r\n check_uv2_(meshes, data.depressWarning)\r\n\r\n if (def.lightMap == null) {\r\n material.lightMap = null // 不太可能發生,目前導出來看!\r\n } else {\r\n // let fm = maps[def.lightMap]\r\n let fm = find_map__(maps, def.lightMap)\r\n if (fm) {\r\n material.lightMap = fm.tex_\r\n // material.lightMapIntensity = 10 // material.envMapIntensity\r\n // material.envMapIntensity = .9\r\n } else {\r\n console.warn('map未發現(lightMap)', def.lightMap)\r\n }\r\n }\r\n }\r\n if (def.hasOwnProperty('aoMap')) {\r\n\r\n check_uv2_(meshes, data.depressWarning)\r\n\r\n if (def.aoMap == null) {\r\n material.aoMap = null // 不太可能發生,目前導出來看!\r\n } else {\r\n // let fm = maps[def.aoMap]\r\n let fm = find_map__(maps, def.aoMap)\r\n if (fm) {\r\n if (data.aoMapLinearEncoding) { // #20220603,for kiwi\r\n fm.tex_.encoding = three__WEBPACK_IMPORTED_MODULE_0__.LinearEncoding\r\n fm.tex_.needsUpdate = true\r\n }\r\n\r\n material.aoMap = fm.tex_\r\n } else {\r\n console.warn('map未發現(aoMap)', def.aoMap)\r\n }\r\n }\r\n }\r\n\r\n if (def.hasOwnProperty('lightMapIntensity')) {\r\n material.lightMapIntensity = def.lightMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('aoMapIntensity')) {\r\n material.aoMapIntensity = def.aoMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('envMapIntensity')) {\r\n material.envMapIntensity = def.envMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('blending')) {\r\n material.blending = def.blending\r\n }\r\n\r\n if (def.hasOwnProperty('color')) {\r\n material.color = def.color\r\n }\r\n\r\n if (def.hasOwnProperty('opacity')) {\r\n material.opacity = def.opacity\r\n }\r\n\r\n // #20220404\r\n if (def.hasOwnProperty('metalness')) {\r\n material.metalness = def.metalness\r\n }\r\n\r\n if (def.hasOwnProperty('roughness')) {\r\n material.roughness = def.roughness\r\n }\r\n\r\n material.needsUpdate = true\r\n}\r\n\r\n\r\nconst def_geo_process_ = (geo, m) => {\r\n\r\n // m.geometry\r\n let uv = m.geometry.attributes['uv']\r\n let uv2 = m.geometry.attributes['uv2']\r\n\r\n if (geo.swapUv) {\r\n if (uv && uv2) {\r\n m.geometry.attributes['uv'] = uv2\r\n m.geometry.attributes['uv2'] = uv\r\n }\r\n } else if (geo.uvToUv2) {\r\n if (uv) {\r\n console.log('geo.uvToUv2')\r\n m.geometry.attributes['uv2'] = uv\r\n // m.geometry.deleteAttribute('uv')\r\n }\r\n }\r\n\r\n}\r\n\r\n// from jx-map\r\n// #20220126, for campus\r\nclass BuilderModel {\r\n\r\n constructor({ prefixAsset, data }) {\r\n this.prefixAsset_ = prefixAsset\r\n this.data_ = data\r\n // aoMapLinearEncoding\r\n this.data_.depressWarning = this.data_.depressWarning || false\r\n }\r\n\r\n process(o3d, onCompletion) {\r\n\r\n let maps = this.data_.maps\r\n if (maps) {\r\n\r\n Promise.all(\r\n Object.values(maps).map(map => {\r\n return new Promise((resolv, reject) => {\r\n new three__WEBPACK_IMPORTED_MODULE_0__.TextureLoader().load(`${this.prefixAsset_}/${map.url}`, tex => {\r\n tex.flipY = false\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_0__.sRGBEncoding\r\n // tex.encoding = LinearEncoding // aoMap 在後續修正\r\n tex.needsUpdate = true\r\n map.tex_ = tex\r\n resolv(tex)\r\n }, null, () => {\r\n reject()\r\n })\r\n })\r\n })\r\n ).then(() => {\r\n // console.log(maps)\r\n this.process_2_(o3d, onCompletion)\r\n })\r\n\r\n } else {\r\n this.process_2_(o3d, onCompletion)\r\n }\r\n }\r\n\r\n process_2_(o3d, onCompletion) {\r\n\r\n let maps = this.data_.maps\r\n\r\n {// #20220314, from vlab3-lab\r\n let mats_re = this.data_.materials_re // 未经测试!\r\n if (mats_re) {\r\n this.data_.materials = this.data_.materials || {}\r\n o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n let matname = c.material.name\r\n mats_re.forEach(d => {\r\n if (d.re.test(matname)) {\r\n this.data_.materials[matname] = Object.assign(\r\n Object.assign({}, d),\r\n this.data_.materials[matname]\r\n )\r\n }\r\n })\r\n // }\r\n })\r\n }\r\n let objs_re = this.data_.objects_re\r\n if (objs_re) {\r\n this.data_.objects = this.data_.objects || {}\r\n o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n let cname = c.name\r\n objs_re.forEach(d => {\r\n // console.log(d, cname, d.re.test(cname))\r\n if (d.re.test(cname)) {\r\n\r\n this.data_.objects[cname] = Object.assign(\r\n Object.assign({}, d),\r\n this.data_.objects[cname]\r\n )\r\n }\r\n })\r\n // }\r\n })\r\n }\r\n }\r\n\r\n let mats = this.data_.materials\r\n if (mats) {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n let mat = c.material\r\n let fmat = mats[mat.name]\r\n if (fmat) {\r\n if (!fmat.material_) {\r\n fmat.material_ = mat\r\n // process!\r\n fmat.meshes_ = [c]\r\n } else {\r\n fmat.meshes_.push(c)\r\n }\r\n }\r\n }\r\n })\r\n\r\n Object.values(mats).forEach(mat => {\r\n if (mat.material_) {\r\n\r\n let def = mat\r\n let geo = def.geo\r\n if (geo) {\r\n def.meshes_.forEach(m => {\r\n\r\n def_geo_process_(geo, m)\r\n\r\n })\r\n }\r\n\r\n process_def_material_(def, def.material_, maps, def.meshes_, this.data_)\r\n\r\n } else {\r\n console.warn('未匹配的材質', mat)\r\n }\r\n })\r\n\r\n }\r\n\r\n // #20220126 for campus\r\n let objs = this.data_.objects\r\n if (objs) {\r\n\r\n o3d.traverse(c => {\r\n let fobj = objs[c.name]\r\n // console.log(c.name, fobj)\r\n if (fobj) {\r\n fobj.o3d_ = c\r\n }\r\n })\r\n\r\n Object.values(objs).forEach(def => {\r\n if (def.o3d_) {\r\n def.o3d_.traverse(c => {\r\n if (c.isMesh) {\r\n if (this.data_.objects_isolate_material) {\r\n c.material = c.material.clone()\r\n }\r\n\r\n if (def.geo) {\r\n def_geo_process_(def.geo, c)\r\n }\r\n\r\n process_def_material_(def, c.material, maps, [c], this.data_)\r\n }\r\n })\r\n } else {\r\n console.warn('def o3d not found', def)\r\n }\r\n })\r\n\r\n\r\n }\r\n\r\n console.log('BUILDER MODEL', this.data_)\r\n\r\n onCompletion()\r\n }\r\n\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/BuilderModel.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BuilderModel\": () => (/* binding */ BuilderModel)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\nconst check_uv2_ = (meshes, depressWarning) => {\r\n if (!depressWarning) {\r\n if (meshes && meshes.length > 0) {\r\n meshes.forEach(m => {\r\n if (!m.geometry.attributes['uv2']) {\r\n console.warn('mesh', m, 'has no uv2!')\r\n }\r\n })\r\n }\r\n }\r\n}\r\n\r\n// #20220603, 通过string或者直接引用变量\r\nconst find_map__ = (maps, map) => {\r\n if (typeof map === 'string') {\r\n return maps[map]\r\n } else {\r\n return map\r\n }\r\n}\r\n\r\n// meshes for validate!\r\nconst process_def_material_ = (def, material, maps, meshes, data) => {\r\n\r\n if (def.hasOwnProperty('map')) {\r\n if (def.map == null) {\r\n material.map = null\r\n } else {\r\n // let fm = maps[def.map]\r\n let fm = find_map__(maps, def.map)\r\n if (fm) {\r\n material.map = fm.tex_\r\n } else {\r\n console.warn('map未發現(map)', def.map)\r\n }\r\n }\r\n }\r\n if (def.hasOwnProperty('lightMap')) {\r\n\r\n check_uv2_(meshes, data.depressWarning)\r\n\r\n if (def.lightMap == null) {\r\n material.lightMap = null // 不太可能發生,目前導出來看!\r\n } else {\r\n // let fm = maps[def.lightMap]\r\n let fm = find_map__(maps, def.lightMap)\r\n if (fm) {\r\n material.lightMap = fm.tex_\r\n // material.lightMapIntensity = 10 // material.envMapIntensity\r\n // material.envMapIntensity = .9\r\n } else {\r\n console.warn('map未發現(lightMap)', def.lightMap)\r\n }\r\n }\r\n }\r\n if (def.hasOwnProperty('aoMap')) {\r\n\r\n check_uv2_(meshes, data.depressWarning)\r\n\r\n if (def.aoMap == null) {\r\n material.aoMap = null // 不太可能發生,目前導出來看!\r\n } else {\r\n // let fm = maps[def.aoMap]\r\n let fm = find_map__(maps, def.aoMap)\r\n if (fm) {\r\n if (data.aoMapLinearEncoding) { // #20220603,for kiwi\r\n fm.tex_.encoding = three__WEBPACK_IMPORTED_MODULE_0__.LinearEncoding\r\n fm.tex_.needsUpdate = true\r\n }\r\n\r\n material.aoMap = fm.tex_\r\n } else {\r\n console.warn('map未發現(aoMap)', def.aoMap)\r\n }\r\n }\r\n }\r\n\r\n if (def.hasOwnProperty('lightMapIntensity')) {\r\n material.lightMapIntensity = def.lightMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('aoMapIntensity')) {\r\n material.aoMapIntensity = def.aoMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('envMapIntensity')) {\r\n material.envMapIntensity = def.envMapIntensity\r\n }\r\n\r\n if (def.hasOwnProperty('blending')) {\r\n material.blending = def.blending\r\n }\r\n\r\n if (def.hasOwnProperty('color')) {\r\n material.color = def.color\r\n }\r\n\r\n if (def.hasOwnProperty('opacity')) {\r\n material.opacity = def.opacity\r\n }\r\n\r\n // #20220404\r\n if (def.hasOwnProperty('metalness')) {\r\n material.metalness = def.metalness\r\n }\r\n\r\n if (def.hasOwnProperty('roughness')) {\r\n material.roughness = def.roughness\r\n }\r\n\r\n material.needsUpdate = true\r\n}\r\n\r\n\r\nconst def_geo_process_ = (geo, m) => {\r\n\r\n // m.geometry\r\n let uv = m.geometry.attributes['uv']\r\n let uv2 = m.geometry.attributes['uv2']\r\n\r\n if (geo.swapUv) {\r\n if (uv && uv2) {\r\n m.geometry.attributes['uv'] = uv2\r\n m.geometry.attributes['uv2'] = uv\r\n }\r\n } else if (geo.uvToUv2) {\r\n if (uv) {\r\n console.log('geo.uvToUv2')\r\n m.geometry.attributes['uv2'] = uv\r\n // m.geometry.deleteAttribute('uv')\r\n }\r\n }\r\n\r\n}\r\n\r\n// from jx-map\r\n// #20220126, for campus\r\nclass BuilderModel {\r\n\r\n constructor({ prefixAsset, data }) {\r\n this.prefixAsset_ = prefixAsset\r\n this.data_ = data\r\n // aoMapLinearEncoding\r\n this.data_.depressWarning = this.data_.depressWarning || false\r\n }\r\n\r\n process(o3d, onCompletion) {\r\n\r\n let maps = this.data_.maps\r\n if (maps) {\r\n\r\n Promise.all(\r\n Object.values(maps).map(map => {\r\n return new Promise((resolv, reject) => {\r\n new three__WEBPACK_IMPORTED_MODULE_0__.TextureLoader().load(`${this.prefixAsset_}/${map.url}`, tex => {\r\n tex.flipY = false\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_0__.sRGBEncoding\r\n // tex.encoding = LinearEncoding // aoMap 在後續修正\r\n tex.needsUpdate = true\r\n map.tex_ = tex\r\n resolv(tex)\r\n }, null, () => {\r\n reject()\r\n })\r\n })\r\n })\r\n ).then(() => {\r\n // console.log(maps)\r\n this.process_2_(o3d, onCompletion)\r\n })\r\n\r\n } else {\r\n this.process_2_(o3d, onCompletion)\r\n }\r\n }\r\n\r\n process_2_(o3d, onCompletion) {\r\n\r\n let maps = this.data_.maps\r\n\r\n {// #20220314, from vlab3-lab\r\n let mats_re = this.data_.materials_re // 未经测试!\r\n if (mats_re) {\r\n this.data_.materials = this.data_.materials || {}\r\n o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n let matname = c.material.name\r\n mats_re.forEach(d => {\r\n if (d.re.test(matname)) {\r\n this.data_.materials[matname] = Object.assign(\r\n Object.assign({}, d),\r\n this.data_.materials[matname]\r\n )\r\n }\r\n })\r\n // }\r\n })\r\n }\r\n let objs_re = this.data_.objects_re\r\n if (objs_re) {\r\n this.data_.objects = this.data_.objects || {}\r\n o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n let cname = c.name\r\n objs_re.forEach(d => {\r\n // console.log(d, cname, d.re.test(cname))\r\n if (d.re.test(cname)) {\r\n\r\n this.data_.objects[cname] = Object.assign(\r\n Object.assign({}, d),\r\n this.data_.objects[cname]\r\n )\r\n }\r\n })\r\n // }\r\n })\r\n }\r\n }\r\n\r\n let mats = this.data_.materials\r\n if (mats) {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n let mat = c.material\r\n let fmat = mats[mat.name]\r\n if (fmat) {\r\n if (!fmat.material_) {\r\n fmat.material_ = mat\r\n // process!\r\n fmat.meshes_ = [c]\r\n } else {\r\n fmat.meshes_.push(c)\r\n }\r\n }\r\n }\r\n })\r\n\r\n Object.values(mats).forEach(mat => {\r\n if (mat.material_) {\r\n\r\n let def = mat\r\n let geo = def.geo\r\n if (geo) {\r\n def.meshes_.forEach(m => {\r\n\r\n def_geo_process_(geo, m)\r\n\r\n })\r\n }\r\n\r\n process_def_material_(def, def.material_, maps, def.meshes_, this.data_)\r\n\r\n } else {\r\n console.warn('未匹配的材質', mat)\r\n }\r\n })\r\n\r\n }\r\n\r\n // #20220126 for campus\r\n let objs = this.data_.objects\r\n if (objs) {\r\n\r\n o3d.traverse(c => {\r\n let fobj = objs[c.name]\r\n // console.log(c.name, fobj)\r\n if (fobj) {\r\n fobj.o3d_ = c\r\n }\r\n })\r\n\r\n Object.values(objs).forEach(def => {\r\n if (def.o3d_) {\r\n def.o3d_.traverse(c => {\r\n if (c.isMesh) {\r\n if (this.data_.objects_isolate_material) {\r\n c.material = c.material.clone()\r\n }\r\n\r\n if (def.geo) {\r\n def_geo_process_(def.geo, c)\r\n }\r\n\r\n process_def_material_(def, c.material, maps, [c], this.data_)\r\n }\r\n })\r\n } else {\r\n console.warn('def o3d not found', def)\r\n }\r\n })\r\n\r\n\r\n }\r\n\r\n console.log('BUILDER MODEL', this.data_)\r\n\r\n onCompletion()\r\n }\r\n\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/BuilderModel.js?");
/***/ }),
@@ -322,7 +322,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Picker\": () => (/* binding */ Picker)\n/* harmony export */ });\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _SceneUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n\r\n\r\n\r\n\r\n\r\n// #20211220, sync from red-valley\r\nclass Picker extends (events__WEBPACK_IMPORTED_MODULE_0___default()) {\r\n\r\n constructor(param) {\r\n\r\n super()\r\n\r\n this.param_ = Object.assign({\r\n useHitVisible: true,\r\n useMeshGroup: false,\r\n useHitsArray: false,\r\n useMove: false,\r\n upPhasePeriodThreshold: 0.05, // #20220306, for shelves 从按下到弹起期间point移动的距离,如果小于这个数值视为点击\r\n }, param) // domElement\r\n\r\n let size = this.param_.viewer.size_\r\n let dpr = this.param_.viewer.pixelRatio_\r\n this.is_wx_ = this.param_.viewer.is_wx_\r\n this.vpos_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2()\r\n\r\n this.on_move_ = event => {\r\n // let vx = (event.clientX / size.w) * 2 - 1\r\n // let vy = -(event.clientY / size.h) * 2 + 1\r\n let vx = (event.offsetX / size.w) * 2 - 1\r\n let vy = -(event.offsetY / size.h) * 2 + 1\r\n // console.log(size, event.clientX, event.clientY)\r\n if (vx != this.vpos_.x || vy != this.vpos_.y) {\r\n this.is_move_ = true\r\n this.vpos_.set(vx, vy)\r\n }\r\n }\r\n\r\n this.hits_ = null\r\n if (this.param_.useHitsArray) {\r\n this.hits_ = {\r\n arr: []\r\n }\r\n }\r\n\r\n this.pick_obj_ = null\r\n this.latest_down_pick_obj_ = null\r\n\r\n let update_vpos_ = (x, y) => {\r\n let vx = (x / size.w) * 2 - 1\r\n let vy = -(y / size.h) * 2 + 1\r\n // console.log('update_vpos_', x, y, size.w, size.h, vx, vy)\r\n if (vx != this.vpos_.x || vy != this.vpos_.y) {\r\n this.vpos_.set(vx, vy)\r\n }\r\n }\r\n\r\n this.on_down_ = event => {\r\n event.preventDefault()\r\n // console.log(event)\r\n this.is_down_ = true\r\n\r\n // console.log(size, event.clientX, event.clientY)\r\n update_vpos_(event.offsetX, event.offsetY)\r\n this.down_vpos_ = this.vpos_.clone()\r\n }\r\n\r\n this.on_up_ = event => {\r\n event.preventDefault()\r\n\r\n update_vpos_(event.offsetX, event.offsetY)\r\n let dist = this.vpos_.distanceTo(this.down_vpos_)\r\n\r\n if (dist < this.param_.upPhasePeriodThreshold) {\r\n this.emit('downUpPick', this.latest_down_pick_obj_)\r\n } else {\r\n this.emit('downUpNone') // #20220916, shelves, just for some subscriber required!\r\n }\r\n }\r\n\r\n // console.log('##picker init', this.param_.domElement)\r\n // for wx use touchstart\r\n\r\n this.on_touchstart_ = event => {\r\n event.preventDefault() // prevent scrolling\r\n // console.log(event)\r\n this.is_down_ = true\r\n\r\n let ts = event.touches\r\n if (ts.length == 1) {\r\n update_vpos_(ts[0].clientX * dpr, ts[0].clientY * dpr)\r\n } else {\r\n update_vpos_(\r\n (ts[0].clientX * dpr + ts[1].clientX * dpr) / 2,\r\n (ts[0].clientY * dpr + ts[1].clientY * dpr) / 2\r\n )\r\n }\r\n this.down_vpos_ = this.vpos_.clone()\r\n }\r\n\r\n this.param_.domElement.addEventListener('pointermove', this.on_move_)\r\n this.param_.domElement.addEventListener('pointerdown', this.on_down_)\r\n this.param_.domElement.addEventListener('pointerup', this.on_up_)\r\n if (this.is_wx_) {\r\n this.param_.domElement.addEventListener('touchstart', this.on_touchstart_, { passive: false })\r\n }\r\n\r\n this.raycaster_ = new three__WEBPACK_IMPORTED_MODULE_2__.Raycaster()\r\n }\r\n\r\n\r\n try_match_group_(int0) {\r\n let grps = int0.object.geometry.groups\r\n if (grps && grps.length > 0) {\r\n // grp { start: Integer, count: Integer, materialIndex: Integer }\r\n // int0.faceIndex\r\n\r\n // console.log(int0, { grps })\r\n\r\n let fi = int0.faceIndex * 3\r\n\r\n let match = null\r\n // #20220114,fixed!\r\n for (let i = grps.length - 1; i >= 0; i--) {\r\n let grp = grps[i]\r\n if (fi >= grp.start) {\r\n match = grp\r\n break\r\n }\r\n }\r\n\r\n if (match) {\r\n // console.log(int0.faceIndex, match)\r\n return match\r\n }\r\n }\r\n return null\r\n }\r\n\r\n update_() {\r\n this.raycaster_.setFromCamera(this.vpos_, this.param_.viewer.camera_)\r\n let hits_arr = null\r\n if (this.hits_) {\r\n if (this.param_.useHitVisible) {\r\n hits_arr = this.hits_.arr.filter(o => o.visible)\r\n } else {\r\n hits_arr = this.hits_.arr\r\n }\r\n } else {\r\n // hits_arr = this.param_.viewer.scene_.children\r\n hits_arr = []\r\n if (this.param_.useHitVisible) {\r\n this.param_.viewer.scene_.traverse(c => {\r\n if (c.isMesh && c.visible) {\r\n hits_arr.push(c)\r\n }\r\n })\r\n } else {\r\n this.param_.viewer.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n hits_arr.push(c)\r\n }\r\n })\r\n }\r\n }\r\n // console.log(hits_arr)\r\n let intersects = this.raycaster_.intersectObjects(hits_arr, false /* true */)\r\n if (intersects.length > 0) {\r\n // console.log(intersects) \r\n // {distance: 138.32836615794753, point: Vector3, object: Mesh, uv: Vector2, \r\n // face: {a: 7803, b: 7804, c: 7805, normal: Vector3, materialIndex: 0}, faceIndex: 2601\r\n\r\n let int0 = intersects[0]\r\n this.pick_obj_ = {\r\n int0\r\n }\r\n if (this.param_.useMeshGroup) {\r\n this.pick_obj_.mg = this.try_match_group_(int0)\r\n }\r\n if (this.param_.useMove && this.is_move_) {\r\n this.emit('movePick', this.pick_obj_)\r\n }\r\n if (this.is_down_) {\r\n this.emit('downPick', this.pick_obj_)\r\n this.latest_down_pick_obj_ = this.pick_obj_\r\n }\r\n\r\n } else {\r\n this.pick_obj_ = null\r\n if (this.param_.useMove && this.is_move_) {\r\n this.emit('movePickNone')\r\n }\r\n // #20220301\r\n if (this.is_down_) {\r\n this.emit('downPick', {})\r\n this.latest_down_pick_obj_ = {}\r\n }\r\n }\r\n\r\n this.is_move_ = false\r\n this.is_down_ = false\r\n }\r\n\r\n update() {\r\n if (!this.param_.useMove) { // normal, just down\r\n if (this.is_down_) {\r\n this.update_()\r\n }\r\n } else { // move or down\r\n if (this.is_move_ || this.is_down_) {\r\n this.update_()\r\n }\r\n }\r\n }\r\n\r\n dispose() {\r\n this.emptyHits()\r\n if (this.is_wx_) {\r\n this.param_.domElement.removeEventListener('touchstart', this.on_touchstart_)\r\n }\r\n this.param_.domElement.removeEventListener('pointerup', this.on_up_)\r\n this.param_.domElement.removeEventListener('pointerdown', this.on_down_)\r\n this.param_.domElement.removeEventListener('pointermove', this.on_move_)\r\n }\r\n\r\n emptyHits() {\r\n if (this.hits_) {\r\n this.hits_.arr = []\r\n }\r\n }\r\n\r\n pushHit(obj, opts = { attachHitBox: false }) {\r\n if (this.hits_) {\r\n // #20220919, for hvac\r\n if (opts.attachHitBox) {\r\n if (!obj.hit_mesh_) {\r\n let bbx = (0,_SceneUtil__WEBPACK_IMPORTED_MODULE_1__.local_box3)(obj)\r\n // console.log('bbx', bbx)\r\n // obj.add(new Box3Helper(bbx))\r\n\r\n let m = new three__WEBPACK_IMPORTED_MODULE_2__.Mesh(new three__WEBPACK_IMPORTED_MODULE_2__.BoxGeometry(1, 1, 1), new three__WEBPACK_IMPORTED_MODULE_2__.MeshBasicMaterial({\r\n color: 0xffff00,\r\n // wireframe: true,\r\n visible: false,\r\n }))\r\n m.is_hit_mesh_ = true\r\n bbx.getSize(m.scale)\r\n bbx.getCenter(m.position)\r\n obj.add(m)\r\n\r\n obj.hit_mesh_ = m\r\n m.hit_ = obj.hit_\r\n }\r\n }\r\n // this.hits_.arr.push(obj)\r\n // #20220528, from kiwi, 例如 red-valley 中的LocO3d 具有 hit_mesh_\r\n this.hits_.arr.push(obj.hit_mesh_ || obj)\r\n }\r\n }\r\n\r\n // #20220610, for shelves\r\n spliceHit(obj) {\r\n if (this.hits_) {\r\n let fi = this.hits_.arr.indexOf(obj)\r\n if (fi >= 0) {\r\n return this.hits_.arr.splice(fi, 1)\r\n }\r\n }\r\n return null\r\n }\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/Picker.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Picker\": () => (/* binding */ Picker)\n/* harmony export */ });\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! events */ \"./node_modules/_events@3.3.0@events/events.js\");\n/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _SceneUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n\r\n\r\n\r\n\r\n\r\n// #20211220, sync from red-valley\r\nclass Picker extends (events__WEBPACK_IMPORTED_MODULE_0___default()) {\r\n\r\n constructor(param) {\r\n\r\n super()\r\n\r\n this.param_ = Object.assign({\r\n useHitVisible: true,\r\n useMeshGroup: false,\r\n useHitsArray: false,\r\n useMove: false,\r\n upPhasePeriodThreshold: 0.05, // #20220306, for shelves 从按下到弹起期间point移动的距离,如果小于这个数值视为点击\r\n }, param) // domElement\r\n\r\n let size = this.param_.viewer.size_\r\n let dpr = this.param_.viewer.pixelRatio_\r\n this.is_wx_ = this.param_.viewer.is_wx_\r\n this.vpos_ = new three__WEBPACK_IMPORTED_MODULE_2__.Vector2()\r\n\r\n this.on_move_ = event => {\r\n // let vx = (event.clientX / size.w) * 2 - 1\r\n // let vy = -(event.clientY / size.h) * 2 + 1\r\n let vx = (event.offsetX / size.w) * 2 - 1\r\n let vy = -(event.offsetY / size.h) * 2 + 1\r\n // console.log(size, event.clientX, event.clientY)\r\n if (vx != this.vpos_.x || vy != this.vpos_.y) {\r\n this.is_move_ = true\r\n this.vpos_.set(vx, vy)\r\n }\r\n }\r\n\r\n this.hits_ = null\r\n if (this.param_.useHitsArray) {\r\n this.hits_ = {\r\n arr: []\r\n }\r\n }\r\n\r\n this.pick_obj_ = null\r\n this.latest_down_pick_obj_ = null\r\n\r\n let update_vpos_ = (x, y) => {\r\n let vx = (x / size.w) * 2 - 1\r\n let vy = -(y / size.h) * 2 + 1\r\n // console.log('update_vpos_', x, y, size.w, size.h, vx, vy)\r\n if (vx != this.vpos_.x || vy != this.vpos_.y) {\r\n this.vpos_.set(vx, vy)\r\n }\r\n }\r\n\r\n this.on_down_ = event => {\r\n event.preventDefault()\r\n // console.log(event)\r\n this.is_down_ = true\r\n\r\n // console.log(size, event.clientX, event.clientY)\r\n update_vpos_(event.offsetX, event.offsetY)\r\n this.down_vpos_ = this.vpos_.clone()\r\n }\r\n\r\n this.on_up_ = event => {\r\n event.preventDefault()\r\n\r\n update_vpos_(event.offsetX, event.offsetY)\r\n let dist = this.vpos_.distanceTo(this.down_vpos_)\r\n\r\n if (dist < this.param_.upPhasePeriodThreshold) {\r\n this.emit('downUpPick', this.latest_down_pick_obj_)\r\n } else {\r\n this.emit('downUpNone') // #20220916, shelves, just for some subscriber required!\r\n }\r\n }\r\n\r\n // console.log('##picker init', this.param_.domElement)\r\n // for wx use touchstart\r\n\r\n this.on_touchstart_ = event => {\r\n event.preventDefault() // prevent scrolling\r\n // console.log(event)\r\n this.is_down_ = true\r\n\r\n let ts = event.touches\r\n if (ts.length == 1) {\r\n update_vpos_(ts[0].clientX * dpr, ts[0].clientY * dpr)\r\n } else {\r\n update_vpos_(\r\n (ts[0].clientX * dpr + ts[1].clientX * dpr) / 2,\r\n (ts[0].clientY * dpr + ts[1].clientY * dpr) / 2\r\n )\r\n }\r\n this.down_vpos_ = this.vpos_.clone()\r\n }\r\n\r\n this.param_.domElement.addEventListener('pointermove', this.on_move_)\r\n this.param_.domElement.addEventListener('pointerdown', this.on_down_)\r\n this.param_.domElement.addEventListener('pointerup', this.on_up_)\r\n if (this.is_wx_) {\r\n this.param_.domElement.addEventListener('touchstart', this.on_touchstart_, { passive: false })\r\n }\r\n\r\n this.raycaster_ = new three__WEBPACK_IMPORTED_MODULE_2__.Raycaster()\r\n }\r\n\r\n\r\n try_match_group_(int0) {\r\n let grps = int0.object.geometry.groups\r\n if (grps && grps.length > 0) {\r\n // grp { start: Integer, count: Integer, materialIndex: Integer }\r\n // int0.faceIndex\r\n\r\n // console.log(int0, { grps })\r\n\r\n let fi = int0.faceIndex * 3\r\n\r\n let match = null\r\n // #20220114,fixed!\r\n for (let i = grps.length - 1; i >= 0; i--) {\r\n let grp = grps[i]\r\n if (fi >= grp.start) {\r\n match = grp\r\n break\r\n }\r\n }\r\n\r\n if (match) {\r\n // console.log(int0.faceIndex, match)\r\n return match\r\n }\r\n }\r\n return null\r\n }\r\n\r\n update_() {\r\n this.raycaster_.setFromCamera(this.vpos_, this.param_.viewer.camera_)\r\n let hits_arr = null\r\n if (this.hits_) {\r\n if (this.param_.useHitVisible) {\r\n hits_arr = this.hits_.arr.filter(o => o.visible)\r\n } else {\r\n hits_arr = this.hits_.arr\r\n }\r\n } else {\r\n // hits_arr = this.param_.viewer.scene_.children\r\n hits_arr = []\r\n if (this.param_.useHitVisible) {\r\n this.param_.viewer.scene_.traverse(c => {\r\n if (c.isMesh && c.visible) {\r\n hits_arr.push(c)\r\n }\r\n })\r\n } else {\r\n this.param_.viewer.scene_.traverse(c => {\r\n if (c.isMesh) {\r\n hits_arr.push(c)\r\n }\r\n })\r\n }\r\n }\r\n // console.log(hits_arr)\r\n let intersects = this.raycaster_.intersectObjects(hits_arr, false /* true */)\r\n if (intersects.length > 0) {\r\n // console.log(intersects) \r\n // {distance: 138.32836615794753, point: Vector3, object: Mesh, uv: Vector2, \r\n // face: {a: 7803, b: 7804, c: 7805, normal: Vector3, materialIndex: 0}, faceIndex: 2601\r\n\r\n let int0 = intersects[0]\r\n this.pick_obj_ = {\r\n int0\r\n }\r\n if (this.param_.useMeshGroup) {\r\n this.pick_obj_.mg = this.try_match_group_(int0)\r\n }\r\n if (this.param_.useMove && this.is_move_) {\r\n this.emit('movePick', this.pick_obj_)\r\n }\r\n if (this.is_down_) {\r\n this.emit('downPick', this.pick_obj_)\r\n this.latest_down_pick_obj_ = this.pick_obj_\r\n }\r\n\r\n } else {\r\n this.pick_obj_ = null\r\n if (this.param_.useMove && this.is_move_) {\r\n this.emit('movePickNone')\r\n }\r\n // #20220301\r\n if (this.is_down_) {\r\n this.emit('downPick', {})\r\n this.latest_down_pick_obj_ = {}\r\n }\r\n }\r\n\r\n this.is_move_ = false\r\n this.is_down_ = false\r\n }\r\n\r\n update() {\r\n if (!this.param_.useMove) { // normal, just down\r\n if (this.is_down_) {\r\n this.update_()\r\n }\r\n } else { // move or down\r\n if (this.is_move_ || this.is_down_) {\r\n this.update_()\r\n }\r\n }\r\n }\r\n\r\n dispose() {\r\n this.emptyHits()\r\n if (this.is_wx_) {\r\n this.param_.domElement.removeEventListener('touchstart', this.on_touchstart_)\r\n }\r\n this.param_.domElement.removeEventListener('pointerup', this.on_up_)\r\n this.param_.domElement.removeEventListener('pointerdown', this.on_down_)\r\n this.param_.domElement.removeEventListener('pointermove', this.on_move_)\r\n }\r\n\r\n emptyHits() {\r\n if (this.hits_) {\r\n this.hits_.arr = []\r\n }\r\n }\r\n\r\n pushHit(obj, opts = { attachHitBox: false }) {\r\n if (this.hits_) {\r\n // #20220919, for hvac\r\n if (opts.attachHitBox) {\r\n if (!obj.hit_mesh_) {\r\n let bbx = (0,_SceneUtil__WEBPACK_IMPORTED_MODULE_1__.local_box3)(obj)\r\n // console.log('bbx', bbx)\r\n // obj.add(new Box3Helper(bbx))\r\n\r\n let m = new three__WEBPACK_IMPORTED_MODULE_2__.Mesh(new three__WEBPACK_IMPORTED_MODULE_2__.BoxGeometry(1, 1, 1), new three__WEBPACK_IMPORTED_MODULE_2__.MeshBasicMaterial({\r\n color: 0xffff00,\r\n // wireframe: true,\r\n visible: false,\r\n }))\r\n m.is_hit_mesh_ = true\r\n bbx.getSize(m.scale)\r\n bbx.getCenter(m.position)\r\n obj.add(m)\r\n\r\n obj.hit_mesh_ = m\r\n m.hit_ = obj.hit_\r\n }\r\n }\r\n // this.hits_.arr.push(obj)\r\n // #20220528, from kiwi, 例如 red-valley 中的LocO3d 具有 hit_mesh_\r\n this.hits_.arr.push(obj.hit_mesh_ || obj)\r\n }\r\n }\r\n\r\n // #20220610, for shelves\r\n spliceHit(obj) {\r\n if (this.hits_) {\r\n let fi = this.hits_.arr.indexOf(obj)\r\n if (fi >= 0) {\r\n return this.hits_.arr.splice(fi, 1)\r\n }\r\n }\r\n return null\r\n }\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/Picker.js?");
/***/ }),
@@ -333,7 +333,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getTuning\": () => (/* binding */ getTuning)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n\r\n\r\n\r\n\r\n\r\nclass Tuning {\r\n\r\n constructor() {\r\n this.gui_ = null\r\n }\r\n\r\n create_env_ball = apply => {\r\n let ball = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(new three__WEBPACK_IMPORTED_MODULE_1__.SphereBufferGeometry(.5, 64, 32), new three__WEBPACK_IMPORTED_MODULE_1__.MeshStandardMaterial({\r\n metalness: 1,\r\n roughness: 0,\r\n }))\r\n if (apply) {\r\n apply(ball)\r\n }\r\n return ball\r\n }\r\n \r\n create_sample_balls = apply => {\r\n const vals = [0, .125, .5, .875, 1]\r\n let grp = new three__WEBPACK_IMPORTED_MODULE_1__.Object3D()\r\n let vlen = vals.length\r\n let vlen2 = vlen / 2\r\n \r\n let geo = new three__WEBPACK_IMPORTED_MODULE_1__.SphereBufferGeometry(.1, 64, 32)\r\n \r\n for (let i = 0; i < vlen; i++) {\r\n for (let j = 0; j < vlen; j++) {\r\n let ball = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(\r\n geo,\r\n // new MeshStandardMaterial({\r\n new three__WEBPACK_IMPORTED_MODULE_1__.MeshPhysicalMaterial({\r\n roughness: vals[i],\r\n metalness: vals[j],\r\n // clearcoat: 1,\r\n })\r\n )\r\n ball.position.set(0, (j - vlen2 + .5) / 4, (i - vlen2 + .5) / 4)\r\n grp.add(ball)\r\n }\r\n }\r\n grp.add(new three__WEBPACK_IMPORTED_MODULE_1__.AxesHelper(1))\r\n if (apply) {\r\n apply(grp)\r\n }\r\n return grp\r\n }\r\n \r\n get gui() {\r\n if (!this.gui_) {\r\n if (_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI) {\r\n this.gui_ = new _BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI()\r\n }\r\n }\r\n return this.gui_\r\n }\r\n\r\n}\r\n\r\nconst ref = {\r\n tuning_: null\r\n}\r\n\r\nconst getTuning = ()=>{\r\n if (!ref.tuning_) {\r\n ref.tuning_ = new Tuning()\r\n }\r\n return ref.tuning_\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getTuning\": () => (/* binding */ getTuning)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n\r\n\r\n\r\n\r\n\r\nclass Tuning {\r\n\r\n constructor() {\r\n this.gui_ = null\r\n }\r\n\r\n create_env_ball = apply => {\r\n let ball = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(new three__WEBPACK_IMPORTED_MODULE_1__.SphereBufferGeometry(.5, 64, 32), new three__WEBPACK_IMPORTED_MODULE_1__.MeshStandardMaterial({\r\n metalness: 1,\r\n roughness: 0,\r\n }))\r\n if (apply) {\r\n apply(ball)\r\n }\r\n return ball\r\n }\r\n \r\n create_sample_balls = apply => {\r\n const vals = [0, .125, .5, .875, 1]\r\n let grp = new three__WEBPACK_IMPORTED_MODULE_1__.Object3D()\r\n let vlen = vals.length\r\n let vlen2 = vlen / 2\r\n \r\n let geo = new three__WEBPACK_IMPORTED_MODULE_1__.SphereBufferGeometry(.1, 64, 32)\r\n \r\n for (let i = 0; i < vlen; i++) {\r\n for (let j = 0; j < vlen; j++) {\r\n let ball = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(\r\n geo,\r\n // new MeshStandardMaterial({\r\n new three__WEBPACK_IMPORTED_MODULE_1__.MeshPhysicalMaterial({\r\n roughness: vals[i],\r\n metalness: vals[j],\r\n // clearcoat: 1,\r\n })\r\n )\r\n ball.position.set(0, (j - vlen2 + .5) / 4, (i - vlen2 + .5) / 4)\r\n grp.add(ball)\r\n }\r\n }\r\n grp.add(new three__WEBPACK_IMPORTED_MODULE_1__.AxesHelper(1))\r\n if (apply) {\r\n apply(grp)\r\n }\r\n return grp\r\n }\r\n \r\n get gui() {\r\n if (!this.gui_) {\r\n if (_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI) {\r\n this.gui_ = new _BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI()\r\n }\r\n }\r\n return this.gui_\r\n }\r\n\r\n}\r\n\r\nconst ref = {\r\n tuning_: null\r\n}\r\n\r\nconst getTuning = ()=>{\r\n if (!ref.tuning_) {\r\n ref.tuning_ = new Tuning()\r\n }\r\n return ref.tuning_\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js?");
/***/ }),
@@ -344,7 +344,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MERGE_RE_CENTER\": () => (/* binding */ MERGE_RE_CENTER),\n/* harmony export */ \"MERGE_TO_ROOT\": () => (/* binding */ MERGE_TO_ROOT),\n/* harmony export */ \"dump_o3d\": () => (/* binding */ dump_o3d),\n/* harmony export */ \"local_box3\": () => (/* binding */ local_box3),\n/* harmony export */ \"merge_o3d_array\": () => (/* binding */ merge_o3d_array),\n/* harmony export */ \"to_material_group\": () => (/* binding */ to_material_group),\n/* harmony export */ \"traverse_deep\": () => (/* binding */ traverse_deep),\n/* harmony export */ \"traverse_mtx\": () => (/* binding */ traverse_mtx)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_utils_BufferGeometryUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/utils/BufferGeometryUtils */ \"./node_modules/_three@0.139.2@three/examples/jsm/utils/BufferGeometryUtils.js\");\n\r\n\r\n\r\n// from pamir base/yo-util, red-valley\r\nconst traverse_deep = (o3d, callback, deep = 0) => {\r\n callback(o3d, deep)\r\n let d2 = deep + 1\r\n o3d.children.forEach(c => {\r\n traverse_deep(c, callback, d2)\r\n })\r\n}\r\n\r\nconst dump_o3d = (o3d) => {\r\n traverse_deep(o3d, (c, deep) => {\r\n let extra = ''\r\n if (c.isMesh) {\r\n extra += c.material.name + ','\r\n if (c.geometry.attributes['uv']) {\r\n extra += 'uv,'\r\n }\r\n if (c.geometry.attributes['uv2']) {\r\n extra += 'uv2,'\r\n }\r\n }\r\n console.log(`${'-'.repeat(deep * 2)}${c.name}`, { c }, extra)\r\n })\r\n}\r\n\r\nconst MERGE_TO_ROOT = 1\r\nconst MERGE_RE_CENTER = 2\r\n\r\n// for smart-farm\r\n// base on root matrix\r\n// current support meshes\r\nconst merge_o3d_array = (o3ds, mode = MERGE_RE_CENTER) => {\r\n\r\n if (o3ds.length > 0) {\r\n let mat = o3ds[0].material\r\n let geos = []\r\n o3ds.forEach(o3d => {\r\n o3d.updateMatrixWorld(true)\r\n geos.push(o3d.geometry.applyMatrix4(o3d.matrixWorld))\r\n })\r\n let geo = (0,three_examples_jsm_utils_BufferGeometryUtils__WEBPACK_IMPORTED_MODULE_0__.mergeBufferGeometries)(geos)\r\n let m = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(geo, mat)\r\n if (mode == MERGE_RE_CENTER) {\r\n geo.computeBoundingBox()\r\n let cnt = geo.boundingBox.getCenter(new three__WEBPACK_IMPORTED_MODULE_1__.Vector3())\r\n m.position.copy(cnt)\r\n geo.center()\r\n }\r\n return m\r\n }\r\n\r\n return null\r\n}\r\n\r\n// from smart-farm\r\n// 按照材质分组,便于执行 merge_o3d_array\r\nconst to_material_group = o3d => {\r\n let mg = {}\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n let mat = c.material\r\n let fm = mg[mat.uuid]\r\n if (!fm) {\r\n fm = { mat, o3ds: [] }\r\n mg[mat.uuid] = fm\r\n }\r\n fm.o3ds.push(c)\r\n }\r\n })\r\n return mg\r\n}\r\n\r\n\r\n\r\n// from altai-gis / Object3DUtil\r\nconst traverse_mtx__ = (n, mtx, callback) => {\r\n callback(n, mtx)\r\n n.children.forEach(c => {\r\n c.updateMatrix()\r\n traverse_mtx__(c, new three__WEBPACK_IMPORTED_MODULE_1__.Matrix4().multiplyMatrices(mtx, c.matrix), callback)\r\n })\r\n}\r\n\r\nconst traverse_mtx = (o3d, callback) => {\r\n traverse_mtx__(o3d, new three__WEBPACK_IMPORTED_MODULE_1__.Matrix4(), callback)\r\n}\r\n\r\n// #20220620, for shelves\r\nconst local_box3 = o3d => {\r\n\r\n let bbx1 = null\r\n traverse_mtx(o3d, (c, mtx) => {\r\n if (c.isMesh) {\r\n c.geometry.computeBoundingBox()\r\n let bbx = c.geometry.boundingBox.clone().applyMatrix4(mtx)\r\n if (!bbx1) {\r\n bbx1 = bbx\r\n } else {\r\n bbx1.union(bbx)\r\n }\r\n }\r\n })\r\n return bbx1\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/SceneUtil.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MERGE_RE_CENTER\": () => (/* binding */ MERGE_RE_CENTER),\n/* harmony export */ \"MERGE_TO_ROOT\": () => (/* binding */ MERGE_TO_ROOT),\n/* harmony export */ \"dump_o3d\": () => (/* binding */ dump_o3d),\n/* harmony export */ \"local_box3\": () => (/* binding */ local_box3),\n/* harmony export */ \"merge_o3d_array\": () => (/* binding */ merge_o3d_array),\n/* harmony export */ \"to_material_group\": () => (/* binding */ to_material_group),\n/* harmony export */ \"traverse_deep\": () => (/* binding */ traverse_deep),\n/* harmony export */ \"traverse_mtx\": () => (/* binding */ traverse_mtx)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_utils_BufferGeometryUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/utils/BufferGeometryUtils */ \"./node_modules/_three@0.146.0@three/examples/jsm/utils/BufferGeometryUtils.js\");\n\r\n\r\n\r\n// from pamir base/yo-util, red-valley\r\nconst traverse_deep = (o3d, callback, deep = 0) => {\r\n callback(o3d, deep)\r\n let d2 = deep + 1\r\n o3d.children.forEach(c => {\r\n traverse_deep(c, callback, d2)\r\n })\r\n}\r\n\r\nconst dump_o3d = (o3d) => {\r\n traverse_deep(o3d, (c, deep) => {\r\n let extra = ''\r\n if (c.isMesh) {\r\n extra += c.material.name + ','\r\n if (c.geometry.attributes['uv']) {\r\n extra += 'uv,'\r\n }\r\n if (c.geometry.attributes['uv2']) {\r\n extra += 'uv2,'\r\n }\r\n }\r\n console.log(`${'-'.repeat(deep * 2)}${c.name}`, { c }, extra)\r\n })\r\n}\r\n\r\nconst MERGE_TO_ROOT = 1\r\nconst MERGE_RE_CENTER = 2\r\n\r\n// for smart-farm\r\n// base on root matrix\r\n// current support meshes\r\nconst merge_o3d_array = (o3ds, mode = MERGE_RE_CENTER) => {\r\n\r\n if (o3ds.length > 0) {\r\n let mat = o3ds[0].material\r\n let geos = []\r\n o3ds.forEach(o3d => {\r\n o3d.updateMatrixWorld(true)\r\n geos.push(o3d.geometry.applyMatrix4(o3d.matrixWorld))\r\n })\r\n let geo = (0,three_examples_jsm_utils_BufferGeometryUtils__WEBPACK_IMPORTED_MODULE_0__.mergeBufferGeometries)(geos)\r\n let m = new three__WEBPACK_IMPORTED_MODULE_1__.Mesh(geo, mat)\r\n if (mode == MERGE_RE_CENTER) {\r\n geo.computeBoundingBox()\r\n let cnt = geo.boundingBox.getCenter(new three__WEBPACK_IMPORTED_MODULE_1__.Vector3())\r\n m.position.copy(cnt)\r\n geo.center()\r\n }\r\n return m\r\n }\r\n\r\n return null\r\n}\r\n\r\n// from smart-farm\r\n// 按照材质分组,便于执行 merge_o3d_array\r\nconst to_material_group = o3d => {\r\n let mg = {}\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n let mat = c.material\r\n let fm = mg[mat.uuid]\r\n if (!fm) {\r\n fm = { mat, o3ds: [] }\r\n mg[mat.uuid] = fm\r\n }\r\n fm.o3ds.push(c)\r\n }\r\n })\r\n return mg\r\n}\r\n\r\n\r\n\r\n// from altai-gis / Object3DUtil\r\nconst traverse_mtx__ = (n, mtx, callback) => {\r\n callback(n, mtx)\r\n n.children.forEach(c => {\r\n c.updateMatrix()\r\n traverse_mtx__(c, new three__WEBPACK_IMPORTED_MODULE_1__.Matrix4().multiplyMatrices(mtx, c.matrix), callback)\r\n })\r\n}\r\n\r\nconst traverse_mtx = (o3d, callback) => {\r\n traverse_mtx__(o3d, new three__WEBPACK_IMPORTED_MODULE_1__.Matrix4(), callback)\r\n}\r\n\r\n// #20220620, for shelves\r\nconst local_box3 = o3d => {\r\n\r\n let bbx1 = null\r\n traverse_mtx(o3d, (c, mtx) => {\r\n if (c.isMesh) {\r\n c.geometry.computeBoundingBox()\r\n let bbx = c.geometry.boundingBox.clone().applyMatrix4(mtx)\r\n if (!bbx1) {\r\n bbx1 = bbx\r\n } else {\r\n bbx1.union(bbx)\r\n }\r\n }\r\n })\r\n return bbx1\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/SceneUtil.js?");
/***/ }),
@@ -355,7 +355,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ControlsDistance\": () => (/* binding */ ControlsDistance)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\n\r\nclass ControlsDistance {\r\n\r\n constructor(v) { // viewer\r\n this.v_ = v\r\n this.value_ = 0\r\n this.valid_ = false\r\n }\r\n\r\n invalid() {\r\n this.valid_ = false\r\n }\r\n\r\n get value() {\r\n if (!this.valid_) {\r\n this.value_ = new three__WEBPACK_IMPORTED_MODULE_0__.Vector3().subVectors(\r\n this.v_.controls_.object.position,\r\n this.v_.controls_.target\r\n ).length()\r\n this.valid_ = true\r\n }\r\n return this.value_\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/frame/caches.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ControlsDistance\": () => (/* binding */ ControlsDistance)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\n\r\nclass ControlsDistance {\r\n\r\n constructor(v) { // viewer\r\n this.v_ = v\r\n this.value_ = 0\r\n this.valid_ = false\r\n }\r\n\r\n invalid() {\r\n this.valid_ = false\r\n }\r\n\r\n get value() {\r\n if (!this.valid_) {\r\n this.value_ = new three__WEBPACK_IMPORTED_MODULE_0__.Vector3().subVectors(\r\n this.v_.controls_.object.position,\r\n this.v_.controls_.target\r\n ).length()\r\n this.valid_ = true\r\n }\r\n return this.value_\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src-kutsi/crossyo/kutsi/util/frame/caches.js?");
/***/ }),
@@ -366,7 +366,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseShelve\": () => (/* binding */ BaseShelve),\n/* harmony export */ \"CELL_HIERARCHY\": () => (/* binding */ CELL_HIERARCHY),\n/* harmony export */ \"HIERARCHY_TYPE\": () => (/* binding */ HIERARCHY_TYPE),\n/* harmony export */ \"parse_v3_cells_from_v1_shelf_model_\": () => (/* binding */ parse_v3_cells_from_v1_shelf_model_)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _common_CommoditiesCache__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../common/CommoditiesCache */ \"./src/crossyo/shelves/common/CommoditiesCache.js\");\n/* harmony import */ var _common_TexturesCache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/TexturesCache */ \"./src/crossyo/shelves/common/TexturesCache.js\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst HIERARCHY_TYPE = {\r\n STANDALONE: 1,\r\n INHERITED: 2,\r\n}\r\n\r\nconst CELL_HIERARCHY = HIERARCHY_TYPE.INHERITED\r\n\r\nclass BaseShelve {\r\n\r\n constructor(viewer) {\r\n\r\n this.viewer_ = viewer\r\n this.commodities_cache_ = new _common_CommoditiesCache__WEBPACK_IMPORTED_MODULE_0__.CommoditiesCache(viewer)\r\n this.textures_cache_ = new _common_TexturesCache__WEBPACK_IMPORTED_MODULE_1__.TexturesCache(viewer)\r\n }\r\n\r\n get_texture_url_(texture) {\r\n if (texture) {\r\n return _common_util__WEBPACK_IMPORTED_MODULE_2__.isMobile ? texture.urlSmall : texture.url\r\n } else {\r\n return null\r\n }\r\n }\r\n\r\n removeWareFromCell(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n let c_o3d__ = ext.get_c_o3d__ ? ext.get_c_o3d__() : null\r\n if (c_o3d__) {\r\n\r\n if (!ext.origin_o3d_url__\r\n && !ext.origin_tex_url__\r\n ) {\r\n console.log('SAME!!')\r\n return\r\n } else {\r\n console.log('REMOVE PREV!!' /*, commodity.url*/, ext.origin_o3d_url__)\r\n // remove previous!\r\n // ext.$c_o3d__.removeFromParent()\r\n // ext.$c_o3d__ = null\r\n\r\n c_o3d__.removeFromParent()\r\n\r\n ext.origin_o3d_url__ = null\r\n ext.$origin_o3d__ = null\r\n ext.origin_tex_url__ = null\r\n ext.$origin_tex__ = null\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n addWareToCell(ware, cell) {\r\n\r\n return new Promise((resolve, reject) => {\r\n\r\n let commodity = ware.commodity\r\n let texture = ware.texture // maybe null!\r\n \r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n let c_o3d__ = ext.get_c_o3d__ ? ext.get_c_o3d__() : null\r\n if (c_o3d__) {\r\n\r\n if (commodity.url == ext.origin_o3d_url__\r\n && this.get_texture_url_(texture) == ext.origin_tex_url__\r\n ) {\r\n console.log('SAME!!')\r\n return\r\n } else {\r\n console.log('REMOVE PREV!!', commodity.url, ext.origin_o3d_url__)\r\n // remove previous!\r\n // ext.$c_o3d__.removeFromParent()\r\n // ext.$c_o3d__ = null\r\n\r\n c_o3d__.removeFromParent()\r\n\r\n ext.origin_o3d_url__ = null\r\n ext.$origin_o3d__ = null\r\n ext.origin_tex_url__ = null\r\n ext.$origin_tex__ = null\r\n }\r\n\r\n }\r\n\r\n this.commodities_cache_.find(commodity).then(o3d_nt => {\r\n this.textures_cache_.find(texture).then(tex => {\r\n\r\n ext.$origin_tex__ = tex\r\n ext.origin_tex_url__ = this.get_texture_url_(texture)\r\n\r\n let o3d = o3d_nt.clone()\r\n\r\n o3d.name = o3d_nt.name + '-mat'\r\n if (o3d.material) {\r\n o3d.material = o3d.material.clone()\r\n if (tex) {\r\n o3d.material.map = tex\r\n }\r\n } else { // #20220729, mesh in children\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n c.material = c.material.clone() // case 自己上传的独特商品\r\n if (tex) {\r\n console.warn('#20220729, un confirmed path, 291G9J81LO1!')\r\n c.material.map = tex\r\n }\r\n }\r\n })\r\n }\r\n\r\n // ext.$origin_o3d__ = o3d\r\n ext.get_origin_o3d__ = () => {\r\n return o3d\r\n }\r\n ext.origin_o3d_url__ = commodity.url\r\n // container!\r\n let c_o3d = new three__WEBPACK_IMPORTED_MODULE_3__.Object3D()\r\n c_o3d.name = 'cell__'\r\n // ext.$c_o3d__ = c_o3d\r\n ext.get_c_o3d__ = () => {\r\n return c_o3d\r\n }\r\n\r\n let box = cell.box\r\n c_o3d.position.set(box.position.x, box.position.y, box.position.z)\r\n c_o3d.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n this.viewer_.mesh_shelf__.add(c_o3d)\r\n\r\n // console.log(this.viewer_.mesh_shelf__)\r\n\r\n this.update_cell_pileNumber_(cell)\r\n\r\n resolve()\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n\r\n })\r\n\r\n\r\n }\r\n\r\n // with pile rotation y\r\n update_cell_pileNumber_(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n if (ext.get_c_o3d__) {\r\n\r\n let c_o3d__ = ext.get_c_o3d__()\r\n if (c_o3d__) {\r\n\r\n let old_number = c_o3d__.children.length\r\n let new_number = cell.pileNumber\r\n\r\n // console.log('update_pile_number', old_number, new_number)\r\n\r\n if (old_number != new_number) {\r\n c_o3d__.clear()\r\n\r\n let exto = ext.get_origin_o3d__()\r\n\r\n let size = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.box3_except_shadow)(exto).getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let sw = size.x\r\n\r\n if (cell.pileNumber == 6) { // temp for v3.5\r\n\r\n let w = sw * (3 - 1)\r\n for (let i = 0; i < new_number; i++) {\r\n\r\n let co = exto.clone()\r\n co.name = exto.name + '-' + i\r\n\r\n if (i < 3) {\r\n co.position.x = i * sw - w / 2\r\n co.position.z = sw / 2\r\n } else {\r\n co.position.x = (i - 3) * sw - w / 2\r\n co.position.z = - sw / 2\r\n }\r\n c_o3d__.add(co)\r\n co.rotation.y = cell.pileRotationY * Math.PI / 180\r\n\r\n\r\n // console.log('#2', exto, co)\r\n\r\n }\r\n\r\n } else {\r\n\r\n let w = sw * (new_number - 1)\r\n for (let i = 0; i < new_number; i++) {\r\n\r\n let co = exto.clone()\r\n co.name = exto.name + '-' + i\r\n\r\n co.position.x = i * sw - w / 2\r\n c_o3d__.add(co)\r\n co.rotation.y = cell.pileRotationY * Math.PI / 180\r\n\r\n // console.log('#2', exto, co)\r\n\r\n }\r\n }\r\n\r\n }\r\n\r\n\r\n } else {\r\n console.warn('sk324kFdfkP34k;ls3k!')\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n update_cell_pileRotationY_(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n\r\n if (ext.get_c_o3d__) {\r\n\r\n let c_o3d__ = ext.get_c_o3d__()\r\n if (c_o3d__) {\r\n\r\n // console.log('update_pileRotationY', ext.$c_o3d__, cell.pileRotationY)\r\n c_o3d__.children.forEach(c => {\r\n c.rotation.y = cell.pileRotationY * Math.PI / 180\r\n })\r\n\r\n } else {\r\n console.warn('UIH4329HJPmk023lKQb!')\r\n }\r\n\r\n }\r\n\r\n\r\n }\r\n\r\n\r\n dispose() {\r\n this.commodities_cache_.dispose()\r\n this.textures_cache_.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n// TEMP for v1 to v3, 解些老的数据,并且生成新的cells数据,copy to store/shelves 列表中\r\nconst parse_v3_cells_from_v1_shelf_model_ = o3d => {\r\n\r\n console.log('## parse_v3_cells_from_v1_shelf_model_')\r\n\r\n let boxes = []\r\n let signs = []\r\n o3d.traverse(c => {\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n // console.log(c)\r\n boxes.push(c)\r\n } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n // console.log(c)\r\n signs.push(c)\r\n }\r\n })\r\n if (boxes.length != signs.length) {\r\n console.warn('boxes len != signs len')\r\n return\r\n }\r\n boxes.sort((a, b) => {\r\n return a.name.localeCompare(b.name)\r\n })\r\n signs.sort((a, b) => {\r\n return a.name.localeCompare(b.name)\r\n })\r\n\r\n // console.log(boxes, signs)\r\n\r\n let to_box_scale_ = (t, box) => {\r\n // console.log('box', box, box.geometry.boundingBox, box.geometry.boundingBox.getSize(new Vector3()))\r\n t.size = box.geometry.boundingBox.getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n // console.log(t)\r\n return t\r\n }\r\n\r\n let cells = []\r\n for (let i = 0; i < boxes.length; i++) {\r\n let box = boxes[i]\r\n let sign = signs[i]\r\n\r\n // let bbx1 = box.geometry.boundingBox\r\n // bbx1.applyMatrix4(box.matrix)\r\n\r\n let cell = {\r\n name: box.name.substr(4),\r\n // 底面中心\r\n box: to_box_scale_((0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(box), box),\r\n }\r\n\r\n if (CELL_HIERARCHY == HIERARCHY_TYPE.STANDALONE) {\r\n // 中心\r\n cell.sign = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(sign)\r\n cell.sign.position.z += .01\r\n cell.logo = { // #20220611\r\n position: {\r\n x: box.position.x,\r\n y: box.position.y + .15,\r\n z: box.position.z\r\n }\r\n }\r\n } else if (CELL_HIERARCHY == HIERARCHY_TYPE.INHERITED) {\r\n\r\n let t_sign = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(sign)\r\n t_sign.position.x -= cell.box.position.x\r\n t_sign.position.y -= cell.box.position.y\r\n t_sign.position.z -= cell.box.position.z\r\n t_sign.position.z += .01\r\n\r\n t_sign.rotation.x = t_sign.rotation.y = t_sign.rotation.z = 0\r\n\r\n cell.box.child = {\r\n sign: t_sign,\r\n logo: { // #20220611\r\n position: {\r\n x: box.position.x - cell.box.position.x,\r\n y: box.position.y + .15 - cell.box.position.y,\r\n z: box.position.z - cell.box.position.z,\r\n },\r\n },\r\n }\r\n\r\n }\r\n\r\n cells.push(cell)\r\n }\r\n\r\n // KLUDGE 记录数据\r\n // console.log('copy to ../shelves-vue-demo/store/shelf?_cells.json')\r\n console.log('cells', JSON.stringify(cells))\r\n\r\n return cells\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/BaseShelve.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseShelve\": () => (/* binding */ BaseShelve),\n/* harmony export */ \"CELL_HIERARCHY\": () => (/* binding */ CELL_HIERARCHY),\n/* harmony export */ \"HIERARCHY_TYPE\": () => (/* binding */ HIERARCHY_TYPE),\n/* harmony export */ \"parse_v3_cells_from_v1_shelf_model_\": () => (/* binding */ parse_v3_cells_from_v1_shelf_model_)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _common_CommoditiesCache__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../common/CommoditiesCache */ \"./src/crossyo/shelves/common/CommoditiesCache.js\");\n/* harmony import */ var _common_TexturesCache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/TexturesCache */ \"./src/crossyo/shelves/common/TexturesCache.js\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst HIERARCHY_TYPE = {\r\n STANDALONE: 1,\r\n INHERITED: 2,\r\n}\r\n\r\nconst CELL_HIERARCHY = HIERARCHY_TYPE.INHERITED\r\n\r\nclass BaseShelve {\r\n\r\n constructor(viewer) {\r\n\r\n this.viewer_ = viewer\r\n this.commodities_cache_ = new _common_CommoditiesCache__WEBPACK_IMPORTED_MODULE_0__.CommoditiesCache(viewer)\r\n this.textures_cache_ = new _common_TexturesCache__WEBPACK_IMPORTED_MODULE_1__.TexturesCache(viewer)\r\n }\r\n\r\n get_texture_url_(texture) {\r\n if (texture) {\r\n return _common_util__WEBPACK_IMPORTED_MODULE_2__.isMobile ? texture.urlSmall : texture.url\r\n } else {\r\n return null\r\n }\r\n }\r\n\r\n removeWareFromCell(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n let c_o3d__ = ext.get_c_o3d__ ? ext.get_c_o3d__() : null\r\n if (c_o3d__) {\r\n\r\n if (!ext.origin_o3d_url__\r\n && !ext.origin_tex_url__\r\n ) {\r\n console.log('SAME!!')\r\n return\r\n } else {\r\n console.log('REMOVE PREV!!' /*, commodity.url*/, ext.origin_o3d_url__)\r\n // remove previous!\r\n // ext.$c_o3d__.removeFromParent()\r\n // ext.$c_o3d__ = null\r\n\r\n c_o3d__.removeFromParent()\r\n\r\n ext.origin_o3d_url__ = null\r\n ext.$origin_o3d__ = null\r\n ext.origin_tex_url__ = null\r\n ext.$origin_tex__ = null\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n addWareToCell(ware, cell) {\r\n\r\n return new Promise((resolve, reject) => {\r\n\r\n let commodity = ware.commodity\r\n let texture = ware.texture // maybe null!\r\n \r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n let c_o3d__ = ext.get_c_o3d__ ? ext.get_c_o3d__() : null\r\n if (c_o3d__) {\r\n\r\n if (commodity.url == ext.origin_o3d_url__\r\n && this.get_texture_url_(texture) == ext.origin_tex_url__\r\n ) {\r\n console.log('SAME!!')\r\n return\r\n } else {\r\n console.log('REMOVE PREV!!', commodity.url, ext.origin_o3d_url__)\r\n // remove previous!\r\n // ext.$c_o3d__.removeFromParent()\r\n // ext.$c_o3d__ = null\r\n\r\n c_o3d__.removeFromParent()\r\n\r\n ext.origin_o3d_url__ = null\r\n ext.$origin_o3d__ = null\r\n ext.origin_tex_url__ = null\r\n ext.$origin_tex__ = null\r\n }\r\n\r\n }\r\n\r\n this.commodities_cache_.find(commodity).then(o3d_nt => {\r\n this.textures_cache_.find(texture).then(tex => {\r\n\r\n ext.$origin_tex__ = tex\r\n ext.origin_tex_url__ = this.get_texture_url_(texture)\r\n\r\n let o3d = o3d_nt.clone()\r\n\r\n o3d.name = o3d_nt.name + '-mat'\r\n if (o3d.material) {\r\n o3d.material = o3d.material.clone()\r\n if (tex) {\r\n o3d.material.map = tex\r\n }\r\n } else { // #20220729, mesh in children\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n c.material = c.material.clone() // case 自己上传的独特商品\r\n if (tex) {\r\n console.warn('#20220729, un confirmed path, 291G9J81LO1!')\r\n c.material.map = tex\r\n }\r\n }\r\n })\r\n }\r\n\r\n // ext.$origin_o3d__ = o3d\r\n ext.get_origin_o3d__ = () => {\r\n return o3d\r\n }\r\n ext.origin_o3d_url__ = commodity.url\r\n // container!\r\n let c_o3d = new three__WEBPACK_IMPORTED_MODULE_3__.Object3D()\r\n c_o3d.name = 'cell__'\r\n // ext.$c_o3d__ = c_o3d\r\n ext.get_c_o3d__ = () => {\r\n return c_o3d\r\n }\r\n\r\n let box = cell.box\r\n c_o3d.position.set(box.position.x, box.position.y, box.position.z)\r\n c_o3d.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n this.viewer_.mesh_shelf__.add(c_o3d)\r\n\r\n // console.log(this.viewer_.mesh_shelf__)\r\n\r\n this.update_cell_pileNumber_(cell)\r\n\r\n resolve()\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n\r\n })\r\n\r\n\r\n }\r\n\r\n // with pile rotation y\r\n update_cell_pileNumber_(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n if (ext.get_c_o3d__) {\r\n\r\n let c_o3d__ = ext.get_c_o3d__()\r\n if (c_o3d__) {\r\n\r\n let old_number = c_o3d__.children.length\r\n let new_number = cell.pileNumber\r\n\r\n // console.log('update_pile_number', old_number, new_number)\r\n\r\n if (old_number != new_number) {\r\n c_o3d__.clear()\r\n\r\n let exto = ext.get_origin_o3d__()\r\n\r\n let size = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.box3_except_shadow)(exto).getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let sw = size.x\r\n\r\n if (cell.pileNumber == 6) { // temp for v3.5\r\n\r\n let w = sw * (3 - 1)\r\n for (let i = 0; i < new_number; i++) {\r\n\r\n let co = exto.clone()\r\n co.name = exto.name + '-' + i\r\n\r\n if (i < 3) {\r\n co.position.x = i * sw - w / 2\r\n co.position.z = sw / 2\r\n } else {\r\n co.position.x = (i - 3) * sw - w / 2\r\n co.position.z = - sw / 2\r\n }\r\n c_o3d__.add(co)\r\n co.rotation.y = cell.pileRotationY * Math.PI / 180\r\n\r\n\r\n // console.log('#2', exto, co)\r\n\r\n }\r\n\r\n } else {\r\n\r\n let w = sw * (new_number - 1)\r\n for (let i = 0; i < new_number; i++) {\r\n\r\n let co = exto.clone()\r\n co.name = exto.name + '-' + i\r\n\r\n co.position.x = i * sw - w / 2\r\n c_o3d__.add(co)\r\n co.rotation.y = cell.pileRotationY * Math.PI / 180\r\n\r\n // console.log('#2', exto, co)\r\n\r\n }\r\n }\r\n\r\n }\r\n\r\n\r\n } else {\r\n console.warn('sk324kFdfkP34k;ls3k!')\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n update_cell_pileRotationY_(cell) {\r\n\r\n let ext = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.use_ext)(cell)\r\n\r\n if (ext.get_c_o3d__) {\r\n\r\n let c_o3d__ = ext.get_c_o3d__()\r\n if (c_o3d__) {\r\n\r\n // console.log('update_pileRotationY', ext.$c_o3d__, cell.pileRotationY)\r\n c_o3d__.children.forEach(c => {\r\n c.rotation.y = cell.pileRotationY * Math.PI / 180\r\n })\r\n\r\n } else {\r\n console.warn('UIH4329HJPmk023lKQb!')\r\n }\r\n\r\n }\r\n\r\n\r\n }\r\n\r\n\r\n dispose() {\r\n this.commodities_cache_.dispose()\r\n this.textures_cache_.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n// TEMP for v1 to v3, 解些老的数据,并且生成新的cells数据,copy to store/shelves 列表中\r\nconst parse_v3_cells_from_v1_shelf_model_ = o3d => {\r\n\r\n console.log('## parse_v3_cells_from_v1_shelf_model_')\r\n\r\n let boxes = []\r\n let signs = []\r\n o3d.traverse(c => {\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n // console.log(c)\r\n boxes.push(c)\r\n } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n // console.log(c)\r\n signs.push(c)\r\n }\r\n })\r\n if (boxes.length != signs.length) {\r\n console.warn('boxes len != signs len')\r\n return\r\n }\r\n boxes.sort((a, b) => {\r\n return a.name.localeCompare(b.name)\r\n })\r\n signs.sort((a, b) => {\r\n return a.name.localeCompare(b.name)\r\n })\r\n\r\n // console.log(boxes, signs)\r\n\r\n let to_box_scale_ = (t, box) => {\r\n // console.log('box', box, box.geometry.boundingBox, box.geometry.boundingBox.getSize(new Vector3()))\r\n t.size = box.geometry.boundingBox.getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n // console.log(t)\r\n return t\r\n }\r\n\r\n let cells = []\r\n for (let i = 0; i < boxes.length; i++) {\r\n let box = boxes[i]\r\n let sign = signs[i]\r\n\r\n // let bbx1 = box.geometry.boundingBox\r\n // bbx1.applyMatrix4(box.matrix)\r\n\r\n let cell = {\r\n name: box.name.substr(4),\r\n // 底面中心\r\n box: to_box_scale_((0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(box), box),\r\n }\r\n\r\n if (CELL_HIERARCHY == HIERARCHY_TYPE.STANDALONE) {\r\n // 中心\r\n cell.sign = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(sign)\r\n cell.sign.position.z += .01\r\n cell.logo = { // #20220611\r\n position: {\r\n x: box.position.x,\r\n y: box.position.y + .15,\r\n z: box.position.z\r\n }\r\n }\r\n } else if (CELL_HIERARCHY == HIERARCHY_TYPE.INHERITED) {\r\n\r\n let t_sign = (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.to_transform)(sign)\r\n t_sign.position.x -= cell.box.position.x\r\n t_sign.position.y -= cell.box.position.y\r\n t_sign.position.z -= cell.box.position.z\r\n t_sign.position.z += .01\r\n\r\n t_sign.rotation.x = t_sign.rotation.y = t_sign.rotation.z = 0\r\n\r\n cell.box.child = {\r\n sign: t_sign,\r\n logo: { // #20220611\r\n position: {\r\n x: box.position.x - cell.box.position.x,\r\n y: box.position.y + .15 - cell.box.position.y,\r\n z: box.position.z - cell.box.position.z,\r\n },\r\n },\r\n }\r\n\r\n }\r\n\r\n cells.push(cell)\r\n }\r\n\r\n // KLUDGE 记录数据\r\n // console.log('copy to ../shelves-vue-demo/store/shelf?_cells.json')\r\n console.log('cells', JSON.stringify(cells))\r\n\r\n return cells\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/BaseShelve.js?");
/***/ }),
@@ -377,7 +377,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CommoditiesCache\": () => (/* binding */ CommoditiesCache)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\nclass CommoditiesCache {\r\n\r\n constructor(view) {\r\n this.view_ = view\r\n this.cache_ = {} // url -> {o3d}\r\n }\r\n\r\n find(commodity) {\r\n return new Promise((resolve, reject) => {\r\n\r\n let c_url = commodity.url\r\n let f = this.cache_[c_url]\r\n if (f) {\r\n if (f.o3d != null) {\r\n resolve(f.o3d)\r\n } else {\r\n f.waits_.push(() => {\r\n resolve()\r\n })\r\n }\r\n } else {\r\n\r\n f = { o3d: null, waits_: [] }\r\n this.cache_[c_url] = f\r\n\r\n let sep_i = c_url.lastIndexOf('/')\r\n this.view_.build_specs__([{\r\n func: 'setupModelGltf',\r\n param: {\r\n path: c_url.substr(0, sep_i + 1),\r\n name: c_url.substr(sep_i + 1),\r\n onAfter: o3d => {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (this.view_.shopData_.panorama) {\r\n c.material.envMapIntensity = this.view_.shopData_.panorama.multiply\r\n } else {\r\n c.material.envMapIntensity = 1\r\n }\r\n c.material.side = three__WEBPACK_IMPORTED_MODULE_0__.FrontSide\r\n }\r\n })\r\n\r\n if (!o3d.isMesh && o3d.children.length == 1) {\r\n f.o3d = o3d.children[0]\r\n } else {\r\n f.o3d = o3d\r\n }\r\n\r\n f.waits_.forEach(fi => {\r\n fi()\r\n })\r\n\r\n resolve(f.o3d)\r\n\r\n }\r\n // TODO onError reject(err)\r\n }\r\n }])\r\n\r\n }\r\n\r\n })\r\n }\r\n\r\n dispose() {\r\n\r\n Object.values(this.cache_).forEach(c => {\r\n if (c.o3d) {\r\n c.o3d.traverse(cc => {\r\n if (cc.isMesh) {\r\n cc.geometry.dispose()\r\n // console.log('dispose geometry!')\r\n }\r\n })\r\n }\r\n })\r\n\r\n\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/CommoditiesCache.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CommoditiesCache\": () => (/* binding */ CommoditiesCache)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\nclass CommoditiesCache {\r\n\r\n constructor(view) {\r\n this.view_ = view\r\n this.cache_ = {} // url -> {o3d}\r\n }\r\n\r\n find(commodity) {\r\n return new Promise((resolve, reject) => {\r\n\r\n let c_url = commodity.url\r\n let f = this.cache_[c_url]\r\n if (f) {\r\n if (f.o3d != null) {\r\n resolve(f.o3d)\r\n } else {\r\n f.waits_.push(() => {\r\n resolve()\r\n })\r\n }\r\n } else {\r\n\r\n f = { o3d: null, waits_: [] }\r\n this.cache_[c_url] = f\r\n\r\n let sep_i = c_url.lastIndexOf('/')\r\n this.view_.build_specs__([{\r\n func: 'setupModelGltf',\r\n param: {\r\n path: c_url.substr(0, sep_i + 1),\r\n name: c_url.substr(sep_i + 1),\r\n onAfter: o3d => {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (this.view_.shopData_.panorama) {\r\n c.material.envMapIntensity = this.view_.shopData_.panorama.multiply\r\n } else {\r\n c.material.envMapIntensity = 1\r\n }\r\n c.material.side = three__WEBPACK_IMPORTED_MODULE_0__.FrontSide\r\n }\r\n })\r\n\r\n if (!o3d.isMesh && o3d.children.length == 1) {\r\n f.o3d = o3d.children[0]\r\n } else {\r\n f.o3d = o3d\r\n }\r\n\r\n f.waits_.forEach(fi => {\r\n fi()\r\n })\r\n\r\n resolve(f.o3d)\r\n\r\n }\r\n // TODO onError reject(err)\r\n }\r\n }])\r\n\r\n }\r\n\r\n })\r\n }\r\n\r\n dispose() {\r\n\r\n Object.values(this.cache_).forEach(c => {\r\n if (c.o3d) {\r\n c.o3d.traverse(cc => {\r\n if (cc.isMesh) {\r\n cc.geometry.dispose()\r\n // console.log('dispose geometry!')\r\n }\r\n })\r\n }\r\n })\r\n\r\n\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/CommoditiesCache.js?");
/***/ }),
@@ -388,7 +388,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SurveyShelve\": () => (/* binding */ SurveyShelve)\n/* harmony export */ });\n/* harmony import */ var _BaseShelve__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var kutsi_red_valley_o3d_TextSprite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi-red-valley/o3d/TextSprite */ \"./src-kutsi-red-valley/crossyo/kutsi/o3d/TextSprite.js\");\n/* harmony import */ var kutsi_red_valley_o3d_TextPlaneSprite__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi-red-valley/o3d/TextPlaneSprite */ \"./src-kutsi-red-valley/crossyo/kutsi/o3d/TextPlaneSprite.js\");\n/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n// import { PerspType } from 'kutsi/util/PerspUtil'\r\n\r\n\r\n\r\nclass SurveyShelve extends _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.BaseShelve {\r\n\r\n constructor(viewer) {\r\n super(viewer)\r\n\r\n this.picker_ = viewer.picker_\r\n\r\n // console.log('SurveyShelve')\r\n this.page_o3ds_ = []\r\n\r\n }\r\n\r\n arrange(page) {\r\n console.log('#### shelve.arrange', page)\r\n // r-1/c-1/{logo, favorite, shape, price}\r\n return new Promise(resolve1 => {\r\n\r\n let mesh_shelf = this.viewer_.mesh_shelf__\r\n if (!mesh_shelf) {\r\n console.warn('shelf 模型 not found!')\r\n return\r\n }\r\n\r\n // remove shelvs\r\n {\r\n this.picker_.emptyHits()\r\n this.page_o3ds_.forEach(o3d => {\r\n o3d.removeFromParent()\r\n })\r\n this.page_o3ds_ = []\r\n }\r\n\r\n {\r\n let cells = page.cells\r\n if (cells) {\r\n let f_cells = cells.filter(cell => (cell && cell.surveyWare))\r\n f_cells.reduce(\r\n (p, cell) => p.then(() => {\r\n cell.ext__ = null // clear previous!\r\n return this.addWareToCell(cell.surveyWare, cell)\r\n }),\r\n Promise.resolve()\r\n ).then(() => {\r\n\r\n f_cells.forEach(cell => {\r\n let hit = {\r\n name: cell.name,\r\n surveyLogo: cell.surveyLogo,\r\n surveyPrice: cell.surveyPrice,\r\n surveyWare: cell.surveyWare,\r\n }\r\n let c_o3d__ = cell.ext__.get_c_o3d__() // 容器\r\n this.page_o3ds_.push(c_o3d__)\r\n c_o3d__.children.forEach(c => {\r\n\r\n if (c.isMesh) {\r\n c.hit_ = Object.assign({\r\n targetObject__: c\r\n }, hit)\r\n this.picker_.pushHit(c)\r\n } else { // v3.3 #20220730 多个mesh的物体\r\n c.traverse(cc => {\r\n if (cc.isMesh) {\r\n cc.hit_ = Object.assign({\r\n targetObject__: c\r\n }, hit)\r\n this.picker_.pushHit(cc)\r\n }\r\n })\r\n }\r\n })\r\n\r\n this.addLogoPriceToCell(cell)\r\n })\r\n\r\n resolve1()\r\n })\r\n\r\n }\r\n }\r\n\r\n })\r\n\r\n }\r\n\r\n addLogoPriceToCell(cell) {\r\n\r\n // console.log('addLogoPriceToCell', cell)\r\n\r\n let mesh_shelf = this.viewer_.mesh_shelf__\r\n\r\n let cell_o3d = (() => {\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n return (0,_util__WEBPACK_IMPORTED_MODULE_3__.use_ext)(cell).get_c_o3d__()\r\n } else {\r\n return null\r\n }\r\n })()\r\n\r\n // #20221023\r\n let showLogo = true\r\n if (cell.hasOwnProperty('showLogo')) {\r\n showLogo = cell.showLogo\r\n }\r\n if (showLogo) {// logo\r\n let txtLogo = new kutsi_red_valley_o3d_TextSprite__WEBPACK_IMPORTED_MODULE_1__[\"default\"]({\r\n depthWrite: true,\r\n depthTest: true,\r\n }, {\r\n text: cell.surveyLogo,\r\n noPerspScale: .028, // .0185 * 1.5,\r\n })\r\n\r\n let logo = null\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n logo = cell.logo\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n logo = cell.box.child.logo\r\n }\r\n\r\n let logopos = logo.position\r\n if (logopos) {\r\n txtLogo.position.copy(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(logopos.x, logopos.y, logopos.z))\r\n } else { // 兼容之前老的logo数据没有position的问题\r\n let boxpos = cell.box.position\r\n txtLogo.position.copy(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(0, .15, 0).add(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(boxpos.x, boxpos.y, boxpos.z)))\r\n }\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n mesh_shelf.add(txtLogo)\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n if (cell_o3d) {\r\n cell_o3d.add(txtLogo)\r\n // { // debug\r\n // let axes = new AxesHelper(.2)\r\n // axes.position.set(logopos.x, logopos.y, logopos.z)\r\n // cell_o3d.add(axes)\r\n // }\r\n }\r\n }\r\n\r\n // // #20220912, v3.5\r\n // txtLogo.visible = !!cell.surveyLogo\r\n\r\n this.page_o3ds_.push(txtLogo)\r\n }\r\n\r\n // #20221023\r\n let showSign = true\r\n if (cell.hasOwnProperty('showSign')) {\r\n showSign = cell.showSign\r\n }\r\n if (showSign) {// sign - price\r\n\r\n let sign = null\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n sign = cell.sign\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n sign = cell.box.child.sign\r\n }\r\n\r\n // let txtPrice = new TextSprite({\r\n let txtPrice = new kutsi_red_valley_o3d_TextPlaneSprite__WEBPACK_IMPORTED_MODULE_2__.TextPlaneSprite({\r\n depthWrite: true,\r\n depthTest: true,\r\n // 214,202,178 \r\n color: 0xd6cab2, // bg\r\n }, {\r\n textColor: 0x000000,\r\n text: (0,_util__WEBPACK_IMPORTED_MODULE_3__.text_price_)(cell.surveyPrice),\r\n center_y: .5,\r\n // noPerspScale: .025,\r\n noPerspScale: .05,\r\n // perpType: PerspType.Persp,\r\n })\r\n\r\n // TODO ..\r\n\r\n let spos = sign.position\r\n txtPrice.position.set(spos.x, spos.y, spos.z)\r\n let srot = sign.rotation\r\n txtPrice.rotation.set(srot.x, srot.y, srot.z)\r\n\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n mesh_shelf.add(txtPrice)\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n if (cell_o3d) {\r\n cell_o3d.add(txtPrice)\r\n // { // debug\r\n // let axes = new AxesHelper(.2)\r\n // axes.position.set(spos.x, spos.y, spos.z)\r\n // cell_o3d.add(axes)\r\n // }\r\n }\r\n }\r\n\r\n this.page_o3ds_.push(txtPrice)\r\n }\r\n\r\n }\r\n\r\n\r\n dispose() {\r\n super.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/SurveyShelve.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SurveyShelve\": () => (/* binding */ SurveyShelve)\n/* harmony export */ });\n/* harmony import */ var _BaseShelve__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var kutsi_red_valley_o3d_TextSprite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi-red-valley/o3d/TextSprite */ \"./src-kutsi-red-valley/crossyo/kutsi/o3d/TextSprite.js\");\n/* harmony import */ var kutsi_red_valley_o3d_TextPlaneSprite__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi-red-valley/o3d/TextPlaneSprite */ \"./src-kutsi-red-valley/crossyo/kutsi/o3d/TextPlaneSprite.js\");\n/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n// import { PerspType } from 'kutsi/util/PerspUtil'\r\n\r\n\r\n\r\nclass SurveyShelve extends _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.BaseShelve {\r\n\r\n constructor(viewer) {\r\n super(viewer)\r\n\r\n this.picker_ = viewer.picker_\r\n\r\n // console.log('SurveyShelve')\r\n this.page_o3ds_ = []\r\n\r\n }\r\n\r\n arrange(page) {\r\n console.log('#### shelve.arrange', page)\r\n // r-1/c-1/{logo, favorite, shape, price}\r\n return new Promise(resolve1 => {\r\n\r\n let mesh_shelf = this.viewer_.mesh_shelf__\r\n if (!mesh_shelf) {\r\n console.warn('shelf 模型 not found!')\r\n return\r\n }\r\n\r\n // remove shelvs\r\n {\r\n this.picker_.emptyHits()\r\n this.page_o3ds_.forEach(o3d => {\r\n o3d.removeFromParent()\r\n })\r\n this.page_o3ds_ = []\r\n }\r\n\r\n {\r\n let cells = page.cells\r\n if (cells) {\r\n let f_cells = cells.filter(cell => (cell && cell.surveyWare))\r\n f_cells.reduce(\r\n (p, cell) => p.then(() => {\r\n cell.ext__ = null // clear previous!\r\n return this.addWareToCell(cell.surveyWare, cell)\r\n }),\r\n Promise.resolve()\r\n ).then(() => {\r\n\r\n f_cells.forEach(cell => {\r\n let hit = {\r\n name: cell.name,\r\n surveyLogo: cell.surveyLogo,\r\n surveyPrice: cell.surveyPrice,\r\n surveyWare: cell.surveyWare,\r\n }\r\n let c_o3d__ = cell.ext__.get_c_o3d__() // 容器\r\n this.page_o3ds_.push(c_o3d__)\r\n c_o3d__.children.forEach(c => {\r\n\r\n if (c.isMesh) {\r\n c.hit_ = Object.assign({\r\n targetObject__: c\r\n }, hit)\r\n this.picker_.pushHit(c)\r\n } else { // v3.3 #20220730 多个mesh的物体\r\n c.traverse(cc => {\r\n if (cc.isMesh) {\r\n cc.hit_ = Object.assign({\r\n targetObject__: c\r\n }, hit)\r\n this.picker_.pushHit(cc)\r\n }\r\n })\r\n }\r\n })\r\n\r\n this.addLogoPriceToCell(cell)\r\n })\r\n\r\n resolve1()\r\n })\r\n\r\n }\r\n }\r\n\r\n })\r\n\r\n }\r\n\r\n addLogoPriceToCell(cell) {\r\n\r\n // console.log('addLogoPriceToCell', cell)\r\n\r\n let mesh_shelf = this.viewer_.mesh_shelf__\r\n\r\n let cell_o3d = (() => {\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n return (0,_util__WEBPACK_IMPORTED_MODULE_3__.use_ext)(cell).get_c_o3d__()\r\n } else {\r\n return null\r\n }\r\n })()\r\n\r\n // #20221023\r\n let showLogo = true\r\n if (cell.hasOwnProperty('showLogo')) {\r\n showLogo = cell.showLogo\r\n }\r\n if (showLogo) {// logo\r\n let txtLogo = new kutsi_red_valley_o3d_TextSprite__WEBPACK_IMPORTED_MODULE_1__[\"default\"]({\r\n depthWrite: true,\r\n depthTest: true,\r\n }, {\r\n text: cell.surveyLogo,\r\n noPerspScale: .028, // .0185 * 1.5,\r\n })\r\n\r\n let logo = null\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n logo = cell.logo\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n logo = cell.box.child.logo\r\n }\r\n\r\n let logopos = logo.position\r\n if (logopos) {\r\n txtLogo.position.copy(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(logopos.x, logopos.y, logopos.z))\r\n } else { // 兼容之前老的logo数据没有position的问题\r\n let boxpos = cell.box.position\r\n txtLogo.position.copy(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(0, .15, 0).add(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(boxpos.x, boxpos.y, boxpos.z)))\r\n }\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n mesh_shelf.add(txtLogo)\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n if (cell_o3d) {\r\n cell_o3d.add(txtLogo)\r\n // { // debug\r\n // let axes = new AxesHelper(.2)\r\n // axes.position.set(logopos.x, logopos.y, logopos.z)\r\n // cell_o3d.add(axes)\r\n // }\r\n }\r\n }\r\n\r\n // // #20220912, v3.5\r\n // txtLogo.visible = !!cell.surveyLogo\r\n\r\n this.page_o3ds_.push(txtLogo)\r\n }\r\n\r\n // #20221023\r\n let showSign = true\r\n if (cell.hasOwnProperty('showSign')) {\r\n showSign = cell.showSign\r\n }\r\n if (showSign) {// sign - price\r\n\r\n let sign = null\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n sign = cell.sign\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n sign = cell.box.child.sign\r\n }\r\n\r\n // let txtPrice = new TextSprite({\r\n let txtPrice = new kutsi_red_valley_o3d_TextPlaneSprite__WEBPACK_IMPORTED_MODULE_2__.TextPlaneSprite({\r\n depthWrite: true,\r\n depthTest: true,\r\n // 214,202,178 \r\n color: 0xd6cab2, // bg\r\n }, {\r\n textColor: 0x000000,\r\n text: (0,_util__WEBPACK_IMPORTED_MODULE_3__.text_price_)(cell.surveyPrice),\r\n center_y: .5,\r\n // noPerspScale: .025,\r\n noPerspScale: .05,\r\n // perpType: PerspType.Persp,\r\n })\r\n\r\n // TODO ..\r\n\r\n let spos = sign.position\r\n txtPrice.position.set(spos.x, spos.y, spos.z)\r\n let srot = sign.rotation\r\n txtPrice.rotation.set(srot.x, srot.y, srot.z)\r\n\r\n if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n mesh_shelf.add(txtPrice)\r\n } else if (_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n if (cell_o3d) {\r\n cell_o3d.add(txtPrice)\r\n // { // debug\r\n // let axes = new AxesHelper(.2)\r\n // axes.position.set(spos.x, spos.y, spos.z)\r\n // cell_o3d.add(axes)\r\n // }\r\n }\r\n }\r\n\r\n this.page_o3ds_.push(txtPrice)\r\n }\r\n\r\n }\r\n\r\n\r\n dispose() {\r\n super.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/SurveyShelve.js?");
/***/ }),
@@ -399,7 +399,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TexturesCache\": () => (/* binding */ TexturesCache)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\nclass TexturesCache {\r\n\r\n constructor(view) {\r\n this.view_ = view\r\n this.cache_ = {} // url -> {tex}\r\n }\r\n\r\n find(texture) {\r\n return new Promise((resolve, reject) => {\r\n\r\n if (texture) {\r\n\r\n let t_url = texture.url\r\n let f = this.cache_[t_url]\r\n if (f) {\r\n if (f.tex != null) {\r\n resolve(f.tex)\r\n } else {\r\n f.waits_.push(() => {\r\n resolve()\r\n })\r\n }\r\n } else {\r\n\r\n f = { tex: null, waits_: [] }\r\n this.cache_[t_url] = f\r\n\r\n new three__WEBPACK_IMPORTED_MODULE_0__.TextureLoader().load(t_url, tex => {\r\n tex.flipY = false\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_0__.sRGBEncoding // #20220719, v3.3 fix\r\n f.tex = tex\r\n f.waits_.forEach(fi => {\r\n fi()\r\n })\r\n resolve(f.tex)\r\n }, undefined, err => {\r\n reject(err)\r\n })\r\n\r\n }\r\n\r\n } else {\r\n resolve(null) // type == 1, texture 可能为null\r\n }\r\n\r\n\r\n })\r\n }\r\n\r\n dispose() {\r\n Object.values(this.cache_).forEach(c => {\r\n if (c.tex) {\r\n c.tex.dispose()\r\n }\r\n })\r\n // console.log('dispose texture')\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/TexturesCache.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"TexturesCache\": () => (/* binding */ TexturesCache)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\nclass TexturesCache {\r\n\r\n constructor(view) {\r\n this.view_ = view\r\n this.cache_ = {} // url -> {tex}\r\n }\r\n\r\n find(texture) {\r\n return new Promise((resolve, reject) => {\r\n\r\n if (texture) {\r\n\r\n let t_url = texture.url\r\n let f = this.cache_[t_url]\r\n if (f) {\r\n if (f.tex != null) {\r\n resolve(f.tex)\r\n } else {\r\n f.waits_.push(() => {\r\n resolve()\r\n })\r\n }\r\n } else {\r\n\r\n f = { tex: null, waits_: [] }\r\n this.cache_[t_url] = f\r\n\r\n new three__WEBPACK_IMPORTED_MODULE_0__.TextureLoader().load(t_url, tex => {\r\n tex.flipY = false\r\n tex.encoding = three__WEBPACK_IMPORTED_MODULE_0__.sRGBEncoding // #20220719, v3.3 fix\r\n f.tex = tex\r\n f.waits_.forEach(fi => {\r\n fi()\r\n })\r\n resolve(f.tex)\r\n }, undefined, err => {\r\n reject(err)\r\n })\r\n\r\n }\r\n\r\n } else {\r\n resolve(null) // type == 1, texture 可能为null\r\n }\r\n\r\n\r\n })\r\n }\r\n\r\n dispose() {\r\n Object.values(this.cache_).forEach(c => {\r\n if (c.tex) {\r\n c.tex.dispose()\r\n }\r\n })\r\n // console.log('dispose texture')\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/TexturesCache.js?");
/***/ }),
@@ -410,7 +410,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"prefab\": () => (/* binding */ prefab)\n/* harmony export */ });\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.139.2@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _assets_prefab_20220620_gltf__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../assets/prefab-20220620.gltf */ \"./src/crossyo/shelves/assets/prefab-20220620.gltf\");\n\r\n\r\n\r\n\r\n\r\nclass Prefab {\r\n\r\n setup(next) {\r\n new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader().parse(_assets_prefab_20220620_gltf__WEBPACK_IMPORTED_MODULE_1__[\"default\"], null, gltf => {\r\n const prefab = gltf.scene\r\n\r\n // console.log(prefab)\r\n this.cell_box_origin_ = prefab.getObjectByName('box-bottom-center')\r\n // this.cell_box_origin_.add(new AxesHelper(1))\r\n\r\n // console.log(this.cell_box_origin_)\r\n this.sign_origin_ = prefab.getObjectByName('sign')\r\n this.logo_origin_ = prefab.getObjectByName('logo')\r\n\r\n next()\r\n }, err => {\r\n console.log(err)\r\n })\r\n\r\n return this\r\n }\r\n\r\n // get_plastic_box_material__() {\r\n // if (!this.plastic_box_material__) {\r\n // this.plastic_box_material__ = new MeshStandardMaterial({\r\n // transparent: true,\r\n // // opacity: .45,\r\n // opacity: .75,\r\n // })\r\n // }\r\n // return this.plastic_box_material__\r\n // }\r\n\r\n // get_plastic_sign_material__() {\r\n // if (!this.plastic_sign_material__) {\r\n // this.plastic_sign_material__ = new MeshStandardMaterial({\r\n // color: 0x804D15,\r\n // })\r\n // }\r\n // return this.plastic_sign_material__\r\n // }\r\n\r\n // get_plastic_logo_material__() {\r\n // if (!this.plastic_logo_material__) {\r\n // this.plastic_logo_material__ = new MeshStandardMaterial({\r\n // color: 0x3c1255,\r\n // })\r\n // }\r\n // return this.plastic_logo_material__\r\n // }\r\n\r\n clone_cell_box() {\r\n let mesh = this.cell_box_origin_.clone()\r\n // mesh.material = this.get_plastic_box_material__()\r\n return mesh\r\n }\r\n\r\n clone_sign() {\r\n let mesh = this.sign_origin_.clone()\r\n // mesh.material = this.get_plastic_sign_material__()\r\n return mesh\r\n }\r\n\r\n clone_logo() {\r\n let mesh = this.logo_origin_.clone()\r\n // mesh.material = this.get_plastic_logo_material__()\r\n return mesh\r\n }\r\n\r\n}\r\n\r\nconst prefab = new Prefab()\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/prefab.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"prefab\": () => (/* binding */ prefab)\n/* harmony export */ });\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.146.0@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _assets_prefab_20220620_gltf__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../assets/prefab-20220620.gltf */ \"./src/crossyo/shelves/assets/prefab-20220620.gltf\");\n\r\n\r\n\r\n\r\n\r\nclass Prefab {\r\n\r\n setup(next) {\r\n new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader().parse(_assets_prefab_20220620_gltf__WEBPACK_IMPORTED_MODULE_0__[\"default\"], null, gltf => {\r\n const prefab = gltf.scene\r\n\r\n // console.log(prefab)\r\n this.cell_box_origin_ = prefab.getObjectByName('box-bottom-center')\r\n // this.cell_box_origin_.add(new AxesHelper(1))\r\n\r\n // console.log(this.cell_box_origin_)\r\n this.sign_origin_ = prefab.getObjectByName('sign')\r\n this.logo_origin_ = prefab.getObjectByName('logo')\r\n\r\n next()\r\n }, err => {\r\n console.log(err)\r\n })\r\n\r\n return this\r\n }\r\n\r\n // get_plastic_box_material__() {\r\n // if (!this.plastic_box_material__) {\r\n // this.plastic_box_material__ = new MeshStandardMaterial({\r\n // transparent: true,\r\n // // opacity: .45,\r\n // opacity: .75,\r\n // })\r\n // }\r\n // return this.plastic_box_material__\r\n // }\r\n\r\n // get_plastic_sign_material__() {\r\n // if (!this.plastic_sign_material__) {\r\n // this.plastic_sign_material__ = new MeshStandardMaterial({\r\n // color: 0x804D15,\r\n // })\r\n // }\r\n // return this.plastic_sign_material__\r\n // }\r\n\r\n // get_plastic_logo_material__() {\r\n // if (!this.plastic_logo_material__) {\r\n // this.plastic_logo_material__ = new MeshStandardMaterial({\r\n // color: 0x3c1255,\r\n // })\r\n // }\r\n // return this.plastic_logo_material__\r\n // }\r\n\r\n clone_cell_box() {\r\n let mesh = this.cell_box_origin_.clone()\r\n // mesh.material = this.get_plastic_box_material__()\r\n return mesh\r\n }\r\n\r\n clone_sign() {\r\n let mesh = this.sign_origin_.clone()\r\n // mesh.material = this.get_plastic_sign_material__()\r\n return mesh\r\n }\r\n\r\n clone_logo() {\r\n let mesh = this.logo_origin_.clone()\r\n // mesh.material = this.get_plastic_logo_material__()\r\n return mesh\r\n }\r\n\r\n}\r\n\r\nconst prefab = new Prefab()\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/prefab.js?");
/***/ }),
@@ -421,7 +421,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"box3_except_shadow\": () => (/* binding */ box3_except_shadow),\n/* harmony export */ \"clone_except_ext\": () => (/* binding */ clone_except_ext),\n/* harmony export */ \"isMobile\": () => (/* binding */ isMobile),\n/* harmony export */ \"text_price_\": () => (/* binding */ text_price_),\n/* harmony export */ \"to_transform\": () => (/* binding */ to_transform),\n/* harmony export */ \"use_ext\": () => (/* binding */ use_ext),\n/* harmony export */ \"write_transform\": () => (/* binding */ write_transform),\n/* harmony export */ \"write_transform_cell_box\": () => (/* binding */ write_transform_cell_box),\n/* harmony export */ \"write_transform_cell_box_inherited\": () => (/* binding */ write_transform_cell_box_inherited),\n/* harmony export */ \"write_transform_cell_logo\": () => (/* binding */ write_transform_cell_logo),\n/* harmony export */ \"write_transform_cell_sign\": () => (/* binding */ write_transform_cell_sign)\n/* harmony export */ });\n/* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mobile-detect */ \"./node_modules/_mobile-detect@1.4.5@mobile-detect/mobile-detect.js\");\n/* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(mobile_detect__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n\r\n\r\n\r\n\r\nconst mobileDetect = new (mobile_detect__WEBPACK_IMPORTED_MODULE_0___default())(window.navigator.userAgent)\r\nconst isMobile = mobileDetect.mobile() != null\r\n\r\nconst to_transform = o3d => {\r\n return {\r\n position: o3d.position,\r\n rotation: {\r\n x: o3d.rotation.x,\r\n y: o3d.rotation.y,\r\n z: o3d.rotation.z\r\n },\r\n scale: o3d.scale,\r\n }\r\n}\r\n\r\n// 使得vue可以更新\r\nconst write_transform = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n obj.scale.x = o3d.scale.x\r\n obj.scale.y = o3d.scale.y\r\n obj.scale.z = o3d.scale.z\r\n\r\n}\r\n\r\nconst write_transform_cell_box = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n obj.size.x = o3d.scale.x\r\n obj.size.y = o3d.scale.y\r\n obj.size.z = o3d.scale.z\r\n\r\n}\r\n\r\nconst write_transform_cell_box_inherited = (o3d, obj) => {\r\n\r\n if (o3d.grp_hit_cell_) { // group\r\n \r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n \r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n } else if (o3d.parent.grp_hit_cell_) { // box mesh\r\n\r\n obj.size.x = o3d.scale.x\r\n obj.size.y = o3d.scale.y\r\n obj.size.z = o3d.scale.z\r\n // console.log('xx size', obj.size)\r\n\r\n } else {\r\n console.log('xx xx')\r\n }\r\n\r\n}\r\n\r\n\r\nconst write_transform_cell_sign = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n}\r\n\r\nconst write_transform_cell_logo = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n}\r\n\r\nconst box3_except_shadow = o3d => {\r\n let bb_c = null\r\n o3d.traverse(c => {\r\n if (c.isMesh && !(/\\w-shadow$/.test(c.name))) {\r\n // console.log(c.name)\r\n if (bb_c == null) {\r\n bb_c = new three__WEBPACK_IMPORTED_MODULE_1__.Box3().copy(c.geometry.boundingBox)\r\n } else {\r\n bb_c = bb_c.union(c.geometry.boundingBox)\r\n }\r\n }\r\n })\r\n return bb_c\r\n}\r\n\r\nconst use_ext = o => {\r\n if (!o.ext__) {\r\n o.ext__ = {}\r\n }\r\n return o.ext__\r\n}\r\n\r\nconst clone_except_ext = o => {\r\n return JSON.parse(JSON.stringify(o, (k, v) => {\r\n if (k == 'ext__') {\r\n return undefined\r\n } else {\r\n return v\r\n }\r\n }))\r\n}\r\n\r\nconst text_price_ = v => ` ¥${parseFloat(v).toFixed(2)}`\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/util.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"box3_except_shadow\": () => (/* binding */ box3_except_shadow),\n/* harmony export */ \"clone_except_ext\": () => (/* binding */ clone_except_ext),\n/* harmony export */ \"isMobile\": () => (/* binding */ isMobile),\n/* harmony export */ \"text_price_\": () => (/* binding */ text_price_),\n/* harmony export */ \"to_transform\": () => (/* binding */ to_transform),\n/* harmony export */ \"use_ext\": () => (/* binding */ use_ext),\n/* harmony export */ \"write_transform\": () => (/* binding */ write_transform),\n/* harmony export */ \"write_transform_cell_box\": () => (/* binding */ write_transform_cell_box),\n/* harmony export */ \"write_transform_cell_box_inherited\": () => (/* binding */ write_transform_cell_box_inherited),\n/* harmony export */ \"write_transform_cell_logo\": () => (/* binding */ write_transform_cell_logo),\n/* harmony export */ \"write_transform_cell_sign\": () => (/* binding */ write_transform_cell_sign)\n/* harmony export */ });\n/* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mobile-detect */ \"./node_modules/_mobile-detect@1.4.5@mobile-detect/mobile-detect.js\");\n/* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(mobile_detect__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n\r\n\r\n\r\n\r\nconst mobileDetect = new (mobile_detect__WEBPACK_IMPORTED_MODULE_0___default())(window.navigator.userAgent)\r\nconst isMobile = mobileDetect.mobile() != null\r\n\r\nconst to_transform = o3d => {\r\n return {\r\n position: o3d.position,\r\n rotation: {\r\n x: o3d.rotation.x,\r\n y: o3d.rotation.y,\r\n z: o3d.rotation.z\r\n },\r\n scale: o3d.scale,\r\n }\r\n}\r\n\r\n// 使得vue可以更新\r\nconst write_transform = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n obj.scale.x = o3d.scale.x\r\n obj.scale.y = o3d.scale.y\r\n obj.scale.z = o3d.scale.z\r\n\r\n}\r\n\r\nconst write_transform_cell_box = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n obj.size.x = o3d.scale.x\r\n obj.size.y = o3d.scale.y\r\n obj.size.z = o3d.scale.z\r\n\r\n}\r\n\r\nconst write_transform_cell_box_inherited = (o3d, obj) => {\r\n\r\n if (o3d.grp_hit_cell_) { // group\r\n \r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n \r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n } else if (o3d.parent.grp_hit_cell_) { // box mesh\r\n\r\n obj.size.x = o3d.scale.x\r\n obj.size.y = o3d.scale.y\r\n obj.size.z = o3d.scale.z\r\n // console.log('xx size', obj.size)\r\n\r\n } else {\r\n console.log('xx xx')\r\n }\r\n\r\n}\r\n\r\n\r\nconst write_transform_cell_sign = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n\r\n obj.rotation.x = o3d.rotation.x\r\n obj.rotation.y = o3d.rotation.y\r\n obj.rotation.z = o3d.rotation.z\r\n\r\n}\r\n\r\nconst write_transform_cell_logo = (o3d, obj) => {\r\n\r\n obj.position.x = o3d.position.x\r\n obj.position.y = o3d.position.y\r\n obj.position.z = o3d.position.z\r\n}\r\n\r\nconst box3_except_shadow = o3d => {\r\n let bb_c = null\r\n o3d.traverse(c => {\r\n if (c.isMesh && !(/\\w-shadow$/.test(c.name))) {\r\n // console.log(c.name)\r\n if (bb_c == null) {\r\n bb_c = new three__WEBPACK_IMPORTED_MODULE_1__.Box3().copy(c.geometry.boundingBox)\r\n } else {\r\n bb_c = bb_c.union(c.geometry.boundingBox)\r\n }\r\n }\r\n })\r\n return bb_c\r\n}\r\n\r\nconst use_ext = o => {\r\n if (!o.ext__) {\r\n o.ext__ = {}\r\n }\r\n return o.ext__\r\n}\r\n\r\nconst clone_except_ext = o => {\r\n return JSON.parse(JSON.stringify(o, (k, v) => {\r\n if (k == 'ext__') {\r\n return undefined\r\n } else {\r\n return v\r\n }\r\n }))\r\n}\r\n\r\nconst text_price_ = v => ` ¥${parseFloat(v).toFixed(2)}`\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/common/util.js?");
/***/ }),
@@ -432,7 +432,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ArrangementEditor\": () => (/* binding */ ArrangementEditor)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/controls/TransformControls */ \"./node_modules/_three@0.139.2@three/examples/jsm/controls/TransformControls.js\");\n/* harmony import */ var _BaseEditor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BaseEditor */ \"./src/crossyo/shelves/editor/BaseEditor.js\");\n/* harmony import */ var _common_BaseShelve__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../common/BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ArrangementEditor extends _BaseEditor__WEBPACK_IMPORTED_MODULE_1__.BaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.shelve_ = new _common_BaseShelve__WEBPACK_IMPORTED_MODULE_2__.BaseShelve(this)\r\n\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n }\r\n\r\n endLoadSpecs() {\r\n // super.endLoadSpecs() // 不执行 viewer 的 endLoadSpecs\r\n this.after_add_shelf__()\r\n\r\n this.picker_.on('downPick', e => {\r\n // console.log('downPick', e)\r\n // if (!this.control_.enabled) {\r\n // return\r\n // }\r\n if (e.int0) {\r\n let object = e.int0.object\r\n let hit_ = object.hit_\r\n // if (hit_.type == 'shelf') {\r\n // // this.control_trans__.detach()\r\n // this.control_trans__.attach(this.mesh_shelf__)\r\n // } \r\n if (hit_.type == 'box') {\r\n // this.control_trans__.detach()\r\n\r\n this.active_selected_(object)\r\n\r\n this.emit('arrange.selectCell', hit_.cell)\r\n //\r\n\r\n // } else if (hit_.type == 'commodity') {\r\n // this.control_trans__.attach(object)\r\n }\r\n\r\n } else {\r\n this.active_selected_(null)\r\n this.control_trans__.detach()\r\n }\r\n })\r\n\r\n this.control_trans__ = new three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_0__.TransformControls(this.camera_, this.renderer_.domElement)\r\n // this.control_trans__.addEventListener('change', )\r\n this.control_trans__.addEventListener('dragging-changed', e => {\r\n this.controls_.enabled = !e.value\r\n })\r\n this.control_trans__.addEventListener('objectChange', e => {\r\n // console.log(e, e.target)\r\n let obj = this.control_trans__.object\r\n // if (obj == this.mesh_shelf__) {\r\n // this.shopData_.scene = {\r\n // shelf: to_transform(obj)\r\n // }\r\n // }\r\n })\r\n this.scene_.add(this.control_trans__)\r\n\r\n // console.log(this.shopData_) // 實際上是 arrangement data!\r\n {\r\n let shelf = this.shopData_.shelf\r\n if (shelf) {\r\n let cells = shelf.cells\r\n if (cells) {\r\n cells.filter(cell => (cell && cell.pileWare)).reduce(\r\n (p, cell) => p.then(() => this.shelve_.addWareToCell(cell.pileWare, cell)),\r\n Promise.resolve()\r\n ).then(() => {\r\n this.emit('loadingCompletion')\r\n })\r\n return\r\n }\r\n }\r\n }\r\n\r\n this.emit('loadingCompletion')\r\n\r\n }\r\n\r\n updateAction(action) {\r\n\r\n // console.log('# updateAction', action)\r\n\r\n if (action.action == 'bindCellWare') {\r\n\r\n console.log('bindCellWare', action)\r\n\r\n this.shelve_.addWareToCell(action.ware, action.cell)\r\n\r\n } else if (action.action == 'unbindCellWare') {\r\n\r\n this.shelve_.removeWareFromCell(action.cell)\r\n\r\n action.cell.pileWare = null\r\n\r\n } else if (action.action == 'updateCellPileNumber') {\r\n\r\n this.shelve_.update_cell_pileNumber_(action.cell)\r\n\r\n } else if (action.action == 'updateCellPileRotationY') {\r\n\r\n this.shelve_.update_cell_pileRotationY_(action.cell)\r\n\r\n }\r\n\r\n }\r\n\r\n after_add_shelf__() {\r\n\r\n this.picker_.emptyHits()\r\n\r\n if (this.mesh_shelf__) {\r\n\r\n // let o3d = this.mesh_shelf__\r\n // let hit_ = { type: 'shelf' }\r\n // // console.log('add_hit__', o3d)\r\n // o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n // if (/^box-\\d-\\d/.test(c.name)) {\r\n // } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n // } else if (/.*-shadow$/.test(c.name)) {\r\n // } else {\r\n // c.hit_ = hit_\r\n // this.picker_.pushHit(c)\r\n // }\r\n // }\r\n // })\r\n\r\n // cells\r\n this.shopData_.shelf.cells.forEach(cell => {\r\n\r\n let box = cell.box\r\n // console.log(cell)\r\n let mesh_box = this.prefab__.clone_cell_box()\r\n mesh_box.position.set(box.position.x, box.position.y, box.position.z)\r\n mesh_box.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n mesh_box.scale.set(box.size.x, box.size.y, box.size.z)\r\n let mat = new three__WEBPACK_IMPORTED_MODULE_3__.MeshStandardMaterial({\r\n transparent: true,\r\n opacity: .45,\r\n // visible: false,\r\n side: three__WEBPACK_IMPORTED_MODULE_3__.BackSide,\r\n })\r\n\r\n mesh_box.material = mat\r\n this.mesh_shelf__.add(mesh_box)\r\n\r\n mesh_box.hit_ = { type: 'box', cell }\r\n this.picker_.pushHit(mesh_box)\r\n\r\n })\r\n\r\n }\r\n\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n this.shelve_.dispose()\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ArrangementEditor.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ArrangementEditor\": () => (/* binding */ ArrangementEditor)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/controls/TransformControls */ \"./node_modules/_three@0.146.0@three/examples/jsm/controls/TransformControls.js\");\n/* harmony import */ var _BaseEditor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseEditor */ \"./src/crossyo/shelves/editor/BaseEditor.js\");\n/* harmony import */ var _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ArrangementEditor extends _BaseEditor__WEBPACK_IMPORTED_MODULE_0__.BaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.shelve_ = new _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.BaseShelve(this)\r\n\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n }\r\n\r\n endLoadSpecs() {\r\n // super.endLoadSpecs() // 不执行 viewer 的 endLoadSpecs\r\n this.after_add_shelf__()\r\n\r\n this.picker_.on('downPick', e => {\r\n // console.log('downPick', e)\r\n // if (!this.control_.enabled) {\r\n // return\r\n // }\r\n if (e.int0) {\r\n let object = e.int0.object\r\n let hit_ = object.hit_\r\n // if (hit_.type == 'shelf') {\r\n // // this.control_trans__.detach()\r\n // this.control_trans__.attach(this.mesh_shelf__)\r\n // } \r\n if (hit_.type == 'box') {\r\n // this.control_trans__.detach()\r\n\r\n this.active_selected_(object)\r\n\r\n this.emit('arrange.selectCell', hit_.cell)\r\n //\r\n\r\n // } else if (hit_.type == 'commodity') {\r\n // this.control_trans__.attach(object)\r\n }\r\n\r\n } else {\r\n this.active_selected_(null)\r\n this.control_trans__.detach()\r\n }\r\n })\r\n\r\n this.control_trans__ = new three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_2__.TransformControls(this.camera_, this.renderer_.domElement)\r\n // this.control_trans__.addEventListener('change', )\r\n this.control_trans__.addEventListener('dragging-changed', e => {\r\n this.controls_.enabled = !e.value\r\n })\r\n this.control_trans__.addEventListener('objectChange', e => {\r\n // console.log(e, e.target)\r\n let obj = this.control_trans__.object\r\n // if (obj == this.mesh_shelf__) {\r\n // this.shopData_.scene = {\r\n // shelf: to_transform(obj)\r\n // }\r\n // }\r\n })\r\n this.scene_.add(this.control_trans__)\r\n\r\n // console.log(this.shopData_) // 實際上是 arrangement data!\r\n {\r\n let shelf = this.shopData_.shelf\r\n if (shelf) {\r\n let cells = shelf.cells\r\n if (cells) {\r\n cells.filter(cell => (cell && cell.pileWare)).reduce(\r\n (p, cell) => p.then(() => this.shelve_.addWareToCell(cell.pileWare, cell)),\r\n Promise.resolve()\r\n ).then(() => {\r\n this.emit('loadingCompletion')\r\n })\r\n return\r\n }\r\n }\r\n }\r\n\r\n this.emit('loadingCompletion')\r\n\r\n }\r\n\r\n updateAction(action) {\r\n\r\n // console.log('# updateAction', action)\r\n\r\n if (action.action == 'bindCellWare') {\r\n\r\n console.log('bindCellWare', action)\r\n\r\n this.shelve_.addWareToCell(action.ware, action.cell)\r\n\r\n } else if (action.action == 'unbindCellWare') {\r\n\r\n this.shelve_.removeWareFromCell(action.cell)\r\n\r\n action.cell.pileWare = null\r\n\r\n } else if (action.action == 'updateCellPileNumber') {\r\n\r\n this.shelve_.update_cell_pileNumber_(action.cell)\r\n\r\n } else if (action.action == 'updateCellPileRotationY') {\r\n\r\n this.shelve_.update_cell_pileRotationY_(action.cell)\r\n\r\n }\r\n\r\n }\r\n\r\n after_add_shelf__() {\r\n\r\n this.picker_.emptyHits()\r\n\r\n if (this.mesh_shelf__) {\r\n\r\n // let o3d = this.mesh_shelf__\r\n // let hit_ = { type: 'shelf' }\r\n // // console.log('add_hit__', o3d)\r\n // o3d.traverse(c => {\r\n // if (c.isMesh) {\r\n // if (/^box-\\d-\\d/.test(c.name)) {\r\n // } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n // } else if (/.*-shadow$/.test(c.name)) {\r\n // } else {\r\n // c.hit_ = hit_\r\n // this.picker_.pushHit(c)\r\n // }\r\n // }\r\n // })\r\n\r\n // cells\r\n this.shopData_.shelf.cells.forEach(cell => {\r\n\r\n let box = cell.box\r\n // console.log(cell)\r\n let mesh_box = this.prefab__.clone_cell_box()\r\n mesh_box.position.set(box.position.x, box.position.y, box.position.z)\r\n mesh_box.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n mesh_box.scale.set(box.size.x, box.size.y, box.size.z)\r\n let mat = new three__WEBPACK_IMPORTED_MODULE_3__.MeshStandardMaterial({\r\n transparent: true,\r\n opacity: .45,\r\n // visible: false,\r\n side: three__WEBPACK_IMPORTED_MODULE_3__.BackSide,\r\n })\r\n\r\n mesh_box.material = mat\r\n this.mesh_shelf__.add(mesh_box)\r\n\r\n mesh_box.hit_ = { type: 'box', cell }\r\n this.picker_.pushHit(mesh_box)\r\n\r\n })\r\n\r\n }\r\n\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n this.shelve_.dispose()\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ArrangementEditor.js?");
/***/ }),
@@ -443,7 +443,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseEditor\": () => (/* binding */ BaseEditor)\n/* harmony export */ });\n/* harmony import */ var _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../viewer/ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _common_prefab__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/prefab */ \"./src/crossyo/shelves/common/prefab.js\");\n/* harmony import */ var kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/util/SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nclass BaseEditor extends _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__.ShelvesBaseViewer {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.use_grid__ = true\r\n this.isViewer__ = false\r\n\r\n this.active_selected_o3d__ = null\r\n\r\n // this.active_selected_box__.visible = false\r\n }\r\n\r\n beginLoadSpecs() {\r\n let arr = super.beginLoadSpecs()\r\n arr.push({\r\n func: 'setupCustomization', param: {\r\n onDoing: next => {\r\n this.prefab__ = _common_prefab__WEBPACK_IMPORTED_MODULE_1__.prefab.setup(next)\r\n }\r\n }\r\n })\r\n return arr\r\n }\r\n\r\n active_selected_(o3d) {\r\n\r\n if (!this.active_selected_box__) {\r\n this.active_selected_box__ = new three__WEBPACK_IMPORTED_MODULE_3__.Object3D()\r\n this.active_selected_box__.add(new three__WEBPACK_IMPORTED_MODULE_3__.Box3Helper(new three__WEBPACK_IMPORTED_MODULE_3__.Box3()))\r\n this.scene_.add(this.active_selected_box__)\r\n }\r\n\r\n // console.log('active_selected_', o3d)\r\n\r\n this.active_selected_o3d__ = o3d\r\n if (o3d) {\r\n this.active_selected_box__.visible = true\r\n\r\n // { // global \r\n // let box = new Box3().expandByObject(o3d)\r\n // this.active_selected_box__.box = box\r\n // this.active_selected_box__.updateMatrixWorld(true)\r\n // }\r\n\r\n { // local, #20220620\r\n let box = (0,kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_2__.local_box3)(o3d)\r\n if (box) {\r\n this.active_selected_box__.children[0].box = box\r\n o3d.updateWorldMatrix(true, false)\r\n o3d.matrixWorld.decompose(\r\n this.active_selected_box__.position,\r\n this.active_selected_box__.quaternion,\r\n this.active_selected_box__.scale\r\n )\r\n }\r\n }\r\n\r\n\r\n } else {\r\n this.active_selected_box__.visible = false\r\n }\r\n\r\n }\r\n\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/BaseEditor.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BaseEditor\": () => (/* binding */ BaseEditor)\n/* harmony export */ });\n/* harmony import */ var _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../viewer/ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _common_prefab__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/prefab */ \"./src/crossyo/shelves/common/prefab.js\");\n/* harmony import */ var kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi/util/SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nclass BaseEditor extends _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__.ShelvesBaseViewer {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.use_grid__ = true\r\n this.isViewer__ = false\r\n\r\n this.active_selected_o3d__ = null\r\n\r\n // this.active_selected_box__.visible = false\r\n }\r\n\r\n beginLoadSpecs() {\r\n let arr = super.beginLoadSpecs()\r\n arr.push({\r\n func: 'setupCustomization', param: {\r\n onDoing: next => {\r\n this.prefab__ = _common_prefab__WEBPACK_IMPORTED_MODULE_1__.prefab.setup(next)\r\n }\r\n }\r\n })\r\n return arr\r\n }\r\n\r\n active_selected_(o3d) {\r\n\r\n if (!this.active_selected_box__) {\r\n this.active_selected_box__ = new three__WEBPACK_IMPORTED_MODULE_3__.Object3D()\r\n this.active_selected_box__.add(new three__WEBPACK_IMPORTED_MODULE_3__.Box3Helper(new three__WEBPACK_IMPORTED_MODULE_3__.Box3()))\r\n this.scene_.add(this.active_selected_box__)\r\n }\r\n\r\n // console.log('active_selected_', o3d)\r\n\r\n this.active_selected_o3d__ = o3d\r\n if (o3d) {\r\n this.active_selected_box__.visible = true\r\n\r\n // { // global \r\n // let box = new Box3().expandByObject(o3d)\r\n // this.active_selected_box__.box = box\r\n // this.active_selected_box__.updateMatrixWorld(true)\r\n // }\r\n\r\n { // local, #20220620\r\n let box = (0,kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_2__.local_box3)(o3d)\r\n if (box) {\r\n this.active_selected_box__.children[0].box = box\r\n o3d.updateWorldMatrix(true, false)\r\n o3d.matrixWorld.decompose(\r\n this.active_selected_box__.position,\r\n this.active_selected_box__.quaternion,\r\n this.active_selected_box__.scale\r\n )\r\n }\r\n }\r\n\r\n\r\n } else {\r\n this.active_selected_box__.visible = false\r\n }\r\n\r\n }\r\n\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/BaseEditor.js?");
/***/ }),
@@ -454,7 +454,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShopEditor\": () => (/* binding */ ShopEditor)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three/examples/jsm/controls/TransformControls */ \"./node_modules/_three@0.139.2@three/examples/jsm/controls/TransformControls.js\");\n/* harmony import */ var _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../common/util */ \"./src/crossyo/shelves/common/util.js\");\n/* harmony import */ var _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ViewModeBaseEditor */ \"./src/crossyo/shelves/editor/ViewModeBaseEditor.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst DEBUG = false // true\r\n\r\nconst trans_axes_ = (trans, arr) => {\r\n trans.showX = arr[0]\r\n trans.showY = arr[1]\r\n trans.showZ = arr[2]\r\n}\r\n\r\nconst axes_def_ = {\r\n 'translate-shelf': trans => { trans_axes_(trans, [true, false, true]) },\r\n 'translate-box': trans => { trans_axes_(trans, [true, true, true]) },\r\n 'translate-sign': trans => { trans_axes_(trans, [true, true, true]) },\r\n 'translate-logo': trans => { trans_axes_(trans, [true, true, true]) },\r\n\r\n 'rotate-shelf': trans => { trans_axes_(trans, [false, true, false]) },\r\n 'rotate-box': trans => { trans_axes_(trans, [false, true, false]) },\r\n 'rotate-sign': trans => { trans_axes_(trans, [false, true, false]) },\r\n\r\n // resize\r\n 'scale-box': trans => { trans_axes_(trans, [true, true, true]) },\r\n}\r\n\r\nconst update_control_trans_axes__ = trans => {\r\n let mode = trans.mode\r\n let obj = trans.object\r\n let obj_type = ''\r\n if (obj.hit_) {\r\n obj_type = obj.hit_.type\r\n } else if (obj.grp_hit_cell_) {\r\n obj_type = 'box'\r\n } else if (obj.name == 'shelf__') {\r\n obj_type = 'shelf'\r\n }\r\n let key = `${mode}-${obj_type}`\r\n // console.log(key)\r\n let f = axes_def_[key]\r\n if (f) {\r\n f(trans)\r\n }\r\n\r\n if (obj_type == 'box') {\r\n if (mode == 'scale') {\r\n // console.log('scale-box', obj)\r\n if (obj.grp_hit_cell_) {\r\n let box = obj.children.filter(c => c.hit_ && c.hit_.type == 'box')[0]\r\n if (box) {\r\n trans.attach(box)\r\n }\r\n }\r\n } else {\r\n if (!obj.grp_hit_cell_ && obj.parent.grp_hit_cell_) {\r\n trans.attach(obj.parent)\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\n\r\nclass ShopEditor extends _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.ViewModeBaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n }\r\n\r\n endLoadSpecs() {\r\n // super.endLoadSpecs() // 不执行 viewer 的 endLoadSpecs\r\n\r\n this.create_cms_()\r\n\r\n this.after_add_shelf__()\r\n\r\n this.picker_.on('downPick', e => {\r\n // console.log('downPick', e)\r\n // if (!this.control_.enabled) {\r\n // return\r\n // }\r\n\r\n // console.log(this.control_trans__.axis)\r\n if (this.control_trans__.axis) { // control trans 优先级更高\r\n return\r\n }\r\n\r\n if (e.int0) {\r\n let object = e.int0.object\r\n let hit_ = object.hit_\r\n if (hit_.type == 'shelf') {\r\n // this.control_trans__.detach()\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(this.mesh_shelf__)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n if (DEBUG) {\r\n this.active_selected_(object)\r\n }\r\n\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.ORBIT) {\r\n this.orbit_update_for_(object)\r\n }\r\n\r\n this.shopData_.ext__.selectedShelf = true\r\n this.shopData_.ext__.selectedCell = null\r\n\r\n } else if (hit_.type == 'box'\r\n || hit_.type == 'sign'\r\n || hit_.type == 'logo'\r\n ) {\r\n // this.control_trans__.detach()\r\n this.control_trans__.showY = true\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(object)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n\r\n this.control_trans__.mode = 'translate'\r\n if (hit_.type == 'box') {\r\n this.control_trans__.attach(object.parent) // grp cell\r\n } else {\r\n this.control_trans__.attach(object)\r\n }\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n }\r\n\r\n if (DEBUG) {\r\n this.active_selected_(object)\r\n }\r\n\r\n // console.log(hit_)\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = hit_.cell\r\n this.shopData_.ext__.selectedCellSubName = hit_.type\r\n\r\n // this.changeViewMode(VIEW_MODE.ORBIT)\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.ORBIT) {\r\n if (hit_.type == 'box') {\r\n this.orbit_update_for_(object)\r\n } else {\r\n this.orbit_update_for_(object.parent)\r\n }\r\n }\r\n\r\n }\r\n\r\n } else {\r\n\r\n if (DEBUG) {\r\n this.active_selected_(null)\r\n }\r\n\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // this.changeViewMode(VIEW_MODE.PANORAMA)\r\n\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = null\r\n\r\n }\r\n\r\n\r\n })\r\n\r\n this.control_trans__ = new three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_0__.TransformControls(this.camera_, this.renderer_.domElement)\r\n // console.log(this.control_trans__)\r\n this.control_trans__.space = 'local'\r\n\r\n // this.control_trans__.addEventListener('change', )\r\n this.control_trans__.addEventListener('dragging-changed', e => {\r\n this.controls_.enabled = !e.value\r\n })\r\n this.control_trans__.addEventListener('objectChange', e => {\r\n // console.log(e, e.target)\r\n let obj = this.control_trans__.object\r\n if (obj == this.mesh_shelf__) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform)(obj, this.shopData_.shelf)\r\n } else if (obj.grp_hit_cell_) { // group (translate, rotate)\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_box_inherited)(obj, obj.grp_hit_cell_.box)\r\n } else {\r\n let hit_ = obj.hit_\r\n if (hit_) {\r\n if (hit_.type == 'box') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_box)(obj, hit_.cell.box)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) { // \r\n\r\n // group / box mesh (scale) -> resize\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_box_inherited)(obj, obj.parent.grp_hit_cell_.box)\r\n\r\n }\r\n } else if (hit_.type == 'sign') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_sign)(obj, hit_.cell.sign)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_sign)(obj, hit_.cell.box.child.sign)\r\n }\r\n } else if (hit_.type == 'logo') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_logo)(obj, hit_.cell.logo)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform_cell_logo)(obj, hit_.cell.box.child.logo)\r\n }\r\n }\r\n }\r\n }\r\n })\r\n this.scene_.add(this.control_trans__)\r\n\r\n // this.control_trans__.showY = false\r\n\r\n {\r\n this.keydown_615__ = event => {\r\n // console.log(event)\r\n if (event.keyCode == 27) {\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA)\r\n this.control_trans__.detach()\r\n }\r\n }\r\n window.addEventListener('keydown', this.keydown_615__)\r\n }\r\n\r\n\r\n this.emit('loadingCompletion')\r\n }\r\n\r\n changeViewMode(mode, changeByIndirectReason = false) {\r\n this.changeViewMode_(mode, changeByIndirectReason, () => {\r\n if (mode == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA) {\r\n // this.controls_.object.position.set(0, 0, 0)\r\n // this.controls_.target = this.DEFAULT_TARGET__\r\n this.controls_.reset()\r\n\r\n } else if (mode == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.ORBIT) {\r\n this.controls_.target = this.DEFAULT_TARGET__\r\n if (this.control_trans__ && this.control_trans__.object) {\r\n this.orbit_update_for_(this.control_trans__.object, true)\r\n } else {\r\n this.orbit_update_for_(this.mesh_shelf__, true)\r\n }\r\n }\r\n })\r\n }\r\n\r\n updateAction(action) {\r\n\r\n // console.log('# updateAction', action)\r\n\r\n if (action.action == 'updatePanorama') {\r\n // console.log('## updatePanorama', this.shopData_)\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA, true)\r\n\r\n let tex = this.scene_.environment\r\n if (tex) {\r\n // this.scene_.background = new Color(0xeeeeee)\r\n\r\n // this.scene_.children.filter(c=>c.name == 'sys-env-sphere-')[0].removeFromParent()\r\n this.mesh_env_sphere__.removeFromParent()\r\n this.mesh_env_sphere__ = null\r\n\r\n this.scene_.environment = null\r\n tex.dispose()\r\n }\r\n\r\n if (this.shopData_.panorama) {\r\n\r\n let panorama_shelf_exr = this.shopData_.panorama.urlShelfExr\r\n let arr = [{\r\n func: 'setupEnvEquirect', param: {\r\n url: `${this.get_panorama_url_(this.shopData_.panorama)}`,\r\n onAfter: tex => {\r\n // this.scene_.background = tex\r\n\r\n let sp = new three__WEBPACK_IMPORTED_MODULE_4__.Mesh(\r\n this.geo_env_sphere__,\r\n new three__WEBPACK_IMPORTED_MODULE_4__.MeshStandardMaterial({\r\n map: tex,\r\n side: three__WEBPACK_IMPORTED_MODULE_4__.BackSide,\r\n // wireframe: true,\r\n fog: false,\r\n // displacementScale: -env_.radius * .992,\r\n // displacementMap: new TextureLoader().load(`${this.prefixAsset_}/env/equirect/${env_.code}-zdepth-1k.png`),\r\n envMap: this.w256_,\r\n // envMapIntensity: 2,\r\n })\r\n )\r\n sp.scale.set(1, 1, -1)\r\n sp.name = 'sys-env-sphere-'\r\n this.scene_.add(sp)\r\n\r\n this.mesh_env_sphere__ = sp\r\n this.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n\r\n if (!panorama_shelf_exr) {\r\n this.scene_.environment = tex\r\n }\r\n\r\n }\r\n }\r\n }]\r\n\r\n if (panorama_shelf_exr) {\r\n arr.push({\r\n func: 'setupEnvEquirect', param: {\r\n url: `${panorama_shelf_exr}`,\r\n onAfter: tex => {\r\n this.scene_.environment = tex\r\n }\r\n }\r\n })\r\n }\r\n\r\n this.build_specs__(arr).then(() => {\r\n //\r\n })\r\n\r\n } else {\r\n // remove!\r\n }\r\n } else if (action.action == 'updatePanoramaRotationY') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA, true)\r\n\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n }\r\n } else if (action.action == 'updatePanoramaMultiply') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA, true)\r\n\r\n\r\n } else if (action.action == 'updateShelf') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.PANORAMA, true)\r\n\r\n // remove!\r\n if (this.mesh_shelf__) {\r\n\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // \r\n\r\n // TODO dispose!\r\n\r\n this.mesh_shelf__.removeFromParent()\r\n this.mesh_shelf__ = null\r\n\r\n }\r\n\r\n if (this.shopData_.shelf && this.shopData_.shelf.url) {\r\n\r\n let shelf_url = this.shopData_.shelf.url\r\n this.build_specs__([{\r\n func: 'setupModelGltf', param: {\r\n path: shelf_url.substr(0, shelf_url.lastIndexOf('/')),\r\n name: shelf_url.substr(shelf_url.lastIndexOf('/')),\r\n onAfter: o3d => {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (c.material.aoMap) {\r\n c.material.lightMap = c.material.aoMap\r\n // c.material.aoMap = null\r\n c.material.lightMapIntensity = .5\r\n }\r\n c.material.side = three__WEBPACK_IMPORTED_MODULE_4__.FrontSide\r\n }\r\n // 兼容 v1\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n c.visible = false\r\n }\r\n })\r\n\r\n o3d.rotation.set(0, - Math.PI / 2, 0)\r\n o3d.position.set(2.7, -1, 0)\r\n\r\n this.scene_.add(o3d)\r\n\r\n this.mesh_shelf__ = o3d\r\n\r\n // .$model__ = o3d\r\n // this.shopData_.shelf.get_model__ = () => {\r\n // return o3d\r\n // }\r\n\r\n // this.control_trans__.detach()\r\n\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(this.mesh_shelf__)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n // { // TEMP for v1 to v3, 解些老的数据,并且生成新的cells数据,copy to store/shelves 列表中\r\n // this.shopData_.shelf.cells = parse_v3_cells_from_v1_shelf_model_(o3d)\r\n // }\r\n\r\n this.after_add_shelf__()\r\n\r\n ;(0,_common_util__WEBPACK_IMPORTED_MODULE_2__.write_transform)(o3d, this.shopData_.shelf)\r\n\r\n }\r\n }\r\n }])\r\n\r\n } else {\r\n\r\n // remove\r\n this.control_trans__.detach()\r\n\r\n }\r\n\r\n } else if (action.action == 'deleteCell') {\r\n\r\n // console.log('delete cell', action)\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // c.hit_.type == 'box'\r\n // this.mesh_shelf__.children.filter(c => (c.hit_ && c.hit_.cell == action.cell)).forEach(c => {\r\n // // let removed = \r\n // this.picker_.spliceHit(c)\r\n // // console.log('removed', removed)\r\n // c.removeFromParent()\r\n // })\r\n\r\n let subs = action.cell.getSubs()\r\n if (subs.sign) {\r\n this.picker_.spliceHit(subs.sign)\r\n subs.sign.removeFromParent()\r\n }\r\n if (subs.logo) {\r\n this.picker_.spliceHit(subs.logo)\r\n subs.logo.removeFromParent()\r\n }\r\n this.picker_.spliceHit(subs.box)\r\n subs.box.removeFromParent()\r\n\r\n this.shopData_.shelf.cells.splice(action.idx, 1)\r\n\r\n } else if (action.action == 'addCell') {\r\n\r\n if (!this.mesh_shelf__) {\r\n console.warn('需要首先有个货架!')\r\n return\r\n }\r\n\r\n // console.log('add cell')\r\n\r\n let bbx = new three__WEBPACK_IMPORTED_MODULE_4__.Box3().expandByObject(this.mesh_shelf__)\r\n let cnt = bbx.getCenter(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3())\r\n let size = bbx.getSize(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3())\r\n\r\n // this.mesh_shelf__.add()\r\n let spos = this.mesh_shelf__.position\r\n // console.log(cnt, size, spos)\r\n\r\n let cell = {\r\n name: '?-?',\r\n box: {\r\n // x 向前一些\r\n position: { x: 0, y: cnt.y + size.y / 2 - spos.y, z: .45 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n size: { x: .3736, y: .2259, z: .2179 },\r\n // child: {}\r\n },\r\n }\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n // 没有测过,有问题,目前也不用到!\r\n // cell.sign = { // 相对于 box的位置\r\n // position: { x: 1, y: 1, z: 1 },\r\n // scale: { x: 1, y: 1, z: 1 },\r\n // rotation: { x: 0, y: 0, z: 0 },\r\n // }\r\n // cell.logo = { // 相对于 box的位置\r\n // position: { x: 1, y: 1, z: 1 }\r\n // }\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n cell.box.child = {\r\n sign: {\r\n position: { x: -0.006, y: -0.064, z: 0.1847 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n },\r\n logo: {\r\n position: { x: 0, y: 0.15, z: 0 }\r\n }\r\n }\r\n }\r\n\r\n this.shopData_.shelf.cells.push(cell)\r\n\r\n this.add_cell__(this.shopData_.shelf.cells[this.shopData_.shelf.cells.length - 1]) // 从proxy数据中取出!\r\n\r\n } else if (action.action == 'selectCell') {\r\n\r\n // console.log('select cell', action) // cell, subName\r\n\r\n let cell = action.cell\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = cell\r\n this.shopData_.ext__.selectedCellSubName = action.subName\r\n let subs = cell.getSubs()\r\n\r\n this.control_trans__.mode = 'translate'\r\n if (action.subName == 'box') {\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n this.control_trans__.attach(subs.box)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n this.control_trans__.attach(subs.box.parent)\r\n }\r\n\r\n } else if (action.subName == 'sign') {\r\n if (subs.sign) {\r\n this.control_trans__.attach(subs.sign)\r\n }\r\n } else if (action.subName == 'logo') {\r\n if (subs.logo) {\r\n this.control_trans__.attach(subs.logo)\r\n }\r\n }\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n // this.changeViewMode(VIEW_MODE.ORBIT)\r\n\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_3__.VIEW_MODE.ORBIT) {\r\n if (action.subName == 'box') {\r\n this.orbit_update_for_(subs.box)\r\n } else if (action.subName == 'sign') {\r\n this.orbit_update_for_(subs.sign)\r\n } else if (action.subName == 'logo') {\r\n this.orbit_update_for_(subs.logo)\r\n }\r\n }\r\n\r\n } else if (action.action == 'transformTranslate') {\r\n // console.log('xx transformTranslate')\r\n this.control_trans__.mode = 'translate'\r\n update_control_trans_axes__(this.control_trans__)\r\n } else if (action.action == 'transformRotate') {\r\n // console.log('xx transformRotate')\r\n this.control_trans__.mode = 'rotate'\r\n update_control_trans_axes__(this.control_trans__)\r\n } else if (action.action == 'transformResize') {\r\n // console.log('xx transformResize')\r\n this.control_trans__.mode = 'scale'\r\n update_control_trans_axes__(this.control_trans__)\r\n }\r\n }\r\n\r\n\r\n after_add_shelf__() {\r\n\r\n this.picker_.emptyHits()\r\n\r\n if (this.mesh_shelf__) {\r\n\r\n let o3d = this.mesh_shelf__\r\n let hit_ = { type: 'shelf' }\r\n // console.log('add_hit__', o3d)\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n } else if (/.*-shadow$/.test(c.name)) {\r\n } else {\r\n c.hit_ = hit_\r\n this.picker_.pushHit(c)\r\n }\r\n }\r\n })\r\n\r\n // cells\r\n if (!this.shopData_.shelf.cells) {\r\n console.warn('# after add shelf cells null, maybe error runtime path!')\r\n this.shopData_.shelf.cells = []\r\n }\r\n this.shopData_.shelf.cells.forEach(cell => {\r\n this.add_cell__(cell)\r\n })\r\n\r\n }\r\n\r\n }\r\n\r\n add_cell__(cell) {\r\n\r\n let box = cell.box\r\n // console.log('add_cell__', cell)\r\n\r\n let grp_cell = new three__WEBPACK_IMPORTED_MODULE_4__.Object3D()\r\n grp_cell.grp_hit_cell_ = cell\r\n grp_cell.position.set(box.position.x, box.position.y, box.position.z)\r\n grp_cell.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n this.mesh_shelf__.add(grp_cell)\r\n\r\n let mesh_box = this.prefab__.clone_cell_box()\r\n // mesh_box.position.set(box.position.x, box.position.y, box.position.z)\r\n mesh_box.scale.set(box.size.x, box.size.y, box.size.z)\r\n\r\n // this.mesh_shelf__.add(mesh_box)\r\n\r\n grp_cell.add(mesh_box)\r\n\r\n mesh_box.hit_ = { type: 'box', cell }\r\n this.picker_.pushHit(mesh_box)\r\n\r\n let mesh_sign = null\r\n let mesh_logo = null\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.STANDALONE) {\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_1__.HIERARCHY_TYPE.INHERITED) {\r\n {\r\n let sign = box.child.sign\r\n\r\n mesh_sign = this.prefab__.clone_sign()\r\n mesh_sign.position.set(sign.position.x, sign.position.y, sign.position.z)\r\n // console.log(JSON.stringify(sign.rotation))\r\n mesh_sign.rotation.set(sign.rotation.x, sign.rotation.y, sign.rotation.z)\r\n grp_cell.add(mesh_sign)\r\n\r\n mesh_sign.hit_ = { type: 'sign', cell }\r\n this.picker_.pushHit(mesh_sign)\r\n }\r\n //\r\n {\r\n let logo = box.child.logo\r\n\r\n // mesh_logo = new Mesh(new BoxBufferGeometry(.1, .04, .005), this.get_plastic_logo_material__())\r\n mesh_logo = this.prefab__.clone_logo()\r\n mesh_logo.position.set(logo.position.x, logo.position.y, logo.position.z)\r\n grp_cell.add(mesh_logo)\r\n\r\n mesh_logo.hit_ = { type: 'logo', cell }\r\n this.picker_.pushHit(mesh_logo)\r\n }\r\n }\r\n\r\n cell.getSubs = function () {\r\n return {\r\n box: mesh_box,\r\n sign: mesh_sign,\r\n logo: mesh_logo,\r\n }\r\n }\r\n\r\n }\r\n\r\n commitToShopData() {\r\n // console.log('commitToShopData...')\r\n // if (this.mesh_shelf__) {\r\n // this.shopData_.scene = {\r\n // shelf: {\r\n // position: this.mesh_shelf__.position,\r\n // rotation: {\r\n // x: this.mesh_shelf__.rotation.x,\r\n // y: this.mesh_shelf__.rotation.y,\r\n // z: this.mesh_shelf__.rotation.z\r\n // },\r\n // }\r\n // }\r\n // }\r\n }\r\n\r\n dispose() {\r\n window.removeEventListener('keydown', this.keydown_615__)\r\n super.dispose()\r\n }\r\n\r\n\r\n}\r\n\r\nconst SHELF_POSITION = { x: 2.7, y: -1, z: 0 }\r\nconst SHELF_ROTATION = { x: 0, y: - Math.PI / 2, z: 0 }\r\nconst SHELF_SCALE = { x: 1, y: 1, z: 1 }\r\n\r\n// 从外部选择时添加默认值\r\nShopEditor.appendDefaultShelfData = shelf => {\r\n shelf.position = SHELF_POSITION\r\n shelf.rotation = SHELF_ROTATION\r\n shelf.scale = SHELF_SCALE\r\n return shelf\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ShopEditor.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShopEditor\": () => (/* binding */ ShopEditor)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/controls/TransformControls */ \"./node_modules/_three@0.146.0@three/examples/jsm/controls/TransformControls.js\");\n/* harmony import */ var _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../common/BaseShelve */ \"./src/crossyo/shelves/common/BaseShelve.js\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/util */ \"./src/crossyo/shelves/common/util.js\");\n/* harmony import */ var _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ViewModeBaseEditor */ \"./src/crossyo/shelves/editor/ViewModeBaseEditor.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst DEBUG = false // true\r\n\r\nconst trans_axes_ = (trans, arr) => {\r\n trans.showX = arr[0]\r\n trans.showY = arr[1]\r\n trans.showZ = arr[2]\r\n}\r\n\r\nconst axes_def_ = {\r\n 'translate-shelf': trans => { trans_axes_(trans, [true, false, true]) },\r\n 'translate-box': trans => { trans_axes_(trans, [true, true, true]) },\r\n 'translate-sign': trans => { trans_axes_(trans, [true, true, true]) },\r\n 'translate-logo': trans => { trans_axes_(trans, [true, true, true]) },\r\n\r\n 'rotate-shelf': trans => { trans_axes_(trans, [false, true, false]) },\r\n 'rotate-box': trans => { trans_axes_(trans, [false, true, false]) },\r\n 'rotate-sign': trans => { trans_axes_(trans, [false, true, false]) },\r\n\r\n // resize\r\n 'scale-box': trans => { trans_axes_(trans, [true, true, true]) },\r\n}\r\n\r\nconst update_control_trans_axes__ = trans => {\r\n let mode = trans.mode\r\n let obj = trans.object\r\n let obj_type = ''\r\n if (obj.hit_) {\r\n obj_type = obj.hit_.type\r\n } else if (obj.grp_hit_cell_) {\r\n obj_type = 'box'\r\n } else if (obj.name == 'shelf__') {\r\n obj_type = 'shelf'\r\n }\r\n let key = `${mode}-${obj_type}`\r\n // console.log(key)\r\n let f = axes_def_[key]\r\n if (f) {\r\n f(trans)\r\n }\r\n\r\n if (obj_type == 'box') {\r\n if (mode == 'scale') {\r\n // console.log('scale-box', obj)\r\n if (obj.grp_hit_cell_) {\r\n let box = obj.children.filter(c => c.hit_ && c.hit_.type == 'box')[0]\r\n if (box) {\r\n trans.attach(box)\r\n }\r\n }\r\n } else {\r\n if (!obj.grp_hit_cell_ && obj.parent.grp_hit_cell_) {\r\n trans.attach(obj.parent)\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\n\r\nclass ShopEditor extends _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.ViewModeBaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n }\r\n\r\n endLoadSpecs() {\r\n // super.endLoadSpecs() // 不执行 viewer 的 endLoadSpecs\r\n\r\n this.create_cms_()\r\n\r\n this.after_add_shelf__()\r\n\r\n this.picker_.on('downPick', e => {\r\n // console.log('downPick', e)\r\n // if (!this.control_.enabled) {\r\n // return\r\n // }\r\n\r\n // console.log(this.control_trans__.axis)\r\n if (this.control_trans__.axis) { // control trans 优先级更高\r\n return\r\n }\r\n\r\n if (e.int0) {\r\n let object = e.int0.object\r\n let hit_ = object.hit_\r\n if (hit_.type == 'shelf') {\r\n // this.control_trans__.detach()\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(this.mesh_shelf__)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n if (DEBUG) {\r\n this.active_selected_(object)\r\n }\r\n\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.ORBIT) {\r\n this.orbit_update_for_(object)\r\n }\r\n\r\n this.shopData_.ext__.selectedShelf = true\r\n this.shopData_.ext__.selectedCell = null\r\n\r\n } else if (hit_.type == 'box'\r\n || hit_.type == 'sign'\r\n || hit_.type == 'logo'\r\n ) {\r\n // this.control_trans__.detach()\r\n this.control_trans__.showY = true\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(object)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n\r\n this.control_trans__.mode = 'translate'\r\n if (hit_.type == 'box') {\r\n this.control_trans__.attach(object.parent) // grp cell\r\n } else {\r\n this.control_trans__.attach(object)\r\n }\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n }\r\n\r\n if (DEBUG) {\r\n this.active_selected_(object)\r\n }\r\n\r\n // console.log(hit_)\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = hit_.cell\r\n this.shopData_.ext__.selectedCellSubName = hit_.type\r\n\r\n // this.changeViewMode(VIEW_MODE.ORBIT)\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.ORBIT) {\r\n if (hit_.type == 'box') {\r\n this.orbit_update_for_(object)\r\n } else {\r\n this.orbit_update_for_(object.parent)\r\n }\r\n }\r\n\r\n }\r\n\r\n } else {\r\n\r\n if (DEBUG) {\r\n this.active_selected_(null)\r\n }\r\n\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // this.changeViewMode(VIEW_MODE.PANORAMA)\r\n\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = null\r\n\r\n }\r\n\r\n\r\n })\r\n\r\n this.control_trans__ = new three_examples_jsm_controls_TransformControls__WEBPACK_IMPORTED_MODULE_3__.TransformControls(this.camera_, this.renderer_.domElement)\r\n // console.log(this.control_trans__)\r\n this.control_trans__.space = 'local'\r\n\r\n // this.control_trans__.addEventListener('change', )\r\n this.control_trans__.addEventListener('dragging-changed', e => {\r\n this.controls_.enabled = !e.value\r\n })\r\n this.control_trans__.addEventListener('objectChange', e => {\r\n // console.log(e, e.target)\r\n let obj = this.control_trans__.object\r\n if (obj == this.mesh_shelf__) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform)(obj, this.shopData_.shelf)\r\n } else if (obj.grp_hit_cell_) { // group (translate, rotate)\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_box_inherited)(obj, obj.grp_hit_cell_.box)\r\n } else {\r\n let hit_ = obj.hit_\r\n if (hit_) {\r\n if (hit_.type == 'box') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_box)(obj, hit_.cell.box)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) { // \r\n\r\n // group / box mesh (scale) -> resize\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_box_inherited)(obj, obj.parent.grp_hit_cell_.box)\r\n\r\n }\r\n } else if (hit_.type == 'sign') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_sign)(obj, hit_.cell.sign)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_sign)(obj, hit_.cell.box.child.sign)\r\n }\r\n } else if (hit_.type == 'logo') {\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_logo)(obj, hit_.cell.logo)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n (0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform_cell_logo)(obj, hit_.cell.box.child.logo)\r\n }\r\n }\r\n }\r\n }\r\n })\r\n this.scene_.add(this.control_trans__)\r\n\r\n // this.control_trans__.showY = false\r\n\r\n {\r\n this.keydown_615__ = event => {\r\n // console.log(event)\r\n if (event.keyCode == 27) {\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA)\r\n this.control_trans__.detach()\r\n }\r\n }\r\n window.addEventListener('keydown', this.keydown_615__)\r\n }\r\n\r\n\r\n this.emit('loadingCompletion')\r\n }\r\n\r\n changeViewMode(mode, changeByIndirectReason = false) {\r\n this.changeViewMode_(mode, changeByIndirectReason, () => {\r\n if (mode == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA) {\r\n // this.controls_.object.position.set(0, 0, 0)\r\n // this.controls_.target = this.DEFAULT_TARGET__\r\n this.controls_.reset()\r\n\r\n } else if (mode == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.ORBIT) {\r\n this.controls_.target = this.DEFAULT_TARGET__\r\n if (this.control_trans__ && this.control_trans__.object) {\r\n this.orbit_update_for_(this.control_trans__.object, true)\r\n } else {\r\n this.orbit_update_for_(this.mesh_shelf__, true)\r\n }\r\n }\r\n })\r\n }\r\n\r\n updateAction(action) {\r\n\r\n // console.log('# updateAction', action)\r\n\r\n if (action.action == 'updatePanorama') {\r\n // console.log('## updatePanorama', this.shopData_)\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA, true)\r\n\r\n let tex = this.scene_.environment\r\n if (tex) {\r\n // this.scene_.background = new Color(0xeeeeee)\r\n\r\n // this.scene_.children.filter(c=>c.name == 'sys-env-sphere-')[0].removeFromParent()\r\n this.mesh_env_sphere__.removeFromParent()\r\n this.mesh_env_sphere__ = null\r\n\r\n this.scene_.environment = null\r\n tex.dispose()\r\n }\r\n\r\n if (this.shopData_.panorama) {\r\n\r\n let panorama_shelf_exr = this.shopData_.panorama.urlShelfExr\r\n let arr = [{\r\n func: 'setupEnvEquirect', param: {\r\n url: `${this.get_panorama_url_(this.shopData_.panorama)}`,\r\n onAfter: tex => {\r\n // this.scene_.background = tex\r\n\r\n let sp = new three__WEBPACK_IMPORTED_MODULE_4__.Mesh(\r\n this.geo_env_sphere__,\r\n new three__WEBPACK_IMPORTED_MODULE_4__.MeshStandardMaterial({\r\n map: tex,\r\n side: three__WEBPACK_IMPORTED_MODULE_4__.BackSide,\r\n // wireframe: true,\r\n fog: false,\r\n // displacementScale: -env_.radius * .992,\r\n // displacementMap: new TextureLoader().load(`${this.prefixAsset_}/env/equirect/${env_.code}-zdepth-1k.png`),\r\n envMap: this.w256_,\r\n // envMapIntensity: 2,\r\n })\r\n )\r\n sp.scale.set(1, 1, -1)\r\n sp.name = 'sys-env-sphere-'\r\n this.scene_.add(sp)\r\n\r\n this.mesh_env_sphere__ = sp\r\n this.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n\r\n if (!panorama_shelf_exr) {\r\n this.scene_.environment = tex\r\n }\r\n\r\n }\r\n }\r\n }]\r\n\r\n if (panorama_shelf_exr) {\r\n arr.push({\r\n func: 'setupEnvEquirect', param: {\r\n url: `${panorama_shelf_exr}`,\r\n onAfter: tex => {\r\n this.scene_.environment = tex\r\n }\r\n }\r\n })\r\n }\r\n\r\n this.build_specs__(arr).then(() => {\r\n //\r\n })\r\n\r\n } else {\r\n // remove!\r\n }\r\n } else if (action.action == 'updatePanoramaRotationY') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA, true)\r\n\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n }\r\n } else if (action.action == 'updatePanoramaMultiply') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA, true)\r\n\r\n\r\n } else if (action.action == 'updateShelf') {\r\n\r\n this.changeViewMode(_ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.PANORAMA, true)\r\n\r\n // remove!\r\n if (this.mesh_shelf__) {\r\n\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // \r\n\r\n // TODO dispose!\r\n\r\n this.mesh_shelf__.removeFromParent()\r\n this.mesh_shelf__ = null\r\n\r\n }\r\n\r\n if (this.shopData_.shelf && this.shopData_.shelf.url) {\r\n\r\n let shelf_url = this.shopData_.shelf.url\r\n this.build_specs__([{\r\n func: 'setupModelGltf', param: {\r\n path: shelf_url.substr(0, shelf_url.lastIndexOf('/')),\r\n name: shelf_url.substr(shelf_url.lastIndexOf('/')),\r\n onAfter: o3d => {\r\n\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (c.material.aoMap) {\r\n c.material.lightMap = c.material.aoMap\r\n // c.material.aoMap = null\r\n c.material.lightMapIntensity = .5\r\n }\r\n c.material.side = three__WEBPACK_IMPORTED_MODULE_4__.FrontSide\r\n }\r\n // 兼容 v1\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n c.visible = false\r\n }\r\n })\r\n\r\n o3d.rotation.set(0, - Math.PI / 2, 0)\r\n o3d.position.set(2.7, -1, 0)\r\n\r\n this.scene_.add(o3d)\r\n\r\n this.mesh_shelf__ = o3d\r\n\r\n // .$model__ = o3d\r\n // this.shopData_.shelf.get_model__ = () => {\r\n // return o3d\r\n // }\r\n\r\n // this.control_trans__.detach()\r\n\r\n this.control_trans__.mode = 'translate'\r\n this.control_trans__.attach(this.mesh_shelf__)\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n // { // TEMP for v1 to v3, 解些老的数据,并且生成新的cells数据,copy to store/shelves 列表中\r\n // this.shopData_.shelf.cells = parse_v3_cells_from_v1_shelf_model_(o3d)\r\n // }\r\n\r\n this.after_add_shelf__()\r\n\r\n ;(0,_common_util__WEBPACK_IMPORTED_MODULE_1__.write_transform)(o3d, this.shopData_.shelf)\r\n\r\n }\r\n }\r\n }])\r\n\r\n } else {\r\n\r\n // remove\r\n this.control_trans__.detach()\r\n\r\n }\r\n\r\n } else if (action.action == 'deleteCell') {\r\n\r\n // console.log('delete cell', action)\r\n this.control_trans__.detach()\r\n this.controls_.enabled = true\r\n\r\n // c.hit_.type == 'box'\r\n // this.mesh_shelf__.children.filter(c => (c.hit_ && c.hit_.cell == action.cell)).forEach(c => {\r\n // // let removed = \r\n // this.picker_.spliceHit(c)\r\n // // console.log('removed', removed)\r\n // c.removeFromParent()\r\n // })\r\n\r\n let subs = action.cell.getSubs()\r\n if (subs.sign) {\r\n this.picker_.spliceHit(subs.sign)\r\n subs.sign.removeFromParent()\r\n }\r\n if (subs.logo) {\r\n this.picker_.spliceHit(subs.logo)\r\n subs.logo.removeFromParent()\r\n }\r\n this.picker_.spliceHit(subs.box)\r\n subs.box.removeFromParent()\r\n\r\n this.shopData_.shelf.cells.splice(action.idx, 1)\r\n\r\n } else if (action.action == 'addCell') {\r\n\r\n if (!this.mesh_shelf__) {\r\n console.warn('需要首先有个货架!')\r\n return\r\n }\r\n\r\n // console.log('add cell')\r\n\r\n let bbx = new three__WEBPACK_IMPORTED_MODULE_4__.Box3().expandByObject(this.mesh_shelf__)\r\n let cnt = bbx.getCenter(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3())\r\n let size = bbx.getSize(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3())\r\n\r\n // this.mesh_shelf__.add()\r\n let spos = this.mesh_shelf__.position\r\n // console.log(cnt, size, spos)\r\n\r\n let cell = {\r\n name: '?-?',\r\n box: {\r\n // x 向前一些\r\n position: { x: 0, y: cnt.y + size.y / 2 - spos.y, z: .45 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n size: { x: .3736, y: .2259, z: .2179 },\r\n // child: {}\r\n },\r\n }\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n // 没有测过,有问题,目前也不用到!\r\n // cell.sign = { // 相对于 box的位置\r\n // position: { x: 1, y: 1, z: 1 },\r\n // scale: { x: 1, y: 1, z: 1 },\r\n // rotation: { x: 0, y: 0, z: 0 },\r\n // }\r\n // cell.logo = { // 相对于 box的位置\r\n // position: { x: 1, y: 1, z: 1 }\r\n // }\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n cell.box.child = {\r\n sign: {\r\n position: { x: -0.006, y: -0.064, z: 0.1847 },\r\n rotation: { x: 0, y: 0, z: 0 },\r\n scale: { x: 1, y: 1, z: 1 },\r\n },\r\n logo: {\r\n position: { x: 0, y: 0.15, z: 0 }\r\n }\r\n }\r\n }\r\n\r\n this.shopData_.shelf.cells.push(cell)\r\n\r\n this.add_cell__(this.shopData_.shelf.cells[this.shopData_.shelf.cells.length - 1]) // 从proxy数据中取出!\r\n\r\n } else if (action.action == 'selectCell') {\r\n\r\n // console.log('select cell', action) // cell, subName\r\n\r\n let cell = action.cell\r\n this.shopData_.ext__.selectedShelf = false\r\n this.shopData_.ext__.selectedCell = cell\r\n this.shopData_.ext__.selectedCellSubName = action.subName\r\n let subs = cell.getSubs()\r\n\r\n this.control_trans__.mode = 'translate'\r\n if (action.subName == 'box') {\r\n\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n this.control_trans__.attach(subs.box)\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n this.control_trans__.attach(subs.box.parent)\r\n }\r\n\r\n } else if (action.subName == 'sign') {\r\n if (subs.sign) {\r\n this.control_trans__.attach(subs.sign)\r\n }\r\n } else if (action.subName == 'logo') {\r\n if (subs.logo) {\r\n this.control_trans__.attach(subs.logo)\r\n }\r\n }\r\n update_control_trans_axes__(this.control_trans__)\r\n\r\n // this.changeViewMode(VIEW_MODE.ORBIT)\r\n\r\n if (this.viewMode__ == _ViewModeBaseEditor__WEBPACK_IMPORTED_MODULE_2__.VIEW_MODE.ORBIT) {\r\n if (action.subName == 'box') {\r\n this.orbit_update_for_(subs.box)\r\n } else if (action.subName == 'sign') {\r\n this.orbit_update_for_(subs.sign)\r\n } else if (action.subName == 'logo') {\r\n this.orbit_update_for_(subs.logo)\r\n }\r\n }\r\n\r\n } else if (action.action == 'transformTranslate') {\r\n // console.log('xx transformTranslate')\r\n this.control_trans__.mode = 'translate'\r\n update_control_trans_axes__(this.control_trans__)\r\n } else if (action.action == 'transformRotate') {\r\n // console.log('xx transformRotate')\r\n this.control_trans__.mode = 'rotate'\r\n update_control_trans_axes__(this.control_trans__)\r\n } else if (action.action == 'transformResize') {\r\n // console.log('xx transformResize')\r\n this.control_trans__.mode = 'scale'\r\n update_control_trans_axes__(this.control_trans__)\r\n }\r\n }\r\n\r\n\r\n after_add_shelf__() {\r\n\r\n this.picker_.emptyHits()\r\n\r\n if (this.mesh_shelf__) {\r\n\r\n let o3d = this.mesh_shelf__\r\n let hit_ = { type: 'shelf' }\r\n // console.log('add_hit__', o3d)\r\n o3d.traverse(c => {\r\n if (c.isMesh) {\r\n if (/^box-\\d-\\d/.test(c.name)) {\r\n } else if (/^sign-\\d-\\d/.test(c.name)) {\r\n } else if (/.*-shadow$/.test(c.name)) {\r\n } else {\r\n c.hit_ = hit_\r\n this.picker_.pushHit(c)\r\n }\r\n }\r\n })\r\n\r\n // cells\r\n if (!this.shopData_.shelf.cells) {\r\n console.warn('# after add shelf cells null, maybe error runtime path!')\r\n this.shopData_.shelf.cells = []\r\n }\r\n this.shopData_.shelf.cells.forEach(cell => {\r\n this.add_cell__(cell)\r\n })\r\n\r\n }\r\n\r\n }\r\n\r\n add_cell__(cell) {\r\n\r\n let box = cell.box\r\n // console.log('add_cell__', cell)\r\n\r\n let grp_cell = new three__WEBPACK_IMPORTED_MODULE_4__.Object3D()\r\n grp_cell.grp_hit_cell_ = cell\r\n grp_cell.position.set(box.position.x, box.position.y, box.position.z)\r\n grp_cell.rotation.set(box.rotation.x, box.rotation.y, box.rotation.z)\r\n this.mesh_shelf__.add(grp_cell)\r\n\r\n let mesh_box = this.prefab__.clone_cell_box()\r\n // mesh_box.position.set(box.position.x, box.position.y, box.position.z)\r\n mesh_box.scale.set(box.size.x, box.size.y, box.size.z)\r\n\r\n // this.mesh_shelf__.add(mesh_box)\r\n\r\n grp_cell.add(mesh_box)\r\n\r\n mesh_box.hit_ = { type: 'box', cell }\r\n this.picker_.pushHit(mesh_box)\r\n\r\n let mesh_sign = null\r\n let mesh_logo = null\r\n if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.STANDALONE) {\r\n } else if (_common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.CELL_HIERARCHY == _common_BaseShelve__WEBPACK_IMPORTED_MODULE_0__.HIERARCHY_TYPE.INHERITED) {\r\n {\r\n let sign = box.child.sign\r\n\r\n mesh_sign = this.prefab__.clone_sign()\r\n mesh_sign.position.set(sign.position.x, sign.position.y, sign.position.z)\r\n // console.log(JSON.stringify(sign.rotation))\r\n mesh_sign.rotation.set(sign.rotation.x, sign.rotation.y, sign.rotation.z)\r\n grp_cell.add(mesh_sign)\r\n\r\n mesh_sign.hit_ = { type: 'sign', cell }\r\n this.picker_.pushHit(mesh_sign)\r\n }\r\n //\r\n {\r\n let logo = box.child.logo\r\n\r\n // mesh_logo = new Mesh(new BoxBufferGeometry(.1, .04, .005), this.get_plastic_logo_material__())\r\n mesh_logo = this.prefab__.clone_logo()\r\n mesh_logo.position.set(logo.position.x, logo.position.y, logo.position.z)\r\n grp_cell.add(mesh_logo)\r\n\r\n mesh_logo.hit_ = { type: 'logo', cell }\r\n this.picker_.pushHit(mesh_logo)\r\n }\r\n }\r\n\r\n cell.getSubs = function () {\r\n return {\r\n box: mesh_box,\r\n sign: mesh_sign,\r\n logo: mesh_logo,\r\n }\r\n }\r\n\r\n }\r\n\r\n commitToShopData() {\r\n // console.log('commitToShopData...')\r\n // if (this.mesh_shelf__) {\r\n // this.shopData_.scene = {\r\n // shelf: {\r\n // position: this.mesh_shelf__.position,\r\n // rotation: {\r\n // x: this.mesh_shelf__.rotation.x,\r\n // y: this.mesh_shelf__.rotation.y,\r\n // z: this.mesh_shelf__.rotation.z\r\n // },\r\n // }\r\n // }\r\n // }\r\n }\r\n\r\n dispose() {\r\n window.removeEventListener('keydown', this.keydown_615__)\r\n super.dispose()\r\n }\r\n\r\n\r\n}\r\n\r\nconst SHELF_POSITION = { x: 2.7, y: -1, z: 0 }\r\nconst SHELF_ROTATION = { x: 0, y: - Math.PI / 2, z: 0 }\r\nconst SHELF_SCALE = { x: 1, y: 1, z: 1 }\r\n\r\n// 从外部选择时添加默认值\r\nShopEditor.appendDefaultShelfData = shelf => {\r\n shelf.position = SHELF_POSITION\r\n shelf.rotation = SHELF_ROTATION\r\n shelf.scale = SHELF_SCALE\r\n return shelf\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ShopEditor.js?");
/***/ }),
@@ -465,7 +465,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"VIEW_MODE\": () => (/* binding */ VIEW_MODE),\n/* harmony export */ \"ViewModeBaseEditor\": () => (/* binding */ ViewModeBaseEditor)\n/* harmony export */ });\n/* harmony import */ var _BaseEditor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseEditor */ \"./src/crossyo/shelves/editor/BaseEditor.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.139.2@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../viewer/ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst VIEW_MODE = {\r\n PANORAMA: 1,\r\n ORBIT: 2,\r\n}\r\n\r\nclass ViewModeBaseEditor extends _BaseEditor__WEBPACK_IMPORTED_MODULE_0__.BaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.viewMode__ = VIEW_MODE.PANORAMA\r\n }\r\n\r\n get viewMode() {\r\n return this.viewMode__\r\n }\r\n\r\n create_cms_() {\r\n\r\n this.cms_ = {\r\n lookAt: { controls: this.controls_ },\r\n orbit: { controls: null }\r\n }\r\n // this.cms_.orbit.controls.enabled = false\r\n console.log('## this.cms_', this.cms_)\r\n }\r\n\r\n changeViewMode_(mode, changeByIndirectReason = false, onCompletion = null) {\r\n if (this.change_view_mode_working__) {\r\n return\r\n }\r\n if (mode != this.viewMode__) {\r\n this.change_view_mode_working__ = true\r\n if (this.viewMode__ == VIEW_MODE.PANORAMA) {\r\n // pano -> orbit\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.visible = false\r\n }\r\n\r\n // fly\r\n this.controls_.enabled = false\r\n if (!this.cms_.orbit.controls) {\r\n let controls = new three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_1__.OrbitControls(this.camera_, this.renderer_.domElement)\r\n controls.minDistance = _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_2__.TARGET_NEAR * .25\r\n controls.maxDistance = _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_2__.TARGET_FAR * 4\r\n this.cms_.orbit.controls = controls\r\n }\r\n this.controls_ = this.cms_.orbit.controls\r\n\r\n this.change_view_mode_working__ = false\r\n this.viewMode__ = mode\r\n\r\n this.controls_.enabled = true\r\n this.emit('viewModeChanged', mode)\r\n if (onCompletion != null) {\r\n onCompletion()\r\n }\r\n\r\n } else {\r\n // orbit -> pano\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.visible = true\r\n }\r\n\r\n // fly\r\n this.controls_.enabled = false\r\n this.controls_ = this.cms_.lookAt.controls\r\n\r\n this.change_view_mode_working__ = false\r\n this.viewMode__ = mode\r\n\r\n this.controls_.enabled = true\r\n this.emit('viewModeChanged', mode)\r\n if (onCompletion != null) {\r\n onCompletion()\r\n }\r\n\r\n }\r\n\r\n }\r\n }\r\n\r\n orbit_update_for_(o3d, forceDeg45 = false) {\r\n let dir = null\r\n if (forceDeg45) {\r\n dir = new three__WEBPACK_IMPORTED_MODULE_3__.Vector3(-2, 1, 1).normalize()\r\n } else {\r\n dir = new three__WEBPACK_IMPORTED_MODULE_3__.Vector3().subVectors(this.controls_.object.position, this.controls_.target).normalize()\r\n }\r\n\r\n let bbx = new three__WEBPACK_IMPORTED_MODULE_3__.Box3().expandByObject(o3d)\r\n let target = bbx.getCenter(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let size = bbx.getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let len = Math.min(Math.max(_viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_2__.TARGET_NEAR, size.length() * 2), _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_2__.TARGET_FAR)\r\n\r\n // this.controls_.object.position.copy(dir.multiplyScalar(len).add(target))\r\n // this.controls_.target.copy(target)\r\n\r\n this.flyTo({\r\n target,\r\n position: dir.multiplyScalar(len).add(target),\r\n duration: .2,\r\n }, () => {\r\n })\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n this.cms_.lookAt.controls.dispose()\r\n if (this.cms_.orbit.controls) {\r\n this.cms_.orbit.controls.dispose()\r\n }\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ViewModeBaseEditor.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"VIEW_MODE\": () => (/* binding */ VIEW_MODE),\n/* harmony export */ \"ViewModeBaseEditor\": () => (/* binding */ ViewModeBaseEditor)\n/* harmony export */ });\n/* harmony import */ var _BaseEditor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseEditor */ \"./src/crossyo/shelves/editor/BaseEditor.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.146.0@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../viewer/ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst VIEW_MODE = {\r\n PANORAMA: 1,\r\n ORBIT: 2,\r\n}\r\n\r\nclass ViewModeBaseEditor extends _BaseEditor__WEBPACK_IMPORTED_MODULE_0__.BaseEditor {\r\n\r\n constructor(opts) {\r\n super(opts)\r\n\r\n this.viewMode__ = VIEW_MODE.PANORAMA\r\n }\r\n\r\n get viewMode() {\r\n return this.viewMode__\r\n }\r\n\r\n create_cms_() {\r\n\r\n this.cms_ = {\r\n lookAt: { controls: this.controls_ },\r\n orbit: { controls: null }\r\n }\r\n // this.cms_.orbit.controls.enabled = false\r\n console.log('## this.cms_', this.cms_)\r\n }\r\n\r\n changeViewMode_(mode, changeByIndirectReason = false, onCompletion = null) {\r\n if (this.change_view_mode_working__) {\r\n return\r\n }\r\n if (mode != this.viewMode__) {\r\n this.change_view_mode_working__ = true\r\n if (this.viewMode__ == VIEW_MODE.PANORAMA) {\r\n // pano -> orbit\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.visible = false\r\n }\r\n\r\n // fly\r\n this.controls_.enabled = false\r\n if (!this.cms_.orbit.controls) {\r\n let controls = new three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_2__.OrbitControls(this.camera_, this.renderer_.domElement)\r\n controls.minDistance = _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_1__.TARGET_NEAR * .25\r\n controls.maxDistance = _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_1__.TARGET_FAR * 4\r\n this.cms_.orbit.controls = controls\r\n }\r\n this.controls_ = this.cms_.orbit.controls\r\n\r\n this.change_view_mode_working__ = false\r\n this.viewMode__ = mode\r\n\r\n this.controls_.enabled = true\r\n this.emit('viewModeChanged', mode)\r\n if (onCompletion != null) {\r\n onCompletion()\r\n }\r\n\r\n } else {\r\n // orbit -> pano\r\n if (this.mesh_env_sphere__) {\r\n this.mesh_env_sphere__.visible = true\r\n }\r\n\r\n // fly\r\n this.controls_.enabled = false\r\n this.controls_ = this.cms_.lookAt.controls\r\n\r\n this.change_view_mode_working__ = false\r\n this.viewMode__ = mode\r\n\r\n this.controls_.enabled = true\r\n this.emit('viewModeChanged', mode)\r\n if (onCompletion != null) {\r\n onCompletion()\r\n }\r\n\r\n }\r\n\r\n }\r\n }\r\n\r\n orbit_update_for_(o3d, forceDeg45 = false) {\r\n let dir = null\r\n if (forceDeg45) {\r\n dir = new three__WEBPACK_IMPORTED_MODULE_3__.Vector3(-2, 1, 1).normalize()\r\n } else {\r\n dir = new three__WEBPACK_IMPORTED_MODULE_3__.Vector3().subVectors(this.controls_.object.position, this.controls_.target).normalize()\r\n }\r\n\r\n let bbx = new three__WEBPACK_IMPORTED_MODULE_3__.Box3().expandByObject(o3d)\r\n let target = bbx.getCenter(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let size = bbx.getSize(new three__WEBPACK_IMPORTED_MODULE_3__.Vector3())\r\n let len = Math.min(Math.max(_viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_1__.TARGET_NEAR, size.length() * 2), _viewer_ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_1__.TARGET_FAR)\r\n\r\n // this.controls_.object.position.copy(dir.multiplyScalar(len).add(target))\r\n // this.controls_.target.copy(target)\r\n\r\n this.flyTo({\r\n target,\r\n position: dir.multiplyScalar(len).add(target),\r\n duration: .2,\r\n }, () => {\r\n })\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n this.cms_.lookAt.controls.dispose()\r\n if (this.cms_.orbit.controls) {\r\n this.cms_.orbit.controls.dispose()\r\n }\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/editor/ViewModeBaseEditor.js?");
/***/ }),
@@ -487,7 +487,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Previewer\": () => (/* binding */ Previewer)\n/* harmony export */ });\n/* harmony import */ var kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n/* harmony import */ var kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/BuilderEx */ \"./src-kutsi/crossyo/kutsi/util/BuilderEx.js\");\n/* harmony import */ var three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/libs/lil-gui.module.min */ \"./node_modules/_three@0.139.2@three/examples/jsm/libs/lil-gui.module.min.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.139.2@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _assets_white_256_png__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../assets/white-256.png */ \"./src/crossyo/shelves/assets/white-256.png\");\n\r\n\r\n\r\n\r\nkutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI = three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__.GUI\r\n\r\n;\r\n\r\n\r\n\r\n\r\nclass Previewer extends kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n constructor(opts) {\r\n super(Object.assign({\r\n trend: {\r\n hdr: true,\r\n },\r\n picker: {\r\n useHitsArray: true,\r\n },\r\n // manually_start_animate: true, // for loading\r\n // clzControls: MapControls,\r\n fov0: 55,\r\n\r\n clzBuilder: kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__.BuilderEx,\r\n\r\n // v2\r\n // assets: {\r\n // \tenv1: assets_env1,\r\n // }\r\n\r\n }, opts))\r\n }\r\n\r\n beginLoadSpecs() {\r\n let arr = super.beginLoadSpecs()\r\n\r\n // this.scene_.background = new Color(0x000000)\r\n arr.push({\r\n func: 'setupEnvEquirect', param: {\r\n url: _assets_white_256_png__WEBPACK_IMPORTED_MODULE_4__,\r\n onAfter: tex => {\r\n // this.w256_ = tex\r\n this.scene_.environment = tex\r\n }\r\n }\r\n })\r\n\r\n return arr\r\n }\r\n\r\n endLoadSpecs() {\r\n super.endLoadSpecs()\r\n\r\n this.emit('loadingCompletion')\r\n }\r\n\r\n set model(v) {\r\n // console.log('set model', v)\r\n {\r\n let loader = new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFLoader()\r\n loader.parse(v.result, '', gltf => {\r\n\r\n // console.log(gltf)\r\n let root = gltf.scene\r\n this.scene_.add(root)\r\n this.updateViewerByBoundingBox(\r\n new three__WEBPACK_IMPORTED_MODULE_5__.Box3().expandByObject(root)\r\n )\r\n\r\n })\r\n }\r\n }\r\n\r\n after_render_(time, delta) {\r\n super.after_render_(time, delta)\r\n if (this.require_snapshot__) {\r\n this.require_snapshot__()\r\n this.require_snapshot__ = null\r\n }\r\n }\r\n\r\n snapshot() {\r\n return new Promise((resolv, reject) => {\r\n if (!this.require_snapshot__) {\r\n this.require_snapshot__ = () => {\r\n this.renderer_.domElement.toBlob(blob => {\r\n resolv(blob)\r\n }, 'image/png', .6)\r\n }\r\n } else {\r\n reject()\r\n }\r\n })\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/previewer/Previewer.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Previewer\": () => (/* binding */ Previewer)\n/* harmony export */ });\n/* harmony import */ var kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n/* harmony import */ var kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/BuilderEx */ \"./src-kutsi/crossyo/kutsi/util/BuilderEx.js\");\n/* harmony import */ var three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/libs/lil-gui.module.min */ \"./node_modules/_three@0.146.0@three/examples/jsm/libs/lil-gui.module.min.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ \"./node_modules/_three@0.146.0@three/examples/jsm/loaders/GLTFLoader.js\");\n/* harmony import */ var _assets_white_256_png__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../assets/white-256.png */ \"./src/crossyo/shelves/assets/white-256.png\");\n\r\n\r\n\r\n\r\nkutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI = three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__.GUI\r\n\r\n;\r\n\r\n\r\n\r\n\r\nclass Previewer extends kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n // #20221118, 整体亮度\r\n brightness_ = 1\r\n\r\n constructor(opts) {\r\n super(Object.assign({\r\n trend: {\r\n hdr: true,\r\n },\r\n picker: {\r\n useHitsArray: true,\r\n },\r\n // manually_start_animate: true, // for loading\r\n // clzControls: MapControls,\r\n fov0: 55,\r\n\r\n clzBuilder: kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__.BuilderEx,\r\n\r\n // v2\r\n // assets: {\r\n // \tenv1: assets_env1,\r\n // }\r\n\r\n }, opts))\r\n }\r\n\r\n beginLoadSpecs() {\r\n let arr = super.beginLoadSpecs()\r\n\r\n // this.scene_.background = new Color(0x000000)\r\n arr.push({\r\n func: 'setupEnvEquirect', param: {\r\n url: _assets_white_256_png__WEBPACK_IMPORTED_MODULE_3__,\r\n onAfter: tex => {\r\n // this.w256_ = tex\r\n this.scene_.environment = tex\r\n // this.env_map_1_ = tex\r\n }\r\n }\r\n })\r\n\r\n return arr\r\n }\r\n\r\n endLoadSpecs() {\r\n super.endLoadSpecs()\r\n this.emit('loadingCompletion')\r\n }\r\n\r\n set model(v) {\r\n // console.log('set model', v)\r\n {\r\n this.scene_.clear()\r\n // this.brightness_ = 1 // maybe reset here!\r\n\r\n let loader = new three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_4__.GLTFLoader()\r\n loader.parse(v.result, '', gltf => {\r\n // console.log(gltf)\r\n let root = gltf.scene\r\n\r\n // root.traverse(c=>{\r\n // if (c.isMesh) {\r\n // c.material.envMap = this.env_map_1_\r\n // }\r\n // })\r\n\r\n this.scene_.add(root)\r\n this.updateViewerByBoundingBox(\r\n new three__WEBPACK_IMPORTED_MODULE_5__.Box3().expandByObject(root)\r\n )\r\n\r\n this.brightness = this.brightness_\r\n\r\n })\r\n }\r\n }\r\n\r\n // 其他光照情况可能不同,采用通用的名称\r\n get brightness() {\r\n return this.brightness_\r\n }\r\n\r\n set brightness(v) {\r\n this.brightness_ = v\r\n this.scene_.traverse(c=>{\r\n if (c.isMesh) {\r\n\r\n c.material.envMapIntensity = v\r\n\r\n // console.log(c.material.name, c.material.envMapIntensity)\r\n }\r\n })\r\n }\r\n\r\n after_render_(time, delta) {\r\n super.after_render_(time, delta)\r\n if (this.require_snapshot__) {\r\n this.require_snapshot__()\r\n this.require_snapshot__ = null\r\n }\r\n }\r\n\r\n snapshot() {\r\n return new Promise((resolv, reject) => {\r\n if (!this.require_snapshot__) {\r\n this.require_snapshot__ = () => {\r\n this.renderer_.domElement.toBlob(blob => {\r\n resolv(blob)\r\n }, 'image/png', .6)\r\n }\r\n } else {\r\n reject()\r\n }\r\n })\r\n }\r\n\r\n}\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/previewer/Previewer.js?");
/***/ }),
@@ -509,7 +509,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShelvesBaseViewer\": () => (/* binding */ ShelvesBaseViewer),\n/* harmony export */ \"TARGET_FAR\": () => (/* binding */ TARGET_FAR),\n/* harmony export */ \"TARGET_NEAR\": () => (/* binding */ TARGET_NEAR)\n/* harmony export */ });\n/* harmony import */ var kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n/* harmony import */ var kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/BuilderEx */ \"./src-kutsi/crossyo/kutsi/util/BuilderEx.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/libs/lil-gui.module.min */ \"./node_modules/_three@0.139.2@three/examples/jsm/libs/lil-gui.module.min.js\");\n/* harmony import */ var kutsi_shelves_controls_ElasticFreeLookControls__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! kutsi-shelves/controls/ElasticFreeLookControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/ElasticFreeLookControls.js\");\n/* harmony import */ var kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! kutsi/util/SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n/* harmony import */ var kutsi_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! kutsi/util/SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n/* harmony import */ var _assets_white_256_png__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../assets/white-256.png */ \"./src/crossyo/shelves/assets/white-256.png\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../common/util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nkutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI = three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__.GUI\r\n\r\n// import { DropTableGeometry } from 'kutsi/geometry/DropTableGeometry'\r\n\r\n;\r\n\r\n\r\n\r\n// import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'\r\n// import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'\r\n\r\n\r\n\r\n\r\n\r\nconst try_mixin_two_fov_ = cam => {\r\n\tif (!cam.hasOwnProperty('aspectFov')) {\r\n\r\n\t\tcam.aspectFov_ = cam.fov\r\n\t\tcam.zoomFov_ = 1\r\n\t\tObject.defineProperty(cam, 'aspectFov', {\r\n\t\t\tset(v) {\r\n\t\t\t\tthis.aspectFov_ = v\r\n\t\t\t\tthis.fov = this.aspectFov_ * this.zoomFov_\r\n\t\t\t\t// console.log('update after aspectFov', this.fov)\r\n\t\t\t},\r\n\t\t\tget() {\r\n\t\t\t\treturn this.aspectFov_\r\n\t\t\t}\r\n\t\t})\r\n\t\tObject.defineProperty(cam, 'zoomFov', {\r\n\t\t\tset(v) {\r\n\t\t\t\tthis.zoomFov_ = v\r\n\t\t\t\tthis.fov = this.aspectFov_ * this.zoomFov_\r\n\t\t\t\t// console.log('update after zoomFov', this.fov)\r\n\t\t\t\tthis.updateProjectionMatrix()\r\n\t\t\t},\r\n\t\t\tget() {\r\n\t\t\t\treturn this.zoomFov_\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t}\r\n}\r\n\r\nconst TARGET_NEAR = .75 // controls 可以 x .25\r\nconst TARGET_FAR = 2 // controls 可以 x 4 \r\n\r\nconst SPHERE_RADIUS = 13.65\r\nconst SPHERE_DEBUG = false // normal\r\n// const SPHERE_DEBUG = true // orbit show depth!\r\n\r\nclass ShelvesBaseViewer extends kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n\tconstructor(opts) {\r\n\r\n\t\tsuper(Object.assign({\r\n\t\t\ttrend: {\r\n\t\t\t\thdr: true,\r\n\t\t\t},\r\n\t\t\tpicker: {\r\n\t\t\t\tuseHitsArray: true,\r\n\t\t\t},\r\n\t\t\t// manually_start_animate: true, // for loading\r\n\t\t\t// clzControls: MapControls,\r\n\t\t\tfov0: 55,\r\n\r\n\t\t\tclzBuilder: kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__.BuilderEx,\r\n\r\n\t\t\t// v2\r\n\t\t\t// assets: {\r\n\t\t\t// \tenv1: assets_env1,\r\n\t\t\t// }\r\n\r\n\t\t}, opts))\r\n\r\n\t\t// {//window aspect ratio!\r\n\t\t// \t// if (window.innerWidth / window.innerHeight < 1) {\r\n\t\t// \t// \tthis.opts_.fov0 = 75\r\n\t\t// \t// }\r\n\t\t// }\r\n\r\n\t\t// console.log('this.opts_', this.opts_)\r\n\r\n\t\tthis.shopData_ = this.opts_.shopData\r\n\r\n\t\tthis.isViewer__ = true\r\n\r\n\t}\r\n\r\n\tresize_() {\r\n\t\tsuper.resize_()\r\n\t\t// this.size_\r\n\r\n\t\ttry_mixin_two_fov_(this.camera_)\r\n\r\n\t\t// .5 -> 75\r\n\t\t// 2 -> 50\r\n\t\tlet aspect = this.size_.w / this.size_.h\r\n\t\tlet fov = three__WEBPACK_IMPORTED_MODULE_8__.MathUtils.lerp(75, 50, three__WEBPACK_IMPORTED_MODULE_8__.MathUtils.smoothstep(aspect, .5, 2))\r\n\t\t// console.log('\\t', aspect, fov)\r\n\r\n\t\t// this.camera_.fov = fov\r\n\t\tthis.camera_.aspectFov = fov\r\n\t\t// this.camera_.aspectFov = 75 // for snapshot!\r\n\t\tthis.camera_.updateProjectionMatrix()\r\n\r\n\t}\r\n\r\n\tstartup() {\r\n\t\tsuper.startup()\r\n\t\t// this.controls_.enablePan = true\r\n\t\tthis.scene_.background = new three__WEBPACK_IMPORTED_MODULE_8__.Color(0xefefef)\r\n\t}\r\n\r\n\tbeginLoadSpecs() {\r\n\r\n\t\tlet arr = super.beginLoadSpecs()\r\n\r\n\t\tthis.geo_env_sphere__ = new three__WEBPACK_IMPORTED_MODULE_8__.SphereBufferGeometry(SPHERE_RADIUS, 256, 256)\r\n\t\t// this.geo_env_sphere__ = new SphereBufferGeometry(SPHERE_RADIUS, 512, 512)\r\n\t\tthis.mesh_env_sphere__ = null\r\n\r\n\t\tthis.cart_plane_ = new three__WEBPACK_IMPORTED_MODULE_8__.Plane(new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(-1, 0, 0), 2)\r\n\t\tthis.mesh_shelf__ = null\r\n\r\n\t\t// {// debug\r\n\t\t// \tthis.dump_keydown_after__ = () => {\r\n\t\t// \t\tconsole.log('shelf', this.mesh_shelf__)\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tarr.push({\r\n\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\turl: _assets_white_256_png__WEBPACK_IMPORTED_MODULE_6__,\r\n\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\tthis.w256_ = tex\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\t// this.DEFAULT_TARGET__ = new Vector3(0.1, -0.01, 0.00)\r\n\t\t// this.DEFAULT_TARGET__ = new Vector3(2.37, -0.41, 0.00)\r\n\t\tthis.DEFAULT_TARGET__ = new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(2.37, -0.31, 0.00)\r\n\r\n\t\tarr.push({\r\n\t\t\tfunc: 'setupCustomization', param: {\r\n\t\t\t\tonDoing: next => {\r\n\r\n\t\t\t\t\t// this.scene_.fog = new Fog(this.theme_.fogColor, 400, 800)\r\n\r\n\t\t\t\t\t// this.controls_.minPolarAngle = 0\r\n\t\t\t\t\t// this.controls_.maxPolarAngle = Math.PI * .67\r\n\t\t\t\t\t// this.controls_.maxDistance = 400\r\n\r\n\t\t\t\t\t// this.scene_.add(new AxesHelper(10))\r\n\r\n\t\t\t\t\tlet target = this.DEFAULT_TARGET__\r\n\r\n\t\t\t\t\tif (SPHERE_DEBUG) { // debug\r\n\t\t\t\t\t\tthis.updateViewerLookat({\r\n\t\t\t\t\t\t\tposition: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(-1, 0.1, 0.00),\r\n\t\t\t\t\t\t\ttarget: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\tforceUpdateNearFar: true,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.controls_.enablePan = true\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.changeControls(\r\n\t\t\t\t\t\t\t// new FreeLookControls\r\n\t\t\t\t\t\t\tnew kutsi_shelves_controls_ElasticFreeLookControls__WEBPACK_IMPORTED_MODULE_3__[\"default\"]\r\n\t\t\t\t\t\t\t\t(this.camera_, this.renderer_.domElement, {\r\n\t\t\t\t\t\t\t\t\tlookDirection: -1,\r\n\t\t\t\t\t\t\t\t\telasticDirection: target,\r\n\t\t\t\t\t\t\t\t\tzoomResetFunction: e => {\r\n\t\t\t\t\t\t\t\t\t\treturn e.object.zoomFov\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\tzoomFunction: e => {\r\n\t\t\t\t\t\t\t\t\t\te.object.zoomFov = e.zoom2\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\tzoomMin: .5,\r\n\t\t\t\t\t\t\t\t\tzoomMax: 1,\r\n\t\t\t\t\t\t\t\t}))\r\n\r\n\t\t\t\t\t\tthis.updateViewerLookat({\r\n\t\t\t\t\t\t\t// position: new Vector3(-0.1, 0.01, 0.00),\r\n\t\t\t\t\t\t\t// target: new Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\tposition: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\t\tforceUpdateNearFar: true,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\r\n\r\n\t\t\t\t\tnext()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tif (this.shopData_ && this.shopData_.panorama) {\r\n\r\n\t\t\t// if (this.shopData_.panorama.urlEnv) {\r\n\t\t\t// \tarr.push({\r\n\t\t\t// \t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t// \t\t\turl: `${this.shopData_.panorama.url}`,\r\n\t\t\t// \t\t\tonAfter: tex => {\r\n\t\t\t// \t\t\t\tthis.scene_.background = tex\r\n\t\t\t// \t\t\t\t// this.scene_.environment = tex\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t})\r\n\t\t\t// \tarr.push({\r\n\t\t\t// \t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t// \t\t\turl: `${this.shopData_.panorama.urlEnv}`,\r\n\t\t\t// \t\t\tonAfter: tex => {\r\n\t\t\t// \t\t\t\t// this.scene_.background = tex\r\n\t\t\t// \t\t\t\tthis.scene_.environment = tex\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t})\r\n\r\n\t\t\t// } else {\r\n\r\n\t\t\tlet panorama_shelf_exr = this.shopData_.panorama.urlShelfExr\r\n\t\t\tarr.push({\r\n\t\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\t\turl: `${this.get_panorama_url_(this.shopData_.panorama)}`,\r\n\t\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\t\t// this.scene_.background = tex\r\n\t\t\t\t\t\t// for rotationY\r\n\r\n\t\t\t\t\t\tlet sp = new three__WEBPACK_IMPORTED_MODULE_8__.Mesh(\r\n\t\t\t\t\t\t\t// new SphereBufferGeometry(20, 256, 256),\r\n\t\t\t\t\t\t\tthis.geo_env_sphere__,\r\n\t\t\t\t\t\t\tnew three__WEBPACK_IMPORTED_MODULE_8__.MeshStandardMaterial({\r\n\t\t\t\t\t\t\t\tmap: tex,\r\n\t\t\t\t\t\t\t\tside: three__WEBPACK_IMPORTED_MODULE_8__.BackSide,\r\n\t\t\t\t\t\t\t\t// wireframe: true,\r\n\t\t\t\t\t\t\t\tfog: false,\r\n\t\t\t\t\t\t\t\t// displacementScale: -env_.radius * .992,\r\n\t\t\t\t\t\t\t\t// displacementMap: new TextureLoader().load(`${this.prefixAsset_}/env/equirect/${env_.code}-zdepth-1k.png`),\r\n\t\t\t\t\t\t\t\tdisplacementScale: - SPHERE_RADIUS,\r\n\t\t\t\t\t\t\t\tdisplacementMap: new three__WEBPACK_IMPORTED_MODULE_8__.TextureLoader().load(`${this.shopData_.panorama.urlDepth}`),\r\n\t\t\t\t\t\t\t\tenvMap: this.w256_,\r\n\t\t\t\t\t\t\t\t// envMapIntensity: 2,\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tsp.scale.set(1, 1, -1)\r\n\t\t\t\t\t\tsp.name = 'sys-env-sphere-'\r\n\t\t\t\t\t\tthis.scene_.add(sp)\r\n\r\n\t\t\t\t\t\tthis.mesh_env_sphere__ = sp\r\n\t\t\t\t\t\tthis.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n\r\n\t\t\t\t\t\tif (!panorama_shelf_exr) {\r\n\t\t\t\t\t\t\tthis.scene_.environment = tex\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\tif (panorama_shelf_exr) {\r\n\t\t\t\tarr.push({\r\n\t\t\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\t\t\turl: `${panorama_shelf_exr}`,\r\n\t\t\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\t\t\tthis.scene_.environment = tex\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t}\r\n\r\n\r\n\t\t\t// }\r\n\r\n\t\t} else {\r\n\r\n\t\t\t// TODO 新增时\r\n\r\n\t\t}\r\n\r\n\t\tif (this.shopData_ && this.shopData_.shelf) {\r\n\t\t\tlet shelf = this.shopData_.shelf\r\n\t\t\tlet shelf_url = shelf.url\r\n\t\t\tarr.push({\r\n\t\t\t\tfunc: 'setupModelGltf', param: {\r\n\t\t\t\t\tpath: shelf_url.substr(0, shelf_url.lastIndexOf('/')),\r\n\t\t\t\t\tname: shelf_url.substr(shelf_url.lastIndexOf('/')),\r\n\t\t\t\t\t// predefinedModel: (() => {\r\n\t\t\t\t\t// \tlet def = {\r\n\t\t\t\t\t// \t\tobjects_isolate_material: true,\r\n\t\t\t\t\t// \t\tmaps: {\r\n\t\t\t\t\t// \t\t\t'm1': { url: 'model/ao-2to1k-s4096/shelves_Bake1_CyclesBake_AO.png' }\r\n\t\t\t\t\t// \t\t},\r\n\t\t\t\t\t// \t\tobjects: {\r\n\t\t\t\t\t// \t\t\t'shelves': {\r\n\t\t\t\t\t// \t\t\t\tlightMap: 'm1'\r\n\t\t\t\t\t// \t\t\t}\r\n\t\t\t\t\t// \t\t}\r\n\t\t\t\t\t// \t}\r\n\t\t\t\t\t// \treturn def\r\n\t\t\t\t\t// })(),\r\n\t\t\t\t\tonAfter: o3d => {\r\n\r\n\t\t\t\t\t\to3d.traverse(c => {\r\n\t\t\t\t\t\t\tif (c.isMesh) {\r\n\t\t\t\t\t\t\t\tif (c.material.aoMap) {\r\n\t\t\t\t\t\t\t\t\tc.material.lightMap = c.material.aoMap\r\n\t\t\t\t\t\t\t\t\t// c.material.aoMap = null\r\n\t\t\t\t\t\t\t\t\tc.material.lightMapIntensity = .5\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tc.material.side = three__WEBPACK_IMPORTED_MODULE_8__.FrontSide\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (/^box-\\d-\\d/.test(c.name)) {\r\n\t\t\t\t\t\t\t\tc.visible = false\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t})\r\n\r\n\t\t\t\t\t\tif (shelf.position && shelf.rotation) {\r\n\r\n\t\t\t\t\t\t\to3d.position.set(shelf.position.x, shelf.position.y, shelf.position.z)\r\n\t\t\t\t\t\t\to3d.rotation.set(shelf.rotation.x, shelf.rotation.y, shelf.rotation.z)\r\n\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\to3d.rotation.set(0, - Math.PI / 2, 0)\r\n\t\t\t\t\t\t\to3d.position.set(2.7, -1, 0)\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tthis.scene_.add(o3d)\r\n\r\n\t\t\t\t\t\to3d.name = 'shelf__'\r\n\t\t\t\t\t\tthis.mesh_shelf__ = o3d\r\n\r\n\t\t\t\t\t\t// .$model__ = o3d\r\n\t\t\t\t\t\tshelf.get_model__ = () => {\r\n\t\t\t\t\t\t\treturn o3d\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// dump_o3d(o3d)\r\n\t\t\t\t\t\t// can-2, box-2, pillow-2\r\n\r\n\t\t\t\t\t\t// create_sample_balls(balls => {\r\n\t\t\t\t\t\t// \tballs.position.set(2, -.25, 0)\r\n\t\t\t\t\t\t// \tthis.scene_.add(balls)\r\n\t\t\t\t\t\t// })\r\n\r\n\t\t\t\t\t\t// create_env_ball(ball => {\r\n\t\t\t\t\t\t// \tball.position.set(2, -.25, 0)\r\n\t\t\t\t\t\t// \tthis.scene_.add(ball)\r\n\t\t\t\t\t\t// })\r\n\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t} else {\r\n\t\t\t// TODO 新建\r\n\t\t}\r\n\r\n\t\t// if (this.shopData_ && this.shopData_.commodities) {\r\n\r\n\t\t// \tthis.shopData_.commodities.forEach(mod => {\r\n\t\t// \t\tlet mod_url = mod.url\r\n\t\t// \t\tarr.push({\r\n\t\t// \t\t\tfunc: 'setupModelGltf', param: {\r\n\t\t// \t\t\t\tpath: mod_url.substr(0, mod_url.lastIndexOf('/')),\r\n\t\t// \t\t\t\tname: mod_url.substr(mod_url.lastIndexOf('/')),\r\n\t\t// \t\t\t\tonAfter: o3d => {\r\n\t\t// \t\t\t\t\to3d.traverse(c => {\r\n\t\t// \t\t\t\t\t\tif (c.isMesh) {\r\n\t\t// \t\t\t\t\t\t\tc.material.envMapIntensity = this.shopData_.panorama.multiply\r\n\t\t// \t\t\t\t\t\t\tc.material.side = FrontSide\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t})\r\n\t\t// \t\t\t\t\tif (!o3d.isMesh && o3d.children.length == 1) {\r\n\t\t// \t\t\t\t\t\t// 单个mesh, 需要导出时apply transform\r\n\t\t// \t\t\t\t\t\tmod.get_model__ = () => {\r\n\t\t// \t\t\t\t\t\t\treturn o3d.children[0]\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t} else {\r\n\t\t// \t\t\t\t\t\tmod.get_model__ = () => {\r\n\t\t// \t\t\t\t\t\t\treturn o3d\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t}\r\n\t\t// \t\t\t\t},\r\n\t\t// \t\t\t},\r\n\t\t// \t\t})\r\n\t\t// \t})\r\n\r\n\t\t// } else {\r\n\t\t// \t// TODO 新建\r\n\t\t// }\r\n\r\n\t\tif (this.use_grid__) {\r\n\r\n\t\t\tlet grid = new three__WEBPACK_IMPORTED_MODULE_8__.GridHelper(4, 8)\r\n\t\t\t// grid.position.set(0, -5, 0)\r\n\t\t\tgrid.position.set(0, -1, 0)\r\n\t\t\tthis.scene_.add(grid)\r\n\r\n\t\t\t// let box = new Mesh(\r\n\t\t\t// \tnew BoxBufferGeometry(1.5, 1.5, .5),\r\n\t\t\t// \tnew MeshStandardMaterial({\r\n\t\t\t// \t\twireframe: true,\r\n\t\t\t// \t})\r\n\t\t\t// )\r\n\t\t\t// box.rotation.set(0, Math.PI / 2, 0)\r\n\t\t\t// box.position.set(2.25, -.25, 0)\r\n\t\t\t// this.scene_.add(box)\r\n\r\n\t\t}\r\n\r\n\t\t// cart plane !\r\n\r\n\r\n\t\treturn arr\r\n\t}\r\n\r\n\tget_panorama_url_(panorama) {\r\n\t\tif (this.isViewer__) {\r\n\t\t\treturn _common_util__WEBPACK_IMPORTED_MODULE_7__.isMobile ? panorama.urlSmall : panorama.url\r\n\t\t} else {\r\n\t\t\treturn panorama.urlSmall // 編輯器頻繁dispose,減少開銷\r\n\t\t}\r\n\t}\r\n\r\n\tdispose() {\r\n\t\tsuper.dispose()\r\n\t\tconsole.log('viewer dispose!')\r\n\t}\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/viewer/ShelvesBaseViewer.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShelvesBaseViewer\": () => (/* binding */ ShelvesBaseViewer),\n/* harmony export */ \"TARGET_FAR\": () => (/* binding */ TARGET_FAR),\n/* harmony export */ \"TARGET_NEAR\": () => (/* binding */ TARGET_NEAR)\n/* harmony export */ });\n/* harmony import */ var kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kutsi/BaseViewer */ \"./src-kutsi/crossyo/kutsi/BaseViewer.js\");\n/* harmony import */ var kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! kutsi/util/BuilderEx */ \"./src-kutsi/crossyo/kutsi/util/BuilderEx.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/libs/lil-gui.module.min */ \"./node_modules/_three@0.146.0@three/examples/jsm/libs/lil-gui.module.min.js\");\n/* harmony import */ var kutsi_shelves_controls_ElasticFreeLookControls__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! kutsi-shelves/controls/ElasticFreeLookControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/ElasticFreeLookControls.js\");\n/* harmony import */ var kutsi_util_SceneUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! kutsi/util/SceneUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneUtil.js\");\n/* harmony import */ var kutsi_util_SceneTuningUtil__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! kutsi/util/SceneTuningUtil */ \"./src-kutsi/crossyo/kutsi/util/SceneTuningUtil.js\");\n/* harmony import */ var _assets_white_256_png__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../assets/white-256.png */ \"./src/crossyo/shelves/assets/white-256.png\");\n/* harmony import */ var _common_util__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../common/util */ \"./src/crossyo/shelves/common/util.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nkutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__.registerClass.GUI = three_examples_jsm_libs_lil_gui_module_min__WEBPACK_IMPORTED_MODULE_2__.GUI\r\n\r\n// import { DropTableGeometry } from 'kutsi/geometry/DropTableGeometry'\r\n\r\n;\r\n\r\n\r\n\r\n// import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'\r\n// import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'\r\n\r\n\r\n\r\n\r\n\r\nconst try_mixin_two_fov_ = cam => {\r\n\tif (!cam.hasOwnProperty('aspectFov')) {\r\n\r\n\t\tcam.aspectFov_ = cam.fov\r\n\t\tcam.zoomFov_ = 1\r\n\t\tObject.defineProperty(cam, 'aspectFov', {\r\n\t\t\tset(v) {\r\n\t\t\t\tthis.aspectFov_ = v\r\n\t\t\t\tthis.fov = this.aspectFov_ * this.zoomFov_\r\n\t\t\t\t// console.log('update after aspectFov', this.fov)\r\n\t\t\t},\r\n\t\t\tget() {\r\n\t\t\t\treturn this.aspectFov_\r\n\t\t\t}\r\n\t\t})\r\n\t\tObject.defineProperty(cam, 'zoomFov', {\r\n\t\t\tset(v) {\r\n\t\t\t\tthis.zoomFov_ = v\r\n\t\t\t\tthis.fov = this.aspectFov_ * this.zoomFov_\r\n\t\t\t\t// console.log('update after zoomFov', this.fov)\r\n\t\t\t\tthis.updateProjectionMatrix()\r\n\t\t\t},\r\n\t\t\tget() {\r\n\t\t\t\treturn this.zoomFov_\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t}\r\n}\r\n\r\nconst TARGET_NEAR = .75 // controls 可以 x .25\r\nconst TARGET_FAR = 2 // controls 可以 x 4 \r\n\r\nconst SPHERE_RADIUS = 13.65\r\nconst SPHERE_DEBUG = false // normal\r\n// const SPHERE_DEBUG = true // orbit show depth!\r\n\r\nclass ShelvesBaseViewer extends kutsi_BaseViewer__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\r\n\tconstructor(opts) {\r\n\r\n\t\tsuper(Object.assign({\r\n\t\t\ttrend: {\r\n\t\t\t\thdr: true,\r\n\t\t\t},\r\n\t\t\tpicker: {\r\n\t\t\t\tuseHitsArray: true,\r\n\t\t\t},\r\n\t\t\t// manually_start_animate: true, // for loading\r\n\t\t\t// clzControls: MapControls,\r\n\t\t\tfov0: 55,\r\n\r\n\t\t\tclzBuilder: kutsi_util_BuilderEx__WEBPACK_IMPORTED_MODULE_1__.BuilderEx,\r\n\r\n\t\t\t// v2\r\n\t\t\t// assets: {\r\n\t\t\t// \tenv1: assets_env1,\r\n\t\t\t// }\r\n\r\n\t\t}, opts))\r\n\r\n\t\t// {//window aspect ratio!\r\n\t\t// \t// if (window.innerWidth / window.innerHeight < 1) {\r\n\t\t// \t// \tthis.opts_.fov0 = 75\r\n\t\t// \t// }\r\n\t\t// }\r\n\r\n\t\t// console.log('this.opts_', this.opts_)\r\n\r\n\t\tthis.shopData_ = this.opts_.shopData\r\n\r\n\t\tthis.isViewer__ = true\r\n\r\n\t}\r\n\r\n\tresize_() {\r\n\t\tsuper.resize_()\r\n\t\t// this.size_\r\n\r\n\t\ttry_mixin_two_fov_(this.camera_)\r\n\r\n\t\t// .5 -> 75\r\n\t\t// 2 -> 50\r\n\t\tlet aspect = this.size_.w / this.size_.h\r\n\t\tlet fov = three__WEBPACK_IMPORTED_MODULE_8__.MathUtils.lerp(75, 50, three__WEBPACK_IMPORTED_MODULE_8__.MathUtils.smoothstep(aspect, .5, 2))\r\n\t\t// console.log('\\t', aspect, fov)\r\n\r\n\t\t// this.camera_.fov = fov\r\n\t\tthis.camera_.aspectFov = fov\r\n\t\t// this.camera_.aspectFov = 75 // for snapshot!\r\n\t\tthis.camera_.updateProjectionMatrix()\r\n\r\n\t}\r\n\r\n\tstartup() {\r\n\t\tsuper.startup()\r\n\t\t// this.controls_.enablePan = true\r\n\t\tthis.scene_.background = new three__WEBPACK_IMPORTED_MODULE_8__.Color(0xefefef)\r\n\t}\r\n\r\n\tbeginLoadSpecs() {\r\n\r\n\t\tlet arr = super.beginLoadSpecs()\r\n\r\n\t\tthis.geo_env_sphere__ = new three__WEBPACK_IMPORTED_MODULE_8__.SphereBufferGeometry(SPHERE_RADIUS, 256, 256)\r\n\t\t// this.geo_env_sphere__ = new SphereBufferGeometry(SPHERE_RADIUS, 512, 512)\r\n\t\tthis.mesh_env_sphere__ = null\r\n\r\n\t\tthis.cart_plane_ = new three__WEBPACK_IMPORTED_MODULE_8__.Plane(new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(-1, 0, 0), 2)\r\n\t\tthis.mesh_shelf__ = null\r\n\r\n\t\t// {// debug\r\n\t\t// \tthis.dump_keydown_after__ = () => {\r\n\t\t// \t\tconsole.log('shelf', this.mesh_shelf__)\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tarr.push({\r\n\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\turl: _assets_white_256_png__WEBPACK_IMPORTED_MODULE_6__,\r\n\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\tthis.w256_ = tex\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\t// this.DEFAULT_TARGET__ = new Vector3(0.1, -0.01, 0.00)\r\n\t\t// this.DEFAULT_TARGET__ = new Vector3(2.37, -0.41, 0.00)\r\n\t\tthis.DEFAULT_TARGET__ = new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(2.37, -0.31, 0.00)\r\n\r\n\t\tarr.push({\r\n\t\t\tfunc: 'setupCustomization', param: {\r\n\t\t\t\tonDoing: next => {\r\n\r\n\t\t\t\t\t// this.scene_.fog = new Fog(this.theme_.fogColor, 400, 800)\r\n\r\n\t\t\t\t\t// this.controls_.minPolarAngle = 0\r\n\t\t\t\t\t// this.controls_.maxPolarAngle = Math.PI * .67\r\n\t\t\t\t\t// this.controls_.maxDistance = 400\r\n\r\n\t\t\t\t\t// this.scene_.add(new AxesHelper(10))\r\n\r\n\t\t\t\t\tlet target = this.DEFAULT_TARGET__\r\n\r\n\t\t\t\t\tif (SPHERE_DEBUG) { // debug\r\n\t\t\t\t\t\tthis.updateViewerLookat({\r\n\t\t\t\t\t\t\tposition: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(-1, 0.1, 0.00),\r\n\t\t\t\t\t\t\ttarget: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\tforceUpdateNearFar: true,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.controls_.enablePan = true\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.changeControls(\r\n\t\t\t\t\t\t\t// new FreeLookControls\r\n\t\t\t\t\t\t\tnew kutsi_shelves_controls_ElasticFreeLookControls__WEBPACK_IMPORTED_MODULE_3__[\"default\"]\r\n\t\t\t\t\t\t\t\t(this.camera_, this.renderer_.domElement, {\r\n\t\t\t\t\t\t\t\t\tlookDirection: -1,\r\n\t\t\t\t\t\t\t\t\telasticDirection: target,\r\n\t\t\t\t\t\t\t\t\tzoomResetFunction: e => {\r\n\t\t\t\t\t\t\t\t\t\treturn e.object.zoomFov\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\tzoomFunction: e => {\r\n\t\t\t\t\t\t\t\t\t\te.object.zoomFov = e.zoom2\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\tzoomMin: .5,\r\n\t\t\t\t\t\t\t\t\tzoomMax: 1,\r\n\t\t\t\t\t\t\t\t}))\r\n\r\n\t\t\t\t\t\tthis.updateViewerLookat({\r\n\t\t\t\t\t\t\t// position: new Vector3(-0.1, 0.01, 0.00),\r\n\t\t\t\t\t\t\t// target: new Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\tposition: new three__WEBPACK_IMPORTED_MODULE_8__.Vector3(0.00, 0.00, 0.00),\r\n\t\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\t\tforceUpdateNearFar: true,\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t}\r\n\r\n\r\n\t\t\t\t\tnext()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tif (this.shopData_ && this.shopData_.panorama) {\r\n\r\n\t\t\t// if (this.shopData_.panorama.urlEnv) {\r\n\t\t\t// \tarr.push({\r\n\t\t\t// \t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t// \t\t\turl: `${this.shopData_.panorama.url}`,\r\n\t\t\t// \t\t\tonAfter: tex => {\r\n\t\t\t// \t\t\t\tthis.scene_.background = tex\r\n\t\t\t// \t\t\t\t// this.scene_.environment = tex\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t})\r\n\t\t\t// \tarr.push({\r\n\t\t\t// \t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t// \t\t\turl: `${this.shopData_.panorama.urlEnv}`,\r\n\t\t\t// \t\t\tonAfter: tex => {\r\n\t\t\t// \t\t\t\t// this.scene_.background = tex\r\n\t\t\t// \t\t\t\tthis.scene_.environment = tex\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t})\r\n\r\n\t\t\t// } else {\r\n\r\n\t\t\tlet panorama_shelf_exr = this.shopData_.panorama.urlShelfExr\r\n\t\t\tarr.push({\r\n\t\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\t\turl: `${this.get_panorama_url_(this.shopData_.panorama)}`,\r\n\t\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\t\t// this.scene_.background = tex\r\n\t\t\t\t\t\t// for rotationY\r\n\r\n\t\t\t\t\t\tlet sp = new three__WEBPACK_IMPORTED_MODULE_8__.Mesh(\r\n\t\t\t\t\t\t\t// new SphereBufferGeometry(20, 256, 256),\r\n\t\t\t\t\t\t\tthis.geo_env_sphere__,\r\n\t\t\t\t\t\t\tnew three__WEBPACK_IMPORTED_MODULE_8__.MeshStandardMaterial({\r\n\t\t\t\t\t\t\t\tmap: tex,\r\n\t\t\t\t\t\t\t\tside: three__WEBPACK_IMPORTED_MODULE_8__.BackSide,\r\n\t\t\t\t\t\t\t\t// wireframe: true,\r\n\t\t\t\t\t\t\t\tfog: false,\r\n\t\t\t\t\t\t\t\t// displacementScale: -env_.radius * .992,\r\n\t\t\t\t\t\t\t\t// displacementMap: new TextureLoader().load(`${this.prefixAsset_}/env/equirect/${env_.code}-zdepth-1k.png`),\r\n\t\t\t\t\t\t\t\tdisplacementScale: - SPHERE_RADIUS,\r\n\t\t\t\t\t\t\t\tdisplacementMap: new three__WEBPACK_IMPORTED_MODULE_8__.TextureLoader().load(`${this.shopData_.panorama.urlDepth}`),\r\n\t\t\t\t\t\t\t\tenvMap: this.w256_,\r\n\t\t\t\t\t\t\t\t// envMapIntensity: 2,\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tsp.scale.set(1, 1, -1)\r\n\t\t\t\t\t\tsp.name = 'sys-env-sphere-'\r\n\t\t\t\t\t\tthis.scene_.add(sp)\r\n\r\n\t\t\t\t\t\tthis.mesh_env_sphere__ = sp\r\n\t\t\t\t\t\tthis.mesh_env_sphere__.rotation.y = this.shopData_.panorama.rotationY * Math.PI / 180\r\n\r\n\t\t\t\t\t\tif (!panorama_shelf_exr) {\r\n\t\t\t\t\t\t\tthis.scene_.environment = tex\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\tif (panorama_shelf_exr) {\r\n\t\t\t\tarr.push({\r\n\t\t\t\t\tfunc: 'setupEnvEquirect', param: {\r\n\t\t\t\t\t\turl: `${panorama_shelf_exr}`,\r\n\t\t\t\t\t\tonAfter: tex => {\r\n\t\t\t\t\t\t\tthis.scene_.environment = tex\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t}\r\n\r\n\r\n\t\t\t// }\r\n\r\n\t\t} else {\r\n\r\n\t\t\t// TODO 新增时\r\n\r\n\t\t}\r\n\r\n\t\tif (this.shopData_ && this.shopData_.shelf) {\r\n\t\t\tlet shelf = this.shopData_.shelf\r\n\t\t\tlet shelf_url = shelf.url\r\n\t\t\tarr.push({\r\n\t\t\t\tfunc: 'setupModelGltf', param: {\r\n\t\t\t\t\tpath: shelf_url.substr(0, shelf_url.lastIndexOf('/')),\r\n\t\t\t\t\tname: shelf_url.substr(shelf_url.lastIndexOf('/')),\r\n\t\t\t\t\t// predefinedModel: (() => {\r\n\t\t\t\t\t// \tlet def = {\r\n\t\t\t\t\t// \t\tobjects_isolate_material: true,\r\n\t\t\t\t\t// \t\tmaps: {\r\n\t\t\t\t\t// \t\t\t'm1': { url: 'model/ao-2to1k-s4096/shelves_Bake1_CyclesBake_AO.png' }\r\n\t\t\t\t\t// \t\t},\r\n\t\t\t\t\t// \t\tobjects: {\r\n\t\t\t\t\t// \t\t\t'shelves': {\r\n\t\t\t\t\t// \t\t\t\tlightMap: 'm1'\r\n\t\t\t\t\t// \t\t\t}\r\n\t\t\t\t\t// \t\t}\r\n\t\t\t\t\t// \t}\r\n\t\t\t\t\t// \treturn def\r\n\t\t\t\t\t// })(),\r\n\t\t\t\t\tonAfter: o3d => {\r\n\r\n\t\t\t\t\t\to3d.traverse(c => {\r\n\t\t\t\t\t\t\tif (c.isMesh) {\r\n\t\t\t\t\t\t\t\tif (c.material.aoMap) {\r\n\t\t\t\t\t\t\t\t\tc.material.lightMap = c.material.aoMap\r\n\t\t\t\t\t\t\t\t\t// c.material.aoMap = null\r\n\t\t\t\t\t\t\t\t\tc.material.lightMapIntensity = .5\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tc.material.side = three__WEBPACK_IMPORTED_MODULE_8__.FrontSide\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (/^box-\\d-\\d/.test(c.name)) {\r\n\t\t\t\t\t\t\t\tc.visible = false\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t})\r\n\r\n\t\t\t\t\t\tif (shelf.position && shelf.rotation) {\r\n\r\n\t\t\t\t\t\t\to3d.position.set(shelf.position.x, shelf.position.y, shelf.position.z)\r\n\t\t\t\t\t\t\to3d.rotation.set(shelf.rotation.x, shelf.rotation.y, shelf.rotation.z)\r\n\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\to3d.rotation.set(0, - Math.PI / 2, 0)\r\n\t\t\t\t\t\t\to3d.position.set(2.7, -1, 0)\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tthis.scene_.add(o3d)\r\n\r\n\t\t\t\t\t\to3d.name = 'shelf__'\r\n\t\t\t\t\t\tthis.mesh_shelf__ = o3d\r\n\r\n\t\t\t\t\t\t// .$model__ = o3d\r\n\t\t\t\t\t\tshelf.get_model__ = () => {\r\n\t\t\t\t\t\t\treturn o3d\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// dump_o3d(o3d)\r\n\t\t\t\t\t\t// can-2, box-2, pillow-2\r\n\r\n\t\t\t\t\t\t// create_sample_balls(balls => {\r\n\t\t\t\t\t\t// \tballs.position.set(2, -.25, 0)\r\n\t\t\t\t\t\t// \tthis.scene_.add(balls)\r\n\t\t\t\t\t\t// })\r\n\r\n\t\t\t\t\t\t// create_env_ball(ball => {\r\n\t\t\t\t\t\t// \tball.position.set(2, -.25, 0)\r\n\t\t\t\t\t\t// \tthis.scene_.add(ball)\r\n\t\t\t\t\t\t// })\r\n\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t} else {\r\n\t\t\t// TODO 新建\r\n\t\t}\r\n\r\n\t\t// if (this.shopData_ && this.shopData_.commodities) {\r\n\r\n\t\t// \tthis.shopData_.commodities.forEach(mod => {\r\n\t\t// \t\tlet mod_url = mod.url\r\n\t\t// \t\tarr.push({\r\n\t\t// \t\t\tfunc: 'setupModelGltf', param: {\r\n\t\t// \t\t\t\tpath: mod_url.substr(0, mod_url.lastIndexOf('/')),\r\n\t\t// \t\t\t\tname: mod_url.substr(mod_url.lastIndexOf('/')),\r\n\t\t// \t\t\t\tonAfter: o3d => {\r\n\t\t// \t\t\t\t\to3d.traverse(c => {\r\n\t\t// \t\t\t\t\t\tif (c.isMesh) {\r\n\t\t// \t\t\t\t\t\t\tc.material.envMapIntensity = this.shopData_.panorama.multiply\r\n\t\t// \t\t\t\t\t\t\tc.material.side = FrontSide\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t})\r\n\t\t// \t\t\t\t\tif (!o3d.isMesh && o3d.children.length == 1) {\r\n\t\t// \t\t\t\t\t\t// 单个mesh, 需要导出时apply transform\r\n\t\t// \t\t\t\t\t\tmod.get_model__ = () => {\r\n\t\t// \t\t\t\t\t\t\treturn o3d.children[0]\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t} else {\r\n\t\t// \t\t\t\t\t\tmod.get_model__ = () => {\r\n\t\t// \t\t\t\t\t\t\treturn o3d\r\n\t\t// \t\t\t\t\t\t}\r\n\t\t// \t\t\t\t\t}\r\n\t\t// \t\t\t\t},\r\n\t\t// \t\t\t},\r\n\t\t// \t\t})\r\n\t\t// \t})\r\n\r\n\t\t// } else {\r\n\t\t// \t// TODO 新建\r\n\t\t// }\r\n\r\n\t\tif (this.use_grid__) {\r\n\r\n\t\t\tlet grid = new three__WEBPACK_IMPORTED_MODULE_8__.GridHelper(4, 8)\r\n\t\t\t// grid.position.set(0, -5, 0)\r\n\t\t\tgrid.position.set(0, -1, 0)\r\n\t\t\tthis.scene_.add(grid)\r\n\r\n\t\t\t// let box = new Mesh(\r\n\t\t\t// \tnew BoxBufferGeometry(1.5, 1.5, .5),\r\n\t\t\t// \tnew MeshStandardMaterial({\r\n\t\t\t// \t\twireframe: true,\r\n\t\t\t// \t})\r\n\t\t\t// )\r\n\t\t\t// box.rotation.set(0, Math.PI / 2, 0)\r\n\t\t\t// box.position.set(2.25, -.25, 0)\r\n\t\t\t// this.scene_.add(box)\r\n\r\n\t\t}\r\n\r\n\t\t// cart plane !\r\n\r\n\r\n\t\treturn arr\r\n\t}\r\n\r\n\tget_panorama_url_(panorama) {\r\n\t\tif (this.isViewer__) {\r\n\t\t\treturn _common_util__WEBPACK_IMPORTED_MODULE_7__.isMobile ? panorama.urlSmall : panorama.url\r\n\t\t} else {\r\n\t\t\treturn panorama.urlSmall // 編輯器頻繁dispose,減少開銷\r\n\t\t}\r\n\t}\r\n\r\n\tdispose() {\r\n\t\tsuper.dispose()\r\n\t\tconsole.log('viewer dispose!')\r\n\t}\r\n\r\n}\r\n\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/viewer/ShelvesBaseViewer.js?");
/***/ }),
@@ -520,7 +520,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SurveyViewer\": () => (/* binding */ SurveyViewer)\n/* harmony export */ });\n/* harmony import */ var _ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n/* harmony import */ var _common_SurveyShelve__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/SurveyShelve */ \"./src/crossyo/shelves/common/SurveyShelve.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.139.2@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.139.2@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var kutsi_shelves_controls_FreeLookControls__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! kutsi-shelves/controls/FreeLookControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookControls.js\");\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! gsap */ \"./node_modules/_gsap@3.11.3@gsap/index.js\");\n/* harmony import */ var _BehaviorQueue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./BehaviorQueue */ \"./src/crossyo/shelves/viewer/BehaviorQueue.js\");\n/* harmony import */ var kutsi_shelves_pp_FrostFar_pp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! kutsi-shelves/pp/FrostFar_pp */ \"./src-kutsi-shelves/crossyo/kutsi/pp/FrostFar_pp.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// const AUTO_ROTATION = true\r\nconst AUTO_ROTATION = false // manually rotation\r\n\r\nclass ManuallyRotationControls {\r\n\r\n constructor({ scene, domElement, focusTarget, behavior }) {\r\n this.scene_ = scene\r\n let fake_cam = new three__WEBPACK_IMPORTED_MODULE_5__.PerspectiveCamera()\r\n this.fake_cam_ = fake_cam\r\n this.behavior_ = behavior\r\n\r\n // USE HELPER!\r\n // this.helper_ = new CameraHelper(fake_cam)\r\n\r\n this.scene_.add(this.helper_)\r\n this.controls_ = new three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_2__.OrbitControls(fake_cam, domElement)\r\n // this.controls_.autoRotate = true\r\n this.controls_.enableDamping = true\r\n this.controls_.enablePan = false\r\n // this.controls_.noPan = true // Trackball\r\n\r\n this.controls_.minPolarAngle = Math.PI / 6\r\n this.controls_.maxPolarAngle = Math.PI * 5 / 6\r\n\r\n this.controls_.minDistance = .1\r\n this.controls_.maxDistance = .4\r\n\r\n this.focusTarget_ = focusTarget\r\n\r\n let tgt = this.focusTarget_.position.clone()\r\n this.controls_.target = tgt\r\n fake_cam.position.copy(new three__WEBPACK_IMPORTED_MODULE_5__.Vector3(0, 0, -.2).add(tgt))\r\n\r\n }\r\n\r\n update(delta) {\r\n this.controls_.update(delta)\r\n let p1 = this.fake_cam_.position\r\n let p0 = this.controls_.target\r\n\r\n let dz = p1.z - p0.z\r\n let dx = p1.x - p0.x\r\n\r\n let xz = Math.sqrt(dz * dz + dx * dx)\r\n\r\n let dist = new three__WEBPACK_IMPORTED_MODULE_5__.Vector3().subVectors(p1, p0).lengthSq()\r\n // console.log(dist) .0\r\n\r\n // .04 1\r\n // .1 \r\n\r\n let s = 1 / Math.sqrt(Math.max(.01, Math.min(dist, .16)) / .04)\r\n\r\n // this.focusTarget_.rotation.set(0, Math.PI / 2 + Math.atan2(dz, dx), Math.atan2(p1.y - p0.y, xz), 'XYZ')\r\n let rz = Math.PI / 2 + Math.atan2(dz, dx) // 左右\r\n let ry = Math.atan2(p1.y - p0.y, xz) // 上下\r\n this.focusTarget_.rotation.set(0, rz, ry, 'XZY')\r\n this.focusTarget_.scale.set(s, s, s)\r\n\r\n let srz = Math.round(rz * 100) / 100\r\n let sry = Math.round(ry * 100) / 100\r\n\r\n this.behavior_.idle_controls_update_(srz, sry, delta)\r\n\r\n }\r\n\r\n reset() {\r\n this.focusTarget_.rotation.set(0, 0, 0, 'XYZ')\r\n this.focusTarget_.scale.set(1, 1, 1)\r\n }\r\n\r\n dispose() {\r\n this.reset()\r\n if (this.helper_) {\r\n this.scene_.remove(this.helper_)\r\n }\r\n this.controls_.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n\r\nclass SurveyViewer extends _ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__.ShelvesBaseViewer {\r\n\r\n constructor(opts) {\r\n super(Object.assign(opts, {\r\n clzPostProcessing: kutsi_shelves_pp_FrostFar_pp__WEBPACK_IMPORTED_MODULE_6__.FrostFar_pp\r\n }))\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n this.renderer_.pp_.default_frost_ = false// true // default true, if clearly load process, set to false\r\n this.renderer_.pp_.grayTend = .25\r\n }\r\n\r\n endLoadSpecs() {\r\n\r\n // super.endLoadSpecs()\r\n // local controller!\r\n\r\n // console.log(this.opts_.shopData.shelf)\r\n this.behavior_ = new _BehaviorQueue__WEBPACK_IMPORTED_MODULE_4__.BehaviorQueue({\r\n viewer: this,\r\n surveyId: this.opts_.surveyId,\r\n shelfId: this.opts_.shopData.shelf.id, // #20221021 之后补充,之前数据没有shelf.id\r\n })\r\n\r\n this.shelve_ = new _common_SurveyShelve__WEBPACK_IMPORTED_MODULE_1__.SurveyShelve(this)\r\n // console.log('MESH SHELF', this.mesh_shelf__)\r\n if (this.shopData_.shelf.hideWhenSurvey) {\r\n // console.log(this.shopData_.shelf)\r\n this.mesh_shelf__.children.filter(c => c.isMesh).forEach(c => c.visible = false)\r\n }\r\n\r\n this.world_space_ = new three__WEBPACK_IMPORTED_MODULE_5__.Object3D()\r\n this.scene_.add(this.world_space_)\r\n\r\n this.hold_ = null\r\n this.hold_null_cd_ = 0 // TEMP\r\n this.cart_ = null\r\n this.picker_.on('downUpPick', e => {\r\n // console.log('downUpPick', e)\r\n\r\n if (this.opt_keepHold__) {\r\n return\r\n }\r\n\r\n this.to_hold_(e)\r\n\r\n })\r\n\r\n this.emit('loadingCompletion')\r\n\r\n }\r\n\r\n to_hold_(e) {\r\n\r\n if (this.hold_null_cd_ > 0) return // TEMP\r\n if (this.hold_ == null) {\r\n if (e.int0) {\r\n // e.int0.object -> Mesh\r\n let m0 = e.int0.object\r\n let m = m0.hit_.targetObject__ // v3.3 #20220730\r\n // console.log(m0, m)\r\n if (m) {\r\n // back_to_shelf_()\r\n\r\n this.controls_.enabled = false\r\n\r\n let mParent = m.parent\r\n this.hold_ = {\r\n // o3d: m,\r\n get_parent_cell() {\r\n return mParent\r\n },\r\n get_o3d() {\r\n return m\r\n },\r\n // position: m.position.clone(),\r\n localPosition: m.position.clone(),\r\n localRotationY: m.rotation.y,\r\n data: m0.hit_,\r\n init_time_: -1, // for rot!\r\n }\r\n\r\n // console.log(this.hold_.get_o3d())\r\n\r\n // m.position.set(.35, 0, 0)\r\n // fly to\r\n\r\n // zoomFov t\t sx\t\tdy\r\n // 1 \t\t0\t 1\t\t0\r\n // .5\t\t1\t 1.5\t\t-0.15\r\n\r\n let t = 2 - this.camera_.zoomFov * 2\r\n\r\n let sx = three__WEBPACK_IMPORTED_MODULE_5__.MathUtils.lerp(1, 1.5, t)\r\n // let dy = MathUtils.lerp(0, -.015, t)\r\n\r\n // let dy = -.1\r\n let dy = -.05 // 视点居中\r\n\r\n // console.log('zoomFov', this.camera_.zoomFov, t, sx, dy)\r\n\r\n this.world_space_.scale.set(1, 1, 1)\r\n this.world_space_.rotation.set(0, 0, 0, 'XYZ')\r\n this.world_space_.position.set(.35 * sx, dy, 0) // #20220930, 设为hold中心一致\r\n this.world_space_.attach(m)\r\n\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(m.position, {\r\n // x: .35 * sx,\r\n // y: dy,\r\n // z: 0,\r\n\r\n x: 0,\r\n y: - .1, // TODO 物体高度的一半\r\n z: 0,\r\n\r\n duration: .4,\r\n onComplete: () => {\r\n // console.log('## hold', this.hold_)\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_4__.BehaviorAction.HOLD,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n if (AUTO_ROTATION) {\r\n\r\n } else {\r\n\r\n // const USE_FREELOOK = true\r\n const USE_FREELOOK = false\r\n if (USE_FREELOOK) {\r\n\r\n this.hold_controls_ = new kutsi_shelves_controls_FreeLookControls__WEBPACK_IMPORTED_MODULE_3__[\"default\"](this.hold_.get_o3d(), this.renderer_.domElement, {\r\n lookDirection: -1,\r\n lookSpeed: 2,\r\n })\r\n this.hold_controls_.target = new three__WEBPACK_IMPORTED_MODULE_5__.Vector3(1, 0, 0).add(this.hold_.get_o3d().position)\r\n\r\n } else {\r\n\r\n this.hold_controls_ = new ManuallyRotationControls({\r\n scene: this.scene_,\r\n domElement: this.renderer_.domElement,\r\n focusTarget: this.world_space_,\r\n behavior: this.behavior_,\r\n })\r\n\r\n }\r\n\r\n }\r\n\r\n }\r\n })\r\n //\r\n\r\n this.emit('hold', this.hold_)\r\n this.hold_null_cd_ = .5 // TEMP\r\n }\r\n }\r\n\r\n } else { // 有 hold\r\n let hold_to_shelf = false\r\n if (e.int0) {// 点中,但不是自己\r\n // e.int0.object -> Mesh\r\n let m0 = e.int0.object\r\n let m = m0.hit_.targetObject__ // v3.3 #20220730\r\n if (this.hold_.get_o3d() != m) {\r\n hold_to_shelf = true\r\n }\r\n } else {\r\n // 没有点中\r\n hold_to_shelf = true\r\n }\r\n\r\n if (hold_to_shelf) {\r\n this.emit('from_scene_hold_to_shelf')\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n before_update_(time, delta) {\r\n // super.before_update_(time, delta)\r\n if (AUTO_ROTATION) {\r\n if (this.hold_) {\r\n if (this.hold_.init_time_ == -1) {\r\n this.hold_.init_time_ = time\r\n }\r\n this.hold_.get_o3d().rotation.set(0, time - this.hold_.init_time_ - Math.PI / 2, 0)\r\n }\r\n\r\n\r\n } else {\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.update(delta)\r\n }\r\n\r\n }\r\n\r\n if (this.hold_null_cd_ > 0) {\r\n this.hold_null_cd_ -= delta\r\n // console.log(this.hold_null_cd_)\r\n }\r\n\r\n // if (this.test_shelf_move__) {\r\n // this.test_shelf_move__.position.z = Math.sin(time)\r\n // }\r\n }\r\n\r\n set elCart(el) {\r\n // console.log('## set elCart', el)\r\n this.el_cart_ = el\r\n }\r\n\r\n calc_cart_target_() {\r\n // console.log('## calc_cart_target_', this.el_cart_, this.cart_plane_)\r\n if (this.el_cart_ && this.cart_plane_) {\r\n\r\n let rect0 = this.renderer_.domElement.getBoundingClientRect()\r\n let rect1 = this.el_cart_.getBoundingClientRect()\r\n\r\n // console.log('update_cart_target_',\r\n // \t// this.el_cart_.getClientRects(),\r\n // \trect0,\r\n // \trect1,\r\n // \tthis.cart_plane_)\r\n\r\n let wpos = new three__WEBPACK_IMPORTED_MODULE_5__.Vector2(\r\n rect1.x + rect1.width / 2 - rect0.x,\r\n rect1.y + rect1.height / 2 - rect0.y\r\n )\r\n\r\n let vpos = new three__WEBPACK_IMPORTED_MODULE_5__.Vector2(\r\n (wpos.x / rect0.width) * 2 - 1,\r\n -(wpos.y / rect0.height) * 2 + 1\r\n )\r\n\r\n // console.log(wpos, vpos)\r\n\r\n let rc = new three__WEBPACK_IMPORTED_MODULE_5__.Raycaster()\r\n rc.setFromCamera(vpos, this.camera_)\r\n return rc.ray.intersectPlane(this.cart_plane_, new three__WEBPACK_IMPORTED_MODULE_5__.Vector3())\r\n\r\n }\r\n\r\n return new three__WEBPACK_IMPORTED_MODULE_5__.Vector3(2, -.55, 1.55) // fall back\r\n }\r\n\r\n // 布置货架内容\r\n arrange(page) {\r\n // console.log(this.shelve_, page)\r\n\r\n this.cart_ = null\r\n if (this.hold_) {// #20220611, 清除前一次可能的hold\r\n let o3d = this.hold_.get_o3d()\r\n o3d.removeFromParent()\r\n }\r\n this.hold_release_()\r\n\r\n return this.shelve_.arrange(page)\r\n }\r\n\r\n action(actionName) {\r\n // console.log('## viewer action', actionName)\r\n if (actionName == 'hold_to_shelf') { // 由按钮激活,改为由场景来操作\r\n if (this.hold_) {\r\n\r\n // this.hold_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.hold_.o3d.position.copy(this.hold_.position)\r\n\r\n // world to local\r\n let o3d = this.hold_.get_o3d()\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.reset()\r\n }\r\n this.hold_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.hold_.localRotationY, 0)\r\n o3d.position.copy(this.hold_.localPosition)\r\n\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_4__.BehaviorAction.PUT_BACK,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n // this.hold_ = null\r\n this.hold_release_()\r\n }\r\n\r\n } else if (actionName == 'hold_to_cart') {\r\n if (this.hold_) {\r\n\r\n if (this.cart_) { // prev\r\n // this.cart_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.cart_.o3d.position.copy(this.cart_.position)\r\n\r\n // world to local\r\n let o3d = this.cart_.get_o3d()\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.reset()\r\n }\r\n this.cart_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.cart_.localRotationY, 0)\r\n o3d.position.copy(this.cart_.localPosition)\r\n\r\n }\r\n\r\n {\r\n this.cart_ = this.hold_\r\n }\r\n\r\n let tgt = this.calc_cart_target_()\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(this.cart_.get_o3d().position, {\r\n x: tgt.x,\r\n y: tgt.y,\r\n z: tgt.z,\r\n duration: .4,\r\n onComplete: () => {\r\n\r\n // this.cart_.o3d.position.set(2, -1, 0) // for debug\r\n this.cart_.get_o3d().position.set(2 - 100, -1 - 100, - 100)\r\n\r\n }\r\n })\r\n\r\n\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_4__.BehaviorAction.PUT_CART,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n // this.hold_ = null\r\n this.hold_release_()\r\n\r\n }\r\n\r\n } else if (actionName == 'try_cart_to_shelf') {\r\n if (this.cart_) {\r\n // this.cart_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.cart_.o3d.position.copy(this.cart_.position)\r\n\r\n // world to local\r\n let o3d = this.cart_.get_o3d()\r\n\r\n this.cart_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.cart_.localRotationY, 0)\r\n o3d.position.copy(this.cart_.localPosition)\r\n\r\n this.cart_ = null\r\n }\r\n }\r\n\r\n }\r\n\r\n hold_release_() {\r\n if (this.hold_controls_) {\r\n this.hold_controls_.dispose()\r\n this.hold_controls_ = null\r\n }\r\n if (this.hold_) {\r\n this.hold_ = null\r\n }\r\n this.controls_.enabled = true\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n }\r\n\r\n // #20221018, hold\r\n // #20221115, frostFarScene\r\n hold({ wareId, keepHold = false, frostFarScene = false }) {\r\n // console.log('hold..', wareId, keepHold)\r\n if (wareId) {\r\n\r\n let arr = this.picker_.hits_.arr\r\n let f_mesh = null\r\n for (let i in arr) {\r\n let mesh = arr[i]\r\n if (mesh.hit_.surveyWare.id == wareId) {\r\n f_mesh = mesh\r\n break\r\n }\r\n }\r\n // console.log(wareId, arr.length, f_mesh)\r\n if (f_mesh) {\r\n this.to_hold_({\r\n int0: {\r\n object: f_mesh\r\n }\r\n })\r\n }\r\n\r\n }\r\n\r\n this.opt_keepHold__ = keepHold\r\n\r\n if (frostFarScene) {\r\n // console.log(this.renderer_.pp_, this.scene_)\r\n // scene sys-env-sphere-, shelf__, \r\n\r\n let sc = this.scene_.children\r\n if (sc.length >= 3) {\r\n\r\n // this.test_shelf_move__ = sc[1]\r\n\r\n let pp = this.renderer_.pp_\r\n pp.beginPass(()=>{\r\n sc[0].visible = true\r\n sc[1].visible = true\r\n sc[2].visible = false\r\n }, ()=>{\r\n sc[0].visible = false\r\n sc[1].visible = false\r\n sc[2].visible = true\r\n })\r\n } else {\r\n console.warn('scene children require to be checked!')\r\n }\r\n \r\n }\r\n\r\n }\r\n\r\n // #20221030\r\n moveToCart({ wareId }) {\r\n\r\n\r\n\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/viewer/SurveyViewer.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SurveyViewer\": () => (/* binding */ SurveyViewer)\n/* harmony export */ });\n/* harmony import */ var _ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ShelvesBaseViewer */ \"./src/crossyo/shelves/viewer/ShelvesBaseViewer.js\");\n/* harmony import */ var _common_SurveyShelve__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common/SurveyShelve */ \"./src/crossyo/shelves/common/SurveyShelve.js\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three */ \"./node_modules/_three@0.146.0@three/build/three.module.js\");\n/* harmony import */ var three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three/examples/jsm/controls/OrbitControls */ \"./node_modules/_three@0.146.0@three/examples/jsm/controls/OrbitControls.js\");\n/* harmony import */ var kutsi_shelves_controls_FreeLookControls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! kutsi-shelves/controls/FreeLookControls */ \"./src-kutsi-shelves/crossyo/kutsi/controls/FreeLookControls.js\");\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! gsap */ \"./node_modules/_gsap@3.11.3@gsap/index.js\");\n/* harmony import */ var _BehaviorQueue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./BehaviorQueue */ \"./src/crossyo/shelves/viewer/BehaviorQueue.js\");\n/* harmony import */ var kutsi_shelves_pp_FrostFar_pp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! kutsi-shelves/pp/FrostFar_pp */ \"./src-kutsi-shelves/crossyo/kutsi/pp/FrostFar_pp.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// const AUTO_ROTATION = true\r\nconst AUTO_ROTATION = false // manually rotation\r\n\r\nclass ManuallyRotationControls {\r\n\r\n constructor({ scene, domElement, focusTarget, behavior }) {\r\n this.scene_ = scene\r\n let fake_cam = new three__WEBPACK_IMPORTED_MODULE_4__.PerspectiveCamera()\r\n this.fake_cam_ = fake_cam\r\n this.behavior_ = behavior\r\n\r\n // USE HELPER!\r\n // this.helper_ = new CameraHelper(fake_cam)\r\n\r\n this.scene_.add(this.helper_)\r\n this.controls_ = new three_examples_jsm_controls_OrbitControls__WEBPACK_IMPORTED_MODULE_5__.OrbitControls(fake_cam, domElement)\r\n // this.controls_.autoRotate = true\r\n this.controls_.enableDamping = true\r\n this.controls_.enablePan = false\r\n // this.controls_.noPan = true // Trackball\r\n\r\n this.controls_.minPolarAngle = Math.PI / 6\r\n this.controls_.maxPolarAngle = Math.PI * 5 / 6\r\n\r\n this.controls_.minDistance = .1\r\n this.controls_.maxDistance = .4\r\n\r\n this.focusTarget_ = focusTarget\r\n\r\n let tgt = this.focusTarget_.position.clone()\r\n this.controls_.target = tgt\r\n fake_cam.position.copy(new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(0, 0, -.2).add(tgt))\r\n\r\n this.enabled_ = true\r\n \r\n }\r\n\r\n get enabled() {\r\n return this.enabled_\r\n }\r\n\r\n set enabled(v) {\r\n this.enabled_ = v\r\n this.controls_.enabled = v\r\n }\r\n\r\n // set rotY(v) {\r\n // console.log('### ManuallyRotationControls set rotY', v)\r\n // }\r\n\r\n update(delta) {\r\n if (!this.enabled_) return\r\n this.controls_.update(delta)\r\n let p1 = this.fake_cam_.position\r\n let p0 = this.controls_.target\r\n\r\n let dz = p1.z - p0.z\r\n let dx = p1.x - p0.x\r\n\r\n let xz = Math.sqrt(dz * dz + dx * dx)\r\n\r\n let dist = new three__WEBPACK_IMPORTED_MODULE_4__.Vector3().subVectors(p1, p0).lengthSq()\r\n // console.log(dist) .0\r\n\r\n // .04 1\r\n // .1 \r\n\r\n let s = 1 / Math.sqrt(Math.max(.01, Math.min(dist, .16)) / .04)\r\n\r\n // this.focusTarget_.rotation.set(0, Math.PI / 2 + Math.atan2(dz, dx), Math.atan2(p1.y - p0.y, xz), 'XYZ')\r\n let rz = Math.PI / 2 + Math.atan2(dz, dx) // 左右\r\n let ry = Math.atan2(p1.y - p0.y, xz) // 上下\r\n this.focusTarget_.rotation.set(0, rz, ry, 'XZY')\r\n this.focusTarget_.scale.set(s, s, s)\r\n\r\n let srz = Math.round(rz * 100) / 100\r\n let sry = Math.round(ry * 100) / 100\r\n\r\n this.behavior_.idle_controls_update_(srz, sry, delta)\r\n\r\n }\r\n\r\n reset() {\r\n this.focusTarget_.rotation.set(0, 0, 0, 'XYZ')\r\n this.focusTarget_.scale.set(1, 1, 1)\r\n }\r\n\r\n dispose() {\r\n this.reset()\r\n if (this.helper_) {\r\n this.scene_.remove(this.helper_)\r\n }\r\n this.controls_.dispose()\r\n }\r\n\r\n}\r\n\r\n\r\n\r\nclass SurveyViewer extends _ShelvesBaseViewer__WEBPACK_IMPORTED_MODULE_0__.ShelvesBaseViewer {\r\n\r\n constructor(opts) {\r\n super(Object.assign(opts, {\r\n clzPostProcessing: kutsi_shelves_pp_FrostFar_pp__WEBPACK_IMPORTED_MODULE_6__.FrostFar_pp\r\n }))\r\n }\r\n\r\n startup() {\r\n super.startup()\r\n this.renderer_.pp_.default_frost_ = false// true // default true, if clearly load process, set to false\r\n this.renderer_.pp_.grayTend = .25\r\n }\r\n\r\n endLoadSpecs() {\r\n\r\n // super.endLoadSpecs()\r\n // local controller!\r\n\r\n // console.log(this.opts_.shopData.shelf)\r\n this.behavior_ = new _BehaviorQueue__WEBPACK_IMPORTED_MODULE_3__.BehaviorQueue({\r\n viewer: this,\r\n surveyId: this.opts_.surveyId,\r\n shelfId: this.opts_.shopData.shelf.id, // #20221021 之后补充,之前数据没有shelf.id\r\n })\r\n\r\n this.shelve_ = new _common_SurveyShelve__WEBPACK_IMPORTED_MODULE_1__.SurveyShelve(this)\r\n // console.log('MESH SHELF', this.mesh_shelf__)\r\n if (this.shopData_.shelf.hideWhenSurvey) {\r\n // console.log(this.shopData_.shelf)\r\n this.mesh_shelf__.children.filter(c => c.isMesh).forEach(c => c.visible = false)\r\n }\r\n\r\n this.world_space_ = new three__WEBPACK_IMPORTED_MODULE_4__.Object3D()\r\n this.scene_.add(this.world_space_)\r\n\r\n this.hold_ = null\r\n this.hold_null_cd_ = 0 // TEMP\r\n this.cart_ = null\r\n this.picker_.on('downUpPick', e => {\r\n // console.log('downUpPick', e)\r\n\r\n if (this.opt_keepHold__) {\r\n return\r\n }\r\n\r\n this.to_hold_(e)\r\n\r\n })\r\n\r\n this.emit('loadingCompletion')\r\n\r\n }\r\n\r\n to_hold_(e) {\r\n\r\n if (this.hold_null_cd_ > 0) return // TEMP\r\n if (this.hold_ == null) {\r\n if (e.int0) {\r\n // e.int0.object -> Mesh\r\n let m0 = e.int0.object\r\n let m = m0.hit_.targetObject__ // v3.3 #20220730\r\n // console.log(m0, m)\r\n if (m) {\r\n // back_to_shelf_()\r\n\r\n this.controls_.enabled = false\r\n\r\n let mParent = m.parent\r\n this.hold_ = {\r\n // o3d: m,\r\n get_parent_cell() {\r\n return mParent\r\n },\r\n get_o3d() {\r\n return m\r\n },\r\n // position: m.position.clone(),\r\n localPosition: m.position.clone(),\r\n localRotationY: m.rotation.y,\r\n data: m0.hit_,\r\n init_time_: -1, // for rot!\r\n }\r\n\r\n // console.log(this.hold_.get_o3d())\r\n\r\n // m.position.set(.35, 0, 0)\r\n // fly to\r\n\r\n // zoomFov t\t sx\t\tdy\r\n // 1 \t\t0\t 1\t\t0\r\n // .5\t\t1\t 1.5\t\t-0.15\r\n\r\n let t = 2 - this.camera_.zoomFov * 2\r\n\r\n let sx = three__WEBPACK_IMPORTED_MODULE_4__.MathUtils.lerp(1, 1.5, t)\r\n // let dy = MathUtils.lerp(0, -.015, t)\r\n\r\n // let dy = -.1\r\n let dy = -.05 // 视点居中\r\n\r\n // console.log('zoomFov', this.camera_.zoomFov, t, sx, dy)\r\n\r\n // console.log('## survey viewer gsap to')\r\n\r\n this.world_space_.scale.set(1, 1, 1)\r\n this.world_space_.rotation.set(0, 0, 0, 'XYZ')\r\n this.world_space_.position.set(.35 * sx, dy, 0) // #20220930, 设为hold中心一致\r\n this.world_space_.attach(m)\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(m.position, {\r\n // x: .35 * sx,\r\n // y: dy,\r\n // z: 0,\r\n\r\n x: 0,\r\n y: - .1, // TODO 物体高度的一半\r\n z: 0,\r\n\r\n duration: .4,\r\n onComplete: () => {\r\n // console.log('## hold', this.hold_)\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_3__.BehaviorAction.HOLD,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n if (AUTO_ROTATION) {\r\n\r\n } else {\r\n\r\n // const USE_FREELOOK = true\r\n const USE_FREELOOK = false\r\n if (USE_FREELOOK) {\r\n\r\n this.hold_controls_ = new kutsi_shelves_controls_FreeLookControls__WEBPACK_IMPORTED_MODULE_2__[\"default\"](this.hold_.get_o3d(), this.renderer_.domElement, {\r\n lookDirection: -1,\r\n lookSpeed: 2,\r\n })\r\n this.hold_controls_.target = new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(1, 0, 0).add(this.hold_.get_o3d().position)\r\n\r\n } else {\r\n\r\n this.hold_controls_ = new ManuallyRotationControls({\r\n scene: this.scene_,\r\n domElement: this.renderer_.domElement,\r\n focusTarget: this.world_space_,\r\n behavior: this.behavior_,\r\n })\r\n if (this.require_hold_controls_opts_) {\r\n if (this.require_hold_controls_opts_.hasOwnProperty('enabled')) {\r\n this.hold_controls_.enabled = this.require_hold_controls_opts_.enabled\r\n }\r\n // if (this.require_hold_controls_opts_.hasOwnProperty('rotY')) {\r\n // this.hold_controls_.rotY = this.require_hold_controls_opts_.rotY\r\n // }\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n }\r\n })\r\n //\r\n\r\n this.emit('hold', this.hold_)\r\n this.hold_null_cd_ = .5 // TEMP\r\n }\r\n }\r\n\r\n } else { // 有 hold\r\n let hold_to_shelf = false\r\n if (e.int0) {// 点中,但不是自己\r\n // e.int0.object -> Mesh\r\n let m0 = e.int0.object\r\n let m = m0.hit_.targetObject__ // v3.3 #20220730\r\n if (this.hold_.get_o3d() != m) {\r\n hold_to_shelf = true\r\n }\r\n } else {\r\n // 没有点中\r\n hold_to_shelf = true\r\n }\r\n\r\n if (hold_to_shelf) {\r\n this.emit('from_scene_hold_to_shelf')\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n before_update_(time, delta) {\r\n // super.before_update_(time, delta)\r\n if (AUTO_ROTATION) {\r\n if (this.hold_) {\r\n if (this.hold_.init_time_ == -1) {\r\n this.hold_.init_time_ = time\r\n }\r\n this.hold_.get_o3d().rotation.set(0, time - this.hold_.init_time_ - Math.PI / 2, 0)\r\n }\r\n\r\n\r\n } else {\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.update(delta)\r\n }\r\n\r\n }\r\n\r\n if (this.hold_null_cd_ > 0) {\r\n this.hold_null_cd_ -= delta\r\n // console.log(this.hold_null_cd_)\r\n }\r\n\r\n // if (this.test_shelf_move__) {\r\n // this.test_shelf_move__.position.z = Math.sin(time)\r\n // }\r\n }\r\n\r\n set elCart(el) {\r\n // console.log('## set elCart', el)\r\n this.el_cart_ = el\r\n }\r\n\r\n calc_cart_target_() {\r\n // console.log('## calc_cart_target_', this.el_cart_, this.cart_plane_)\r\n if (this.el_cart_ && this.cart_plane_) {\r\n\r\n let rect0 = this.renderer_.domElement.getBoundingClientRect()\r\n let rect1 = this.el_cart_.getBoundingClientRect()\r\n\r\n // console.log('update_cart_target_',\r\n // \t// this.el_cart_.getClientRects(),\r\n // \trect0,\r\n // \trect1,\r\n // \tthis.cart_plane_)\r\n\r\n let wpos = new three__WEBPACK_IMPORTED_MODULE_4__.Vector2(\r\n rect1.x + rect1.width / 2 - rect0.x,\r\n rect1.y + rect1.height / 2 - rect0.y\r\n )\r\n\r\n let vpos = new three__WEBPACK_IMPORTED_MODULE_4__.Vector2(\r\n (wpos.x / rect0.width) * 2 - 1,\r\n -(wpos.y / rect0.height) * 2 + 1\r\n )\r\n\r\n // console.log(wpos, vpos)\r\n\r\n let rc = new three__WEBPACK_IMPORTED_MODULE_4__.Raycaster()\r\n rc.setFromCamera(vpos, this.camera_)\r\n return rc.ray.intersectPlane(this.cart_plane_, new three__WEBPACK_IMPORTED_MODULE_4__.Vector3())\r\n\r\n }\r\n\r\n return new three__WEBPACK_IMPORTED_MODULE_4__.Vector3(2, -.55, 1.55) // fall back\r\n }\r\n\r\n // 布置货架内容\r\n arrange(page) {\r\n // console.log(this.shelve_, page)\r\n\r\n this.cart_ = null\r\n if (this.hold_) {// #20220611, 清除前一次可能的hold\r\n let o3d = this.hold_.get_o3d()\r\n o3d.removeFromParent()\r\n }\r\n this.hold_release_()\r\n\r\n return this.shelve_.arrange(page)\r\n }\r\n\r\n action(actionName) {\r\n // console.log('## viewer action', actionName)\r\n if (actionName == 'hold_to_shelf') { // 由按钮激活,改为由场景来操作\r\n if (this.hold_) {\r\n\r\n // this.hold_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.hold_.o3d.position.copy(this.hold_.position)\r\n\r\n // world to local\r\n let o3d = this.hold_.get_o3d()\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.reset()\r\n }\r\n this.hold_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.hold_.localRotationY, 0)\r\n o3d.position.copy(this.hold_.localPosition)\r\n\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_3__.BehaviorAction.PUT_BACK,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n // this.hold_ = null\r\n this.hold_release_()\r\n }\r\n\r\n } else if (actionName == 'hold_to_cart') {\r\n if (this.hold_) {\r\n\r\n if (this.cart_) { // prev\r\n // this.cart_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.cart_.o3d.position.copy(this.cart_.position)\r\n\r\n // world to local\r\n let o3d = this.cart_.get_o3d()\r\n\r\n if (this.hold_controls_) {\r\n this.hold_controls_.reset()\r\n }\r\n this.cart_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.cart_.localRotationY, 0)\r\n o3d.position.copy(this.cart_.localPosition)\r\n\r\n }\r\n\r\n {\r\n this.cart_ = this.hold_\r\n }\r\n\r\n let tgt = this.calc_cart_target_()\r\n gsap__WEBPACK_IMPORTED_MODULE_7__[\"default\"].to(this.cart_.get_o3d().position, {\r\n x: tgt.x,\r\n y: tgt.y,\r\n z: tgt.z,\r\n duration: .4,\r\n onComplete: () => {\r\n\r\n // this.cart_.o3d.position.set(2, -1, 0) // for debug\r\n this.cart_.get_o3d().position.set(2 - 100, -1 - 100, - 100)\r\n\r\n }\r\n })\r\n\r\n\r\n this.behavior_.push({\r\n action: _BehaviorQueue__WEBPACK_IMPORTED_MODULE_3__.BehaviorAction.PUT_CART,\r\n wareId: this.hold_.data.surveyWare.id,\r\n })\r\n\r\n // this.hold_ = null\r\n this.hold_release_()\r\n\r\n }\r\n\r\n } else if (actionName == 'try_cart_to_shelf') {\r\n if (this.cart_) {\r\n // this.cart_.o3d.rotation.set(0, - Math.PI / 2, 0)\r\n // this.cart_.o3d.position.copy(this.cart_.position)\r\n\r\n // world to local\r\n let o3d = this.cart_.get_o3d()\r\n\r\n this.cart_.get_parent_cell().attach(o3d)\r\n\r\n o3d.rotation.set(0, this.cart_.localRotationY, 0)\r\n o3d.position.copy(this.cart_.localPosition)\r\n\r\n this.cart_ = null\r\n }\r\n }\r\n\r\n }\r\n\r\n hold_release_() {\r\n if (this.hold_controls_) {\r\n this.hold_controls_.dispose()\r\n this.hold_controls_ = null\r\n }\r\n if (this.hold_) {\r\n this.hold_ = null\r\n }\r\n this.controls_.enabled = true\r\n }\r\n\r\n dispose() {\r\n super.dispose()\r\n }\r\n\r\n // #20221018, hold\r\n // #20221115, frostFarScene\r\n hold({ wareId, keepHold = false, frostFarScene = false, freezeRotY = NaN }) {\r\n // console.log('hold..', wareId, keepHold)\r\n if (wareId) {\r\n\r\n let arr = this.picker_.hits_.arr\r\n let f_mesh = null\r\n for (let i in arr) {\r\n let mesh = arr[i]\r\n if (mesh.hit_.surveyWare.id == wareId) {\r\n f_mesh = mesh\r\n break\r\n }\r\n }\r\n // console.log(wareId, arr.length, f_mesh)\r\n if (f_mesh) {\r\n this.to_hold_({\r\n int0: {\r\n object: f_mesh\r\n }\r\n })\r\n }\r\n\r\n }\r\n\r\n this.opt_keepHold__ = keepHold\r\n\r\n if (frostFarScene) {\r\n // console.log(this.renderer_.pp_, this.scene_)\r\n // scene sys-env-sphere-, shelf__, \r\n\r\n let sc = this.scene_.children\r\n if (sc.length >= 3) {\r\n\r\n // this.test_shelf_move__ = sc[1]\r\n\r\n let pp = this.renderer_.pp_\r\n pp.beginPass(()=>{\r\n sc[0].visible = true\r\n sc[1].visible = true\r\n sc[2].visible = false\r\n }, ()=>{\r\n sc[0].visible = false\r\n sc[1].visible = false\r\n sc[2].visible = true\r\n })\r\n } else {\r\n console.warn('scene children require to be checked!')\r\n }\r\n \r\n }\r\n\r\n freezeRotY = parseFloat(freezeRotY)\r\n if (!isNaN(freezeRotY)) {\r\n // console.log('## survey viewer freezeRotY', freezeRotY, this.world_space_)\r\n this.require_hold_controls_opts_ = {\r\n enabled: false,\r\n // rotY: freezeRotY / 180 * Math.PI,\r\n }\r\n this.world_space_.children.forEach(c=>{\r\n c.rotation.y += freezeRotY / 180 * Math.PI\r\n })\r\n }\r\n\r\n }\r\n\r\n // #20221030\r\n moveToCart({ wareId }) {\r\n\r\n\r\n\r\n }\r\n\r\n}\r\n\n\n//# sourceURL=webpack://shelves/./src/crossyo/shelves/viewer/SurveyViewer.js?");
/***/ }),
@@ -535,190 +535,190 @@ eval("module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAACAC
/***/ }),
-/***/ "./node_modules/_three@0.139.2@three/build/three.module.js":
+/***/ "./node_modules/_three@0.146.0@three/build/three.module.js":
/*!*****************************************************************!*\
- !*** ./node_modules/_three@0.139.2@three/build/three.module.js ***!
+ !*** ./node_modules/_three@0.146.0@three/build/three.module.js ***!
\*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ACESFilmicToneMapping\": () => (/* binding */ ACESFilmicToneMapping),\n/* harmony export */ \"AddEquation\": () => (/* binding */ AddEquation),\n/* harmony export */ \"AddOperation\": () => (/* binding */ AddOperation),\n/* harmony export */ \"AdditiveAnimationBlendMode\": () => (/* binding */ AdditiveAnimationBlendMode),\n/* harmony export */ \"AdditiveBlending\": () => (/* binding */ AdditiveBlending),\n/* harmony export */ \"AlphaFormat\": () => (/* binding */ AlphaFormat),\n/* harmony export */ \"AlwaysDepth\": () => (/* binding */ AlwaysDepth),\n/* harmony export */ \"AlwaysStencilFunc\": () => (/* binding */ AlwaysStencilFunc),\n/* harmony export */ \"AmbientLight\": () => (/* binding */ AmbientLight),\n/* harmony export */ \"AmbientLightProbe\": () => (/* binding */ AmbientLightProbe),\n/* harmony export */ \"AnimationClip\": () => (/* binding */ AnimationClip),\n/* harmony export */ \"AnimationLoader\": () => (/* binding */ AnimationLoader),\n/* harmony export */ \"AnimationMixer\": () => (/* binding */ AnimationMixer),\n/* harmony export */ \"AnimationObjectGroup\": () => (/* binding */ AnimationObjectGroup),\n/* harmony export */ \"AnimationUtils\": () => (/* binding */ AnimationUtils),\n/* harmony export */ \"ArcCurve\": () => (/* binding */ ArcCurve),\n/* harmony export */ \"ArrayCamera\": () => (/* binding */ ArrayCamera),\n/* harmony export */ \"ArrowHelper\": () => (/* binding */ ArrowHelper),\n/* harmony export */ \"Audio\": () => (/* binding */ Audio),\n/* harmony export */ \"AudioAnalyser\": () => (/* binding */ AudioAnalyser),\n/* harmony export */ \"AudioContext\": () => (/* binding */ AudioContext),\n/* harmony export */ \"AudioListener\": () => (/* binding */ AudioListener),\n/* harmony export */ \"AudioLoader\": () => (/* binding */ AudioLoader),\n/* harmony export */ \"AxesHelper\": () => (/* binding */ AxesHelper),\n/* harmony export */ \"AxisHelper\": () => (/* binding */ AxisHelper),\n/* harmony export */ \"BackSide\": () => (/* binding */ BackSide),\n/* harmony export */ \"BasicDepthPacking\": () => (/* binding */ BasicDepthPacking),\n/* harmony export */ \"BasicShadowMap\": () => (/* binding */ BasicShadowMap),\n/* harmony export */ \"BinaryTextureLoader\": () => (/* binding */ BinaryTextureLoader),\n/* harmony export */ \"Bone\": () => (/* binding */ Bone),\n/* harmony export */ \"BooleanKeyframeTrack\": () => (/* binding */ BooleanKeyframeTrack),\n/* harmony export */ \"BoundingBoxHelper\": () => (/* binding */ BoundingBoxHelper),\n/* harmony export */ \"Box2\": () => (/* binding */ Box2),\n/* harmony export */ \"Box3\": () => (/* binding */ Box3),\n/* harmony export */ \"Box3Helper\": () => (/* binding */ Box3Helper),\n/* harmony export */ \"BoxBufferGeometry\": () => (/* binding */ BoxGeometry),\n/* harmony export */ \"BoxGeometry\": () => (/* binding */ BoxGeometry),\n/* harmony export */ \"BoxHelper\": () => (/* binding */ BoxHelper),\n/* harmony export */ \"BufferAttribute\": () => (/* binding */ BufferAttribute),\n/* harmony export */ \"BufferGeometry\": () => (/* binding */ BufferGeometry),\n/* harmony export */ \"BufferGeometryLoader\": () => (/* binding */ BufferGeometryLoader),\n/* harmony export */ \"ByteType\": () => (/* binding */ ByteType),\n/* harmony export */ \"Cache\": () => (/* binding */ Cache),\n/* harmony export */ \"Camera\": () => (/* binding */ Camera),\n/* harmony export */ \"CameraHelper\": () => (/* binding */ CameraHelper),\n/* harmony export */ \"CanvasRenderer\": () => (/* binding */ CanvasRenderer),\n/* harmony export */ \"CanvasTexture\": () => (/* binding */ CanvasTexture),\n/* harmony export */ \"CapsuleBufferGeometry\": () => (/* binding */ CapsuleGeometry),\n/* harmony export */ \"CapsuleGeometry\": () => (/* binding */ CapsuleGeometry),\n/* harmony export */ \"CatmullRomCurve3\": () => (/* binding */ CatmullRomCurve3),\n/* harmony export */ \"CineonToneMapping\": () => (/* binding */ CineonToneMapping),\n/* harmony export */ \"CircleBufferGeometry\": () => (/* binding */ CircleGeometry),\n/* harmony export */ \"CircleGeometry\": () => (/* binding */ CircleGeometry),\n/* harmony export */ \"ClampToEdgeWrapping\": () => (/* binding */ ClampToEdgeWrapping),\n/* harmony export */ \"Clock\": () => (/* binding */ Clock),\n/* harmony export */ \"Color\": () => (/* binding */ Color),\n/* harmony export */ \"ColorKeyframeTrack\": () => (/* binding */ ColorKeyframeTrack),\n/* harmony export */ \"ColorManagement\": () => (/* binding */ ColorManagement),\n/* harmony export */ \"CompressedTexture\": () => (/* binding */ CompressedTexture),\n/* harmony export */ \"CompressedTextureLoader\": () => (/* binding */ CompressedTextureLoader),\n/* harmony export */ \"ConeBufferGeometry\": () => (/* binding */ ConeGeometry),\n/* harmony export */ \"ConeGeometry\": () => (/* binding */ ConeGeometry),\n/* harmony export */ \"CubeCamera\": () => (/* binding */ CubeCamera),\n/* harmony export */ \"CubeReflectionMapping\": () => (/* binding */ CubeReflectionMapping),\n/* harmony export */ \"CubeRefractionMapping\": () => (/* binding */ CubeRefractionMapping),\n/* harmony export */ \"CubeTexture\": () => (/* binding */ CubeTexture),\n/* harmony export */ \"CubeTextureLoader\": () => (/* binding */ CubeTextureLoader),\n/* harmony export */ \"CubeUVReflectionMapping\": () => (/* binding */ CubeUVReflectionMapping),\n/* harmony export */ \"CubicBezierCurve\": () => (/* binding */ CubicBezierCurve),\n/* harmony export */ \"CubicBezierCurve3\": () => (/* binding */ CubicBezierCurve3),\n/* harmony export */ \"CubicInterpolant\": () => (/* binding */ CubicInterpolant),\n/* harmony export */ \"CullFaceBack\": () => (/* binding */ CullFaceBack),\n/* harmony export */ \"CullFaceFront\": () => (/* binding */ CullFaceFront),\n/* harmony export */ \"CullFaceFrontBack\": () => (/* binding */ CullFaceFrontBack),\n/* harmony export */ \"CullFaceNone\": () => (/* binding */ CullFaceNone),\n/* harmony export */ \"Curve\": () => (/* binding */ Curve),\n/* harmony export */ \"CurvePath\": () => (/* binding */ CurvePath),\n/* harmony export */ \"CustomBlending\": () => (/* binding */ CustomBlending),\n/* harmony export */ \"CustomToneMapping\": () => (/* binding */ CustomToneMapping),\n/* harmony export */ \"CylinderBufferGeometry\": () => (/* binding */ CylinderGeometry),\n/* harmony export */ \"CylinderGeometry\": () => (/* binding */ CylinderGeometry),\n/* harmony export */ \"Cylindrical\": () => (/* binding */ Cylindrical),\n/* harmony export */ \"Data3DTexture\": () => (/* binding */ Data3DTexture),\n/* harmony export */ \"DataArrayTexture\": () => (/* binding */ DataArrayTexture),\n/* harmony export */ \"DataTexture\": () => (/* binding */ DataTexture),\n/* harmony export */ \"DataTexture2DArray\": () => (/* binding */ DataTexture2DArray),\n/* harmony export */ \"DataTexture3D\": () => (/* binding */ DataTexture3D),\n/* harmony export */ \"DataTextureLoader\": () => (/* binding */ DataTextureLoader),\n/* harmony export */ \"DataUtils\": () => (/* binding */ DataUtils),\n/* harmony export */ \"DecrementStencilOp\": () => (/* binding */ DecrementStencilOp),\n/* harmony export */ \"DecrementWrapStencilOp\": () => (/* binding */ DecrementWrapStencilOp),\n/* harmony export */ \"DefaultLoadingManager\": () => (/* binding */ DefaultLoadingManager),\n/* harmony export */ \"DepthFormat\": () => (/* binding */ DepthFormat),\n/* harmony export */ \"DepthStencilFormat\": () => (/* binding */ DepthStencilFormat),\n/* harmony export */ \"DepthTexture\": () => (/* binding */ DepthTexture),\n/* harmony export */ \"DirectionalLight\": () => (/* binding */ DirectionalLight),\n/* harmony export */ \"DirectionalLightHelper\": () => (/* binding */ DirectionalLightHelper),\n/* harmony export */ \"DiscreteInterpolant\": () => (/* binding */ DiscreteInterpolant),\n/* harmony export */ \"DodecahedronBufferGeometry\": () => (/* binding */ DodecahedronGeometry),\n/* harmony export */ \"DodecahedronGeometry\": () => (/* binding */ DodecahedronGeometry),\n/* harmony export */ \"DoubleSide\": () => (/* binding */ DoubleSide),\n/* harmony export */ \"DstAlphaFactor\": () => (/* binding */ DstAlphaFactor),\n/* harmony export */ \"DstColorFactor\": () => (/* binding */ DstColorFactor),\n/* harmony export */ \"DynamicBufferAttribute\": () => (/* binding */ DynamicBufferAttribute),\n/* harmony export */ \"DynamicCopyUsage\": () => (/* binding */ DynamicCopyUsage),\n/* harmony export */ \"DynamicDrawUsage\": () => (/* binding */ DynamicDrawUsage),\n/* harmony export */ \"DynamicReadUsage\": () => (/* binding */ DynamicReadUsage),\n/* harmony export */ \"EdgesGeometry\": () => (/* binding */ EdgesGeometry),\n/* harmony export */ \"EdgesHelper\": () => (/* binding */ EdgesHelper),\n/* harmony export */ \"EllipseCurve\": () => (/* binding */ EllipseCurve),\n/* harmony export */ \"EqualDepth\": () => (/* binding */ EqualDepth),\n/* harmony export */ \"EqualStencilFunc\": () => (/* binding */ EqualStencilFunc),\n/* harmony export */ \"EquirectangularReflectionMapping\": () => (/* binding */ EquirectangularReflectionMapping),\n/* harmony export */ \"EquirectangularRefractionMapping\": () => (/* binding */ EquirectangularRefractionMapping),\n/* harmony export */ \"Euler\": () => (/* binding */ Euler),\n/* harmony export */ \"EventDispatcher\": () => (/* binding */ EventDispatcher),\n/* harmony export */ \"ExtrudeBufferGeometry\": () => (/* binding */ ExtrudeGeometry),\n/* harmony export */ \"ExtrudeGeometry\": () => (/* binding */ ExtrudeGeometry),\n/* harmony export */ \"FaceColors\": () => (/* binding */ FaceColors),\n/* harmony export */ \"FileLoader\": () => (/* binding */ FileLoader),\n/* harmony export */ \"FlatShading\": () => (/* binding */ FlatShading),\n/* harmony export */ \"Float16BufferAttribute\": () => (/* binding */ Float16BufferAttribute),\n/* harmony export */ \"Float32Attribute\": () => (/* binding */ Float32Attribute),\n/* harmony export */ \"Float32BufferAttribute\": () => (/* binding */ Float32BufferAttribute),\n/* harmony export */ \"Float64Attribute\": () => (/* binding */ Float64Attribute),\n/* harmony export */ \"Float64BufferAttribute\": () => (/* binding */ Float64BufferAttribute),\n/* harmony export */ \"FloatType\": () => (/* binding */ FloatType),\n/* harmony export */ \"Fog\": () => (/* binding */ Fog),\n/* harmony export */ \"FogExp2\": () => (/* binding */ FogExp2),\n/* harmony export */ \"Font\": () => (/* binding */ Font),\n/* harmony export */ \"FontLoader\": () => (/* binding */ FontLoader),\n/* harmony export */ \"FramebufferTexture\": () => (/* binding */ FramebufferTexture),\n/* harmony export */ \"FrontSide\": () => (/* binding */ FrontSide),\n/* harmony export */ \"Frustum\": () => (/* binding */ Frustum),\n/* harmony export */ \"GLBufferAttribute\": () => (/* binding */ GLBufferAttribute),\n/* harmony export */ \"GLSL1\": () => (/* binding */ GLSL1),\n/* harmony export */ \"GLSL3\": () => (/* binding */ GLSL3),\n/* harmony export */ \"GreaterDepth\": () => (/* binding */ GreaterDepth),\n/* harmony export */ \"GreaterEqualDepth\": () => (/* binding */ GreaterEqualDepth),\n/* harmony export */ \"GreaterEqualStencilFunc\": () => (/* binding */ GreaterEqualStencilFunc),\n/* harmony export */ \"GreaterStencilFunc\": () => (/* binding */ GreaterStencilFunc),\n/* harmony export */ \"GridHelper\": () => (/* binding */ GridHelper),\n/* harmony export */ \"Group\": () => (/* binding */ Group),\n/* harmony export */ \"HalfFloatType\": () => (/* binding */ HalfFloatType),\n/* harmony export */ \"HemisphereLight\": () => (/* binding */ HemisphereLight),\n/* harmony export */ \"HemisphereLightHelper\": () => (/* binding */ HemisphereLightHelper),\n/* harmony export */ \"HemisphereLightProbe\": () => (/* binding */ HemisphereLightProbe),\n/* harmony export */ \"IcosahedronBufferGeometry\": () => (/* binding */ IcosahedronGeometry),\n/* harmony export */ \"IcosahedronGeometry\": () => (/* binding */ IcosahedronGeometry),\n/* harmony export */ \"ImageBitmapLoader\": () => (/* binding */ ImageBitmapLoader),\n/* harmony export */ \"ImageLoader\": () => (/* binding */ ImageLoader),\n/* harmony export */ \"ImageUtils\": () => (/* binding */ ImageUtils),\n/* harmony export */ \"ImmediateRenderObject\": () => (/* binding */ ImmediateRenderObject),\n/* harmony export */ \"IncrementStencilOp\": () => (/* binding */ IncrementStencilOp),\n/* harmony export */ \"IncrementWrapStencilOp\": () => (/* binding */ IncrementWrapStencilOp),\n/* harmony export */ \"InstancedBufferAttribute\": () => (/* binding */ InstancedBufferAttribute),\n/* harmony export */ \"InstancedBufferGeometry\": () => (/* binding */ InstancedBufferGeometry),\n/* harmony export */ \"InstancedInterleavedBuffer\": () => (/* binding */ InstancedInterleavedBuffer),\n/* harmony export */ \"InstancedMesh\": () => (/* binding */ InstancedMesh),\n/* harmony export */ \"Int16Attribute\": () => (/* binding */ Int16Attribute),\n/* harmony export */ \"Int16BufferAttribute\": () => (/* binding */ Int16BufferAttribute),\n/* harmony export */ \"Int32Attribute\": () => (/* binding */ Int32Attribute),\n/* harmony export */ \"Int32BufferAttribute\": () => (/* binding */ Int32BufferAttribute),\n/* harmony export */ \"Int8Attribute\": () => (/* binding */ Int8Attribute),\n/* harmony export */ \"Int8BufferAttribute\": () => (/* binding */ Int8BufferAttribute),\n/* harmony export */ \"IntType\": () => (/* binding */ IntType),\n/* harmony export */ \"InterleavedBuffer\": () => (/* binding */ InterleavedBuffer),\n/* harmony export */ \"InterleavedBufferAttribute\": () => (/* binding */ InterleavedBufferAttribute),\n/* harmony export */ \"Interpolant\": () => (/* binding */ Interpolant),\n/* harmony export */ \"InterpolateDiscrete\": () => (/* binding */ InterpolateDiscrete),\n/* harmony export */ \"InterpolateLinear\": () => (/* binding */ InterpolateLinear),\n/* harmony export */ \"InterpolateSmooth\": () => (/* binding */ InterpolateSmooth),\n/* harmony export */ \"InvertStencilOp\": () => (/* binding */ InvertStencilOp),\n/* harmony export */ \"JSONLoader\": () => (/* binding */ JSONLoader),\n/* harmony export */ \"KeepStencilOp\": () => (/* binding */ KeepStencilOp),\n/* harmony export */ \"KeyframeTrack\": () => (/* binding */ KeyframeTrack),\n/* harmony export */ \"LOD\": () => (/* binding */ LOD),\n/* harmony export */ \"LatheBufferGeometry\": () => (/* binding */ LatheGeometry),\n/* harmony export */ \"LatheGeometry\": () => (/* binding */ LatheGeometry),\n/* harmony export */ \"Layers\": () => (/* binding */ Layers),\n/* harmony export */ \"LensFlare\": () => (/* binding */ LensFlare),\n/* harmony export */ \"LessDepth\": () => (/* binding */ LessDepth),\n/* harmony export */ \"LessEqualDepth\": () => (/* binding */ LessEqualDepth),\n/* harmony export */ \"LessEqualStencilFunc\": () => (/* binding */ LessEqualStencilFunc),\n/* harmony export */ \"LessStencilFunc\": () => (/* binding */ LessStencilFunc),\n/* harmony export */ \"Light\": () => (/* binding */ Light),\n/* harmony export */ \"LightProbe\": () => (/* binding */ LightProbe),\n/* harmony export */ \"Line\": () => (/* binding */ Line),\n/* harmony export */ \"Line3\": () => (/* binding */ Line3),\n/* harmony export */ \"LineBasicMaterial\": () => (/* binding */ LineBasicMaterial),\n/* harmony export */ \"LineCurve\": () => (/* binding */ LineCurve),\n/* harmony export */ \"LineCurve3\": () => (/* binding */ LineCurve3),\n/* harmony export */ \"LineDashedMaterial\": () => (/* binding */ LineDashedMaterial),\n/* harmony export */ \"LineLoop\": () => (/* binding */ LineLoop),\n/* harmony export */ \"LinePieces\": () => (/* binding */ LinePieces),\n/* harmony export */ \"LineSegments\": () => (/* binding */ LineSegments),\n/* harmony export */ \"LineStrip\": () => (/* binding */ LineStrip),\n/* harmony export */ \"LinearEncoding\": () => (/* binding */ LinearEncoding),\n/* harmony export */ \"LinearFilter\": () => (/* binding */ LinearFilter),\n/* harmony export */ \"LinearInterpolant\": () => (/* binding */ LinearInterpolant),\n/* harmony export */ \"LinearMipMapLinearFilter\": () => (/* binding */ LinearMipMapLinearFilter),\n/* harmony export */ \"LinearMipMapNearestFilter\": () => (/* binding */ LinearMipMapNearestFilter),\n/* harmony export */ \"LinearMipmapLinearFilter\": () => (/* binding */ LinearMipmapLinearFilter),\n/* harmony export */ \"LinearMipmapNearestFilter\": () => (/* binding */ LinearMipmapNearestFilter),\n/* harmony export */ \"LinearSRGBColorSpace\": () => (/* binding */ LinearSRGBColorSpace),\n/* harmony export */ \"LinearToneMapping\": () => (/* binding */ LinearToneMapping),\n/* harmony export */ \"Loader\": () => (/* binding */ Loader),\n/* harmony export */ \"LoaderUtils\": () => (/* binding */ LoaderUtils),\n/* harmony export */ \"LoadingManager\": () => (/* binding */ LoadingManager),\n/* harmony export */ \"LoopOnce\": () => (/* binding */ LoopOnce),\n/* harmony export */ \"LoopPingPong\": () => (/* binding */ LoopPingPong),\n/* harmony export */ \"LoopRepeat\": () => (/* binding */ LoopRepeat),\n/* harmony export */ \"LuminanceAlphaFormat\": () => (/* binding */ LuminanceAlphaFormat),\n/* harmony export */ \"LuminanceFormat\": () => (/* binding */ LuminanceFormat),\n/* harmony export */ \"MOUSE\": () => (/* binding */ MOUSE),\n/* harmony export */ \"Material\": () => (/* binding */ Material),\n/* harmony export */ \"MaterialLoader\": () => (/* binding */ MaterialLoader),\n/* harmony export */ \"Math\": () => (/* binding */ MathUtils),\n/* harmony export */ \"MathUtils\": () => (/* binding */ MathUtils),\n/* harmony export */ \"Matrix3\": () => (/* binding */ Matrix3),\n/* harmony export */ \"Matrix4\": () => (/* binding */ Matrix4),\n/* harmony export */ \"MaxEquation\": () => (/* binding */ MaxEquation),\n/* harmony export */ \"Mesh\": () => (/* binding */ Mesh),\n/* harmony export */ \"MeshBasicMaterial\": () => (/* binding */ MeshBasicMaterial),\n/* harmony export */ \"MeshDepthMaterial\": () => (/* binding */ MeshDepthMaterial),\n/* harmony export */ \"MeshDistanceMaterial\": () => (/* binding */ MeshDistanceMaterial),\n/* harmony export */ \"MeshFaceMaterial\": () => (/* binding */ MeshFaceMaterial),\n/* harmony export */ \"MeshLambertMaterial\": () => (/* binding */ MeshLambertMaterial),\n/* harmony export */ \"MeshMatcapMaterial\": () => (/* binding */ MeshMatcapMaterial),\n/* harmony export */ \"MeshNormalMaterial\": () => (/* binding */ MeshNormalMaterial),\n/* harmony export */ \"MeshPhongMaterial\": () => (/* binding */ MeshPhongMaterial),\n/* harmony export */ \"MeshPhysicalMaterial\": () => (/* binding */ MeshPhysicalMaterial),\n/* harmony export */ \"MeshStandardMaterial\": () => (/* binding */ MeshStandardMaterial),\n/* harmony export */ \"MeshToonMaterial\": () => (/* binding */ MeshToonMaterial),\n/* harmony export */ \"MinEquation\": () => (/* binding */ MinEquation),\n/* harmony export */ \"MirroredRepeatWrapping\": () => (/* binding */ MirroredRepeatWrapping),\n/* harmony export */ \"MixOperation\": () => (/* binding */ MixOperation),\n/* harmony export */ \"MultiMaterial\": () => (/* binding */ MultiMaterial),\n/* harmony export */ \"MultiplyBlending\": () => (/* binding */ MultiplyBlending),\n/* harmony export */ \"MultiplyOperation\": () => (/* binding */ MultiplyOperation),\n/* harmony export */ \"NearestFilter\": () => (/* binding */ NearestFilter),\n/* harmony export */ \"NearestMipMapLinearFilter\": () => (/* binding */ NearestMipMapLinearFilter),\n/* harmony export */ \"NearestMipMapNearestFilter\": () => (/* binding */ NearestMipMapNearestFilter),\n/* harmony export */ \"NearestMipmapLinearFilter\": () => (/* binding */ NearestMipmapLinearFilter),\n/* harmony export */ \"NearestMipmapNearestFilter\": () => (/* binding */ NearestMipmapNearestFilter),\n/* harmony export */ \"NeverDepth\": () => (/* binding */ NeverDepth),\n/* harmony export */ \"NeverStencilFunc\": () => (/* binding */ NeverStencilFunc),\n/* harmony export */ \"NoBlending\": () => (/* binding */ NoBlending),\n/* harmony export */ \"NoColorSpace\": () => (/* binding */ NoColorSpace),\n/* harmony export */ \"NoColors\": () => (/* binding */ NoColors),\n/* harmony export */ \"NoToneMapping\": () => (/* binding */ NoToneMapping),\n/* harmony export */ \"NormalAnimationBlendMode\": () => (/* binding */ NormalAnimationBlendMode),\n/* harmony export */ \"NormalBlending\": () => (/* binding */ NormalBlending),\n/* harmony export */ \"NotEqualDepth\": () => (/* binding */ NotEqualDepth),\n/* harmony export */ \"NotEqualStencilFunc\": () => (/* binding */ NotEqualStencilFunc),\n/* harmony export */ \"NumberKeyframeTrack\": () => (/* binding */ NumberKeyframeTrack),\n/* harmony export */ \"Object3D\": () => (/* binding */ Object3D),\n/* harmony export */ \"ObjectLoader\": () => (/* binding */ ObjectLoader),\n/* harmony export */ \"ObjectSpaceNormalMap\": () => (/* binding */ ObjectSpaceNormalMap),\n/* harmony export */ \"OctahedronBufferGeometry\": () => (/* binding */ OctahedronGeometry),\n/* harmony export */ \"OctahedronGeometry\": () => (/* binding */ OctahedronGeometry),\n/* harmony export */ \"OneFactor\": () => (/* binding */ OneFactor),\n/* harmony export */ \"OneMinusDstAlphaFactor\": () => (/* binding */ OneMinusDstAlphaFactor),\n/* harmony export */ \"OneMinusDstColorFactor\": () => (/* binding */ OneMinusDstColorFactor),\n/* harmony export */ \"OneMinusSrcAlphaFactor\": () => (/* binding */ OneMinusSrcAlphaFactor),\n/* harmony export */ \"OneMinusSrcColorFactor\": () => (/* binding */ OneMinusSrcColorFactor),\n/* harmony export */ \"OrthographicCamera\": () => (/* binding */ OrthographicCamera),\n/* harmony export */ \"PCFShadowMap\": () => (/* binding */ PCFShadowMap),\n/* harmony export */ \"PCFSoftShadowMap\": () => (/* binding */ PCFSoftShadowMap),\n/* harmony export */ \"PMREMGenerator\": () => (/* binding */ PMREMGenerator),\n/* harmony export */ \"ParametricGeometry\": () => (/* binding */ ParametricGeometry),\n/* harmony export */ \"Particle\": () => (/* binding */ Particle),\n/* harmony export */ \"ParticleBasicMaterial\": () => (/* binding */ ParticleBasicMaterial),\n/* harmony export */ \"ParticleSystem\": () => (/* binding */ ParticleSystem),\n/* harmony export */ \"ParticleSystemMaterial\": () => (/* binding */ ParticleSystemMaterial),\n/* harmony export */ \"Path\": () => (/* binding */ Path),\n/* harmony export */ \"PerspectiveCamera\": () => (/* binding */ PerspectiveCamera),\n/* harmony export */ \"Plane\": () => (/* binding */ Plane),\n/* harmony export */ \"PlaneBufferGeometry\": () => (/* binding */ PlaneGeometry),\n/* harmony export */ \"PlaneGeometry\": () => (/* binding */ PlaneGeometry),\n/* harmony export */ \"PlaneHelper\": () => (/* binding */ PlaneHelper),\n/* harmony export */ \"PointCloud\": () => (/* binding */ PointCloud),\n/* harmony export */ \"PointCloudMaterial\": () => (/* binding */ PointCloudMaterial),\n/* harmony export */ \"PointLight\": () => (/* binding */ PointLight),\n/* harmony export */ \"PointLightHelper\": () => (/* binding */ PointLightHelper),\n/* harmony export */ \"Points\": () => (/* binding */ Points),\n/* harmony export */ \"PointsMaterial\": () => (/* binding */ PointsMaterial),\n/* harmony export */ \"PolarGridHelper\": () => (/* binding */ PolarGridHelper),\n/* harmony export */ \"PolyhedronBufferGeometry\": () => (/* binding */ PolyhedronGeometry),\n/* harmony export */ \"PolyhedronGeometry\": () => (/* binding */ PolyhedronGeometry),\n/* harmony export */ \"PositionalAudio\": () => (/* binding */ PositionalAudio),\n/* harmony export */ \"PropertyBinding\": () => (/* binding */ PropertyBinding),\n/* harmony export */ \"PropertyMixer\": () => (/* binding */ PropertyMixer),\n/* harmony export */ \"QuadraticBezierCurve\": () => (/* binding */ QuadraticBezierCurve),\n/* harmony export */ \"QuadraticBezierCurve3\": () => (/* binding */ QuadraticBezierCurve3),\n/* harmony export */ \"Quaternion\": () => (/* binding */ Quaternion),\n/* harmony export */ \"QuaternionKeyframeTrack\": () => (/* binding */ QuaternionKeyframeTrack),\n/* harmony export */ \"QuaternionLinearInterpolant\": () => (/* binding */ QuaternionLinearInterpolant),\n/* harmony export */ \"REVISION\": () => (/* binding */ REVISION),\n/* harmony export */ \"RGBADepthPacking\": () => (/* binding */ RGBADepthPacking),\n/* harmony export */ \"RGBAFormat\": () => (/* binding */ RGBAFormat),\n/* harmony export */ \"RGBAIntegerFormat\": () => (/* binding */ RGBAIntegerFormat),\n/* harmony export */ \"RGBA_ASTC_10x10_Format\": () => (/* binding */ RGBA_ASTC_10x10_Format),\n/* harmony export */ \"RGBA_ASTC_10x5_Format\": () => (/* binding */ RGBA_ASTC_10x5_Format),\n/* harmony export */ \"RGBA_ASTC_10x6_Format\": () => (/* binding */ RGBA_ASTC_10x6_Format),\n/* harmony export */ \"RGBA_ASTC_10x8_Format\": () => (/* binding */ RGBA_ASTC_10x8_Format),\n/* harmony export */ \"RGBA_ASTC_12x10_Format\": () => (/* binding */ RGBA_ASTC_12x10_Format),\n/* harmony export */ \"RGBA_ASTC_12x12_Format\": () => (/* binding */ RGBA_ASTC_12x12_Format),\n/* harmony export */ \"RGBA_ASTC_4x4_Format\": () => (/* binding */ RGBA_ASTC_4x4_Format),\n/* harmony export */ \"RGBA_ASTC_5x4_Format\": () => (/* binding */ RGBA_ASTC_5x4_Format),\n/* harmony export */ \"RGBA_ASTC_5x5_Format\": () => (/* binding */ RGBA_ASTC_5x5_Format),\n/* harmony export */ \"RGBA_ASTC_6x5_Format\": () => (/* binding */ RGBA_ASTC_6x5_Format),\n/* harmony export */ \"RGBA_ASTC_6x6_Format\": () => (/* binding */ RGBA_ASTC_6x6_Format),\n/* harmony export */ \"RGBA_ASTC_8x5_Format\": () => (/* binding */ RGBA_ASTC_8x5_Format),\n/* harmony export */ \"RGBA_ASTC_8x6_Format\": () => (/* binding */ RGBA_ASTC_8x6_Format),\n/* harmony export */ \"RGBA_ASTC_8x8_Format\": () => (/* binding */ RGBA_ASTC_8x8_Format),\n/* harmony export */ \"RGBA_BPTC_Format\": () => (/* binding */ RGBA_BPTC_Format),\n/* harmony export */ \"RGBA_ETC2_EAC_Format\": () => (/* binding */ RGBA_ETC2_EAC_Format),\n/* harmony export */ \"RGBA_PVRTC_2BPPV1_Format\": () => (/* binding */ RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ \"RGBA_PVRTC_4BPPV1_Format\": () => (/* binding */ RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ \"RGBA_S3TC_DXT1_Format\": () => (/* binding */ RGBA_S3TC_DXT1_Format),\n/* harmony export */ \"RGBA_S3TC_DXT3_Format\": () => (/* binding */ RGBA_S3TC_DXT3_Format),\n/* harmony export */ \"RGBA_S3TC_DXT5_Format\": () => (/* binding */ RGBA_S3TC_DXT5_Format),\n/* harmony export */ \"RGBFormat\": () => (/* binding */ RGBFormat),\n/* harmony export */ \"RGB_ETC1_Format\": () => (/* binding */ RGB_ETC1_Format),\n/* harmony export */ \"RGB_ETC2_Format\": () => (/* binding */ RGB_ETC2_Format),\n/* harmony export */ \"RGB_PVRTC_2BPPV1_Format\": () => (/* binding */ RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ \"RGB_PVRTC_4BPPV1_Format\": () => (/* binding */ RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ \"RGB_S3TC_DXT1_Format\": () => (/* binding */ RGB_S3TC_DXT1_Format),\n/* harmony export */ \"RGFormat\": () => (/* binding */ RGFormat),\n/* harmony export */ \"RGIntegerFormat\": () => (/* binding */ RGIntegerFormat),\n/* harmony export */ \"RawShaderMaterial\": () => (/* binding */ RawShaderMaterial),\n/* harmony export */ \"Ray\": () => (/* binding */ Ray),\n/* harmony export */ \"Raycaster\": () => (/* binding */ Raycaster),\n/* harmony export */ \"RectAreaLight\": () => (/* binding */ RectAreaLight),\n/* harmony export */ \"RedFormat\": () => (/* binding */ RedFormat),\n/* harmony export */ \"RedIntegerFormat\": () => (/* binding */ RedIntegerFormat),\n/* harmony export */ \"ReinhardToneMapping\": () => (/* binding */ ReinhardToneMapping),\n/* harmony export */ \"RepeatWrapping\": () => (/* binding */ RepeatWrapping),\n/* harmony export */ \"ReplaceStencilOp\": () => (/* binding */ ReplaceStencilOp),\n/* harmony export */ \"ReverseSubtractEquation\": () => (/* binding */ ReverseSubtractEquation),\n/* harmony export */ \"RingBufferGeometry\": () => (/* binding */ RingGeometry),\n/* harmony export */ \"RingGeometry\": () => (/* binding */ RingGeometry),\n/* harmony export */ \"SRGBColorSpace\": () => (/* binding */ SRGBColorSpace),\n/* harmony export */ \"Scene\": () => (/* binding */ Scene),\n/* harmony export */ \"SceneUtils\": () => (/* binding */ SceneUtils),\n/* harmony export */ \"ShaderChunk\": () => (/* binding */ ShaderChunk),\n/* harmony export */ \"ShaderLib\": () => (/* binding */ ShaderLib),\n/* harmony export */ \"ShaderMaterial\": () => (/* binding */ ShaderMaterial),\n/* harmony export */ \"ShadowMaterial\": () => (/* binding */ ShadowMaterial),\n/* harmony export */ \"Shape\": () => (/* binding */ Shape),\n/* harmony export */ \"ShapeBufferGeometry\": () => (/* binding */ ShapeGeometry),\n/* harmony export */ \"ShapeGeometry\": () => (/* binding */ ShapeGeometry),\n/* harmony export */ \"ShapePath\": () => (/* binding */ ShapePath),\n/* harmony export */ \"ShapeUtils\": () => (/* binding */ ShapeUtils),\n/* harmony export */ \"ShortType\": () => (/* binding */ ShortType),\n/* harmony export */ \"Skeleton\": () => (/* binding */ Skeleton),\n/* harmony export */ \"SkeletonHelper\": () => (/* binding */ SkeletonHelper),\n/* harmony export */ \"SkinnedMesh\": () => (/* binding */ SkinnedMesh),\n/* harmony export */ \"SmoothShading\": () => (/* binding */ SmoothShading),\n/* harmony export */ \"Source\": () => (/* binding */ Source),\n/* harmony export */ \"Sphere\": () => (/* binding */ Sphere),\n/* harmony export */ \"SphereBufferGeometry\": () => (/* binding */ SphereGeometry),\n/* harmony export */ \"SphereGeometry\": () => (/* binding */ SphereGeometry),\n/* harmony export */ \"Spherical\": () => (/* binding */ Spherical),\n/* harmony export */ \"SphericalHarmonics3\": () => (/* binding */ SphericalHarmonics3),\n/* harmony export */ \"SplineCurve\": () => (/* binding */ SplineCurve),\n/* harmony export */ \"SpotLight\": () => (/* binding */ SpotLight),\n/* harmony export */ \"SpotLightHelper\": () => (/* binding */ SpotLightHelper),\n/* harmony export */ \"Sprite\": () => (/* binding */ Sprite),\n/* harmony export */ \"SpriteMaterial\": () => (/* binding */ SpriteMaterial),\n/* harmony export */ \"SrcAlphaFactor\": () => (/* binding */ SrcAlphaFactor),\n/* harmony export */ \"SrcAlphaSaturateFactor\": () => (/* binding */ SrcAlphaSaturateFactor),\n/* harmony export */ \"SrcColorFactor\": () => (/* binding */ SrcColorFactor),\n/* harmony export */ \"StaticCopyUsage\": () => (/* binding */ StaticCopyUsage),\n/* harmony export */ \"StaticDrawUsage\": () => (/* binding */ StaticDrawUsage),\n/* harmony export */ \"StaticReadUsage\": () => (/* binding */ StaticReadUsage),\n/* harmony export */ \"StereoCamera\": () => (/* binding */ StereoCamera),\n/* harmony export */ \"StreamCopyUsage\": () => (/* binding */ StreamCopyUsage),\n/* harmony export */ \"StreamDrawUsage\": () => (/* binding */ StreamDrawUsage),\n/* harmony export */ \"StreamReadUsage\": () => (/* binding */ StreamReadUsage),\n/* harmony export */ \"StringKeyframeTrack\": () => (/* binding */ StringKeyframeTrack),\n/* harmony export */ \"SubtractEquation\": () => (/* binding */ SubtractEquation),\n/* harmony export */ \"SubtractiveBlending\": () => (/* binding */ SubtractiveBlending),\n/* harmony export */ \"TOUCH\": () => (/* binding */ TOUCH),\n/* harmony export */ \"TangentSpaceNormalMap\": () => (/* binding */ TangentSpaceNormalMap),\n/* harmony export */ \"TetrahedronBufferGeometry\": () => (/* binding */ TetrahedronGeometry),\n/* harmony export */ \"TetrahedronGeometry\": () => (/* binding */ TetrahedronGeometry),\n/* harmony export */ \"TextGeometry\": () => (/* binding */ TextGeometry),\n/* harmony export */ \"Texture\": () => (/* binding */ Texture),\n/* harmony export */ \"TextureLoader\": () => (/* binding */ TextureLoader),\n/* harmony export */ \"TorusBufferGeometry\": () => (/* binding */ TorusGeometry),\n/* harmony export */ \"TorusGeometry\": () => (/* binding */ TorusGeometry),\n/* harmony export */ \"TorusKnotBufferGeometry\": () => (/* binding */ TorusKnotGeometry),\n/* harmony export */ \"TorusKnotGeometry\": () => (/* binding */ TorusKnotGeometry),\n/* harmony export */ \"Triangle\": () => (/* binding */ Triangle),\n/* harmony export */ \"TriangleFanDrawMode\": () => (/* binding */ TriangleFanDrawMode),\n/* harmony export */ \"TriangleStripDrawMode\": () => (/* binding */ TriangleStripDrawMode),\n/* harmony export */ \"TrianglesDrawMode\": () => (/* binding */ TrianglesDrawMode),\n/* harmony export */ \"TubeBufferGeometry\": () => (/* binding */ TubeGeometry),\n/* harmony export */ \"TubeGeometry\": () => (/* binding */ TubeGeometry),\n/* harmony export */ \"UVMapping\": () => (/* binding */ UVMapping),\n/* harmony export */ \"Uint16Attribute\": () => (/* binding */ Uint16Attribute),\n/* harmony export */ \"Uint16BufferAttribute\": () => (/* binding */ Uint16BufferAttribute),\n/* harmony export */ \"Uint32Attribute\": () => (/* binding */ Uint32Attribute),\n/* harmony export */ \"Uint32BufferAttribute\": () => (/* binding */ Uint32BufferAttribute),\n/* harmony export */ \"Uint8Attribute\": () => (/* binding */ Uint8Attribute),\n/* harmony export */ \"Uint8BufferAttribute\": () => (/* binding */ Uint8BufferAttribute),\n/* harmony export */ \"Uint8ClampedAttribute\": () => (/* binding */ Uint8ClampedAttribute),\n/* harmony export */ \"Uint8ClampedBufferAttribute\": () => (/* binding */ Uint8ClampedBufferAttribute),\n/* harmony export */ \"Uniform\": () => (/* binding */ Uniform),\n/* harmony export */ \"UniformsLib\": () => (/* binding */ UniformsLib),\n/* harmony export */ \"UniformsUtils\": () => (/* binding */ UniformsUtils),\n/* harmony export */ \"UnsignedByteType\": () => (/* binding */ UnsignedByteType),\n/* harmony export */ \"UnsignedInt248Type\": () => (/* binding */ UnsignedInt248Type),\n/* harmony export */ \"UnsignedIntType\": () => (/* binding */ UnsignedIntType),\n/* harmony export */ \"UnsignedShort4444Type\": () => (/* binding */ UnsignedShort4444Type),\n/* harmony export */ \"UnsignedShort5551Type\": () => (/* binding */ UnsignedShort5551Type),\n/* harmony export */ \"UnsignedShortType\": () => (/* binding */ UnsignedShortType),\n/* harmony export */ \"VSMShadowMap\": () => (/* binding */ VSMShadowMap),\n/* harmony export */ \"Vector2\": () => (/* binding */ Vector2),\n/* harmony export */ \"Vector3\": () => (/* binding */ Vector3),\n/* harmony export */ \"Vector4\": () => (/* binding */ Vector4),\n/* harmony export */ \"VectorKeyframeTrack\": () => (/* binding */ VectorKeyframeTrack),\n/* harmony export */ \"Vertex\": () => (/* binding */ Vertex),\n/* harmony export */ \"VertexColors\": () => (/* binding */ VertexColors),\n/* harmony export */ \"VideoTexture\": () => (/* binding */ VideoTexture),\n/* harmony export */ \"WebGL1Renderer\": () => (/* binding */ WebGL1Renderer),\n/* harmony export */ \"WebGL3DRenderTarget\": () => (/* binding */ WebGL3DRenderTarget),\n/* harmony export */ \"WebGLArrayRenderTarget\": () => (/* binding */ WebGLArrayRenderTarget),\n/* harmony export */ \"WebGLCubeRenderTarget\": () => (/* binding */ WebGLCubeRenderTarget),\n/* harmony export */ \"WebGLMultipleRenderTargets\": () => (/* binding */ WebGLMultipleRenderTargets),\n/* harmony export */ \"WebGLMultisampleRenderTarget\": () => (/* binding */ WebGLMultisampleRenderTarget),\n/* harmony export */ \"WebGLRenderTarget\": () => (/* binding */ WebGLRenderTarget),\n/* harmony export */ \"WebGLRenderTargetCube\": () => (/* binding */ WebGLRenderTargetCube),\n/* harmony export */ \"WebGLRenderer\": () => (/* binding */ WebGLRenderer),\n/* harmony export */ \"WebGLUtils\": () => (/* binding */ WebGLUtils),\n/* harmony export */ \"WireframeGeometry\": () => (/* binding */ WireframeGeometry),\n/* harmony export */ \"WireframeHelper\": () => (/* binding */ WireframeHelper),\n/* harmony export */ \"WrapAroundEnding\": () => (/* binding */ WrapAroundEnding),\n/* harmony export */ \"XHRLoader\": () => (/* binding */ XHRLoader),\n/* harmony export */ \"ZeroCurvatureEnding\": () => (/* binding */ ZeroCurvatureEnding),\n/* harmony export */ \"ZeroFactor\": () => (/* binding */ ZeroFactor),\n/* harmony export */ \"ZeroSlopeEnding\": () => (/* binding */ ZeroSlopeEnding),\n/* harmony export */ \"ZeroStencilOp\": () => (/* binding */ ZeroStencilOp),\n/* harmony export */ \"_SRGBAFormat\": () => (/* binding */ _SRGBAFormat),\n/* harmony export */ \"sRGBEncoding\": () => (/* binding */ sRGBEncoding)\n/* harmony export */ });\n/**\n * @license\n * Copyright 2010-2022 Three.js Authors\n * SPDX-License-Identifier: MIT\n */\nconst REVISION = '139';\nconst MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };\nconst TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };\nconst CullFaceNone = 0;\nconst CullFaceBack = 1;\nconst CullFaceFront = 2;\nconst CullFaceFrontBack = 3;\nconst BasicShadowMap = 0;\nconst PCFShadowMap = 1;\nconst PCFSoftShadowMap = 2;\nconst VSMShadowMap = 3;\nconst FrontSide = 0;\nconst BackSide = 1;\nconst DoubleSide = 2;\nconst FlatShading = 1;\nconst SmoothShading = 2;\nconst NoBlending = 0;\nconst NormalBlending = 1;\nconst AdditiveBlending = 2;\nconst SubtractiveBlending = 3;\nconst MultiplyBlending = 4;\nconst CustomBlending = 5;\nconst AddEquation = 100;\nconst SubtractEquation = 101;\nconst ReverseSubtractEquation = 102;\nconst MinEquation = 103;\nconst MaxEquation = 104;\nconst ZeroFactor = 200;\nconst OneFactor = 201;\nconst SrcColorFactor = 202;\nconst OneMinusSrcColorFactor = 203;\nconst SrcAlphaFactor = 204;\nconst OneMinusSrcAlphaFactor = 205;\nconst DstAlphaFactor = 206;\nconst OneMinusDstAlphaFactor = 207;\nconst DstColorFactor = 208;\nconst OneMinusDstColorFactor = 209;\nconst SrcAlphaSaturateFactor = 210;\nconst NeverDepth = 0;\nconst AlwaysDepth = 1;\nconst LessDepth = 2;\nconst LessEqualDepth = 3;\nconst EqualDepth = 4;\nconst GreaterEqualDepth = 5;\nconst GreaterDepth = 6;\nconst NotEqualDepth = 7;\nconst MultiplyOperation = 0;\nconst MixOperation = 1;\nconst AddOperation = 2;\nconst NoToneMapping = 0;\nconst LinearToneMapping = 1;\nconst ReinhardToneMapping = 2;\nconst CineonToneMapping = 3;\nconst ACESFilmicToneMapping = 4;\nconst CustomToneMapping = 5;\n\nconst UVMapping = 300;\nconst CubeReflectionMapping = 301;\nconst CubeRefractionMapping = 302;\nconst EquirectangularReflectionMapping = 303;\nconst EquirectangularRefractionMapping = 304;\nconst CubeUVReflectionMapping = 306;\nconst RepeatWrapping = 1000;\nconst ClampToEdgeWrapping = 1001;\nconst MirroredRepeatWrapping = 1002;\nconst NearestFilter = 1003;\nconst NearestMipmapNearestFilter = 1004;\nconst NearestMipMapNearestFilter = 1004;\nconst NearestMipmapLinearFilter = 1005;\nconst NearestMipMapLinearFilter = 1005;\nconst LinearFilter = 1006;\nconst LinearMipmapNearestFilter = 1007;\nconst LinearMipMapNearestFilter = 1007;\nconst LinearMipmapLinearFilter = 1008;\nconst LinearMipMapLinearFilter = 1008;\nconst UnsignedByteType = 1009;\nconst ByteType = 1010;\nconst ShortType = 1011;\nconst UnsignedShortType = 1012;\nconst IntType = 1013;\nconst UnsignedIntType = 1014;\nconst FloatType = 1015;\nconst HalfFloatType = 1016;\nconst UnsignedShort4444Type = 1017;\nconst UnsignedShort5551Type = 1018;\nconst UnsignedInt248Type = 1020;\nconst AlphaFormat = 1021;\nconst RGBFormat = 1022;\nconst RGBAFormat = 1023;\nconst LuminanceFormat = 1024;\nconst LuminanceAlphaFormat = 1025;\nconst DepthFormat = 1026;\nconst DepthStencilFormat = 1027;\nconst RedFormat = 1028;\nconst RedIntegerFormat = 1029;\nconst RGFormat = 1030;\nconst RGIntegerFormat = 1031;\nconst RGBAIntegerFormat = 1033;\n\nconst RGB_S3TC_DXT1_Format = 33776;\nconst RGBA_S3TC_DXT1_Format = 33777;\nconst RGBA_S3TC_DXT3_Format = 33778;\nconst RGBA_S3TC_DXT5_Format = 33779;\nconst RGB_PVRTC_4BPPV1_Format = 35840;\nconst RGB_PVRTC_2BPPV1_Format = 35841;\nconst RGBA_PVRTC_4BPPV1_Format = 35842;\nconst RGBA_PVRTC_2BPPV1_Format = 35843;\nconst RGB_ETC1_Format = 36196;\nconst RGB_ETC2_Format = 37492;\nconst RGBA_ETC2_EAC_Format = 37496;\nconst RGBA_ASTC_4x4_Format = 37808;\nconst RGBA_ASTC_5x4_Format = 37809;\nconst RGBA_ASTC_5x5_Format = 37810;\nconst RGBA_ASTC_6x5_Format = 37811;\nconst RGBA_ASTC_6x6_Format = 37812;\nconst RGBA_ASTC_8x5_Format = 37813;\nconst RGBA_ASTC_8x6_Format = 37814;\nconst RGBA_ASTC_8x8_Format = 37815;\nconst RGBA_ASTC_10x5_Format = 37816;\nconst RGBA_ASTC_10x6_Format = 37817;\nconst RGBA_ASTC_10x8_Format = 37818;\nconst RGBA_ASTC_10x10_Format = 37819;\nconst RGBA_ASTC_12x10_Format = 37820;\nconst RGBA_ASTC_12x12_Format = 37821;\nconst RGBA_BPTC_Format = 36492;\nconst LoopOnce = 2200;\nconst LoopRepeat = 2201;\nconst LoopPingPong = 2202;\nconst InterpolateDiscrete = 2300;\nconst InterpolateLinear = 2301;\nconst InterpolateSmooth = 2302;\nconst ZeroCurvatureEnding = 2400;\nconst ZeroSlopeEnding = 2401;\nconst WrapAroundEnding = 2402;\nconst NormalAnimationBlendMode = 2500;\nconst AdditiveAnimationBlendMode = 2501;\nconst TrianglesDrawMode = 0;\nconst TriangleStripDrawMode = 1;\nconst TriangleFanDrawMode = 2;\nconst LinearEncoding = 3000;\nconst sRGBEncoding = 3001;\nconst BasicDepthPacking = 3200;\nconst RGBADepthPacking = 3201;\nconst TangentSpaceNormalMap = 0;\nconst ObjectSpaceNormalMap = 1;\n\n// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.\nconst NoColorSpace = '';\nconst SRGBColorSpace = 'srgb';\nconst LinearSRGBColorSpace = 'srgb-linear';\n\nconst ZeroStencilOp = 0;\nconst KeepStencilOp = 7680;\nconst ReplaceStencilOp = 7681;\nconst IncrementStencilOp = 7682;\nconst DecrementStencilOp = 7683;\nconst IncrementWrapStencilOp = 34055;\nconst DecrementWrapStencilOp = 34056;\nconst InvertStencilOp = 5386;\n\nconst NeverStencilFunc = 512;\nconst LessStencilFunc = 513;\nconst EqualStencilFunc = 514;\nconst LessEqualStencilFunc = 515;\nconst GreaterStencilFunc = 516;\nconst NotEqualStencilFunc = 517;\nconst GreaterEqualStencilFunc = 518;\nconst AlwaysStencilFunc = 519;\n\nconst StaticDrawUsage = 35044;\nconst DynamicDrawUsage = 35048;\nconst StreamDrawUsage = 35040;\nconst StaticReadUsage = 35045;\nconst DynamicReadUsage = 35049;\nconst StreamReadUsage = 35041;\nconst StaticCopyUsage = 35046;\nconst DynamicCopyUsage = 35050;\nconst StreamCopyUsage = 35042;\n\nconst GLSL1 = '100';\nconst GLSL3 = '300 es';\n\nconst _SRGBAFormat = 1035; // fallback for WebGL 1\n\n/**\n * https://github.com/mrdoob/eventdispatcher.js/\n */\n\nclass EventDispatcher {\n\n\taddEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\tconst listeners = this._listeners;\n\n\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\tlisteners[ type ] = [];\n\n\t\t}\n\n\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\tlisteners[ type ].push( listener );\n\n\t\t}\n\n\t}\n\n\thasEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) return false;\n\n\t\tconst listeners = this._listeners;\n\n\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t}\n\n\tremoveEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) return;\n\n\t\tconst listeners = this._listeners;\n\t\tconst listenerArray = listeners[ type ];\n\n\t\tif ( listenerArray !== undefined ) {\n\n\t\t\tconst index = listenerArray.indexOf( listener );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tdispatchEvent( event ) {\n\n\t\tif ( this._listeners === undefined ) return;\n\n\t\tconst listeners = this._listeners;\n\t\tconst listenerArray = listeners[ event.type ];\n\n\t\tif ( listenerArray !== undefined ) {\n\n\t\t\tevent.target = this;\n\n\t\t\t// Make a copy, in case listeners are removed while iterating.\n\t\t\tconst array = listenerArray.slice( 0 );\n\n\t\t\tfor ( let i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t}\n\n\t\t\tevent.target = null;\n\n\t\t}\n\n\t}\n\n}\n\nconst _lut = [];\n\nfor ( let i = 0; i < 256; i ++ ) {\n\n\t_lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );\n\n}\n\nlet _seed = 1234567;\n\n\nconst DEG2RAD = Math.PI / 180;\nconst RAD2DEG = 180 / Math.PI;\n\n// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136\nfunction generateUUID() {\n\n\tconst d0 = Math.random() * 0xffffffff | 0;\n\tconst d1 = Math.random() * 0xffffffff | 0;\n\tconst d2 = Math.random() * 0xffffffff | 0;\n\tconst d3 = Math.random() * 0xffffffff | 0;\n\tconst uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' +\n\t\t\t_lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' +\n\t\t\t_lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] +\n\t\t\t_lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ];\n\n\t// .toLowerCase() here flattens concatenated strings to save heap memory space.\n\treturn uuid.toLowerCase();\n\n}\n\nfunction clamp( value, min, max ) {\n\n\treturn Math.max( min, Math.min( max, value ) );\n\n}\n\n// compute euclidean modulo of m % n\n// https://en.wikipedia.org/wiki/Modulo_operation\nfunction euclideanModulo( n, m ) {\n\n\treturn ( ( n % m ) + m ) % m;\n\n}\n\n// Linear mapping from range to range \nfunction mapLinear( x, a1, a2, b1, b2 ) {\n\n\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n}\n\n// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/\nfunction inverseLerp( x, y, value ) {\n\n\tif ( x !== y ) {\n\n\t\treturn ( value - x ) / ( y - x );\n\n\t} else {\n\n\t\treturn 0;\n\n\t}\n\n}\n\n// https://en.wikipedia.org/wiki/Linear_interpolation\nfunction lerp( x, y, t ) {\n\n\treturn ( 1 - t ) * x + t * y;\n\n}\n\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\nfunction damp( x, y, lambda, dt ) {\n\n\treturn lerp( x, y, 1 - Math.exp( - lambda * dt ) );\n\n}\n\n// https://www.desmos.com/calculator/vcsjnyz7x4\nfunction pingpong( x, length = 1 ) {\n\n\treturn length - Math.abs( euclideanModulo( x, length * 2 ) - length );\n\n}\n\n// http://en.wikipedia.org/wiki/Smoothstep\nfunction smoothstep( x, min, max ) {\n\n\tif ( x <= min ) return 0;\n\tif ( x >= max ) return 1;\n\n\tx = ( x - min ) / ( max - min );\n\n\treturn x * x * ( 3 - 2 * x );\n\n}\n\nfunction smootherstep( x, min, max ) {\n\n\tif ( x <= min ) return 0;\n\tif ( x >= max ) return 1;\n\n\tx = ( x - min ) / ( max - min );\n\n\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n}\n\n// Random integer from interval\nfunction randInt( low, high ) {\n\n\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n}\n\n// Random float from interval\nfunction randFloat( low, high ) {\n\n\treturn low + Math.random() * ( high - low );\n\n}\n\n// Random float from <-range/2, range/2> interval\nfunction randFloatSpread( range ) {\n\n\treturn range * ( 0.5 - Math.random() );\n\n}\n\n// Deterministic pseudo-random float in the interval [ 0, 1 ]\nfunction seededRandom( s ) {\n\n\tif ( s !== undefined ) _seed = s;\n\n\t// Mulberry32 generator\n\n\tlet t = _seed += 0x6D2B79F5;\n\n\tt = Math.imul( t ^ t >>> 15, t | 1 );\n\n\tt ^= t + Math.imul( t ^ t >>> 7, t | 61 );\n\n\treturn ( ( t ^ t >>> 14 ) >>> 0 ) / 4294967296;\n\n}\n\nfunction degToRad( degrees ) {\n\n\treturn degrees * DEG2RAD;\n\n}\n\nfunction radToDeg( radians ) {\n\n\treturn radians * RAD2DEG;\n\n}\n\nfunction isPowerOfTwo( value ) {\n\n\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n}\n\nfunction ceilPowerOfTwo( value ) {\n\n\treturn Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );\n\n}\n\nfunction floorPowerOfTwo( value ) {\n\n\treturn Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );\n\n}\n\nfunction setQuaternionFromProperEuler( q, a, b, c, order ) {\n\n\t// Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles\n\n\t// rotations are applied to the axes in the order specified by 'order'\n\t// rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'\n\t// angles are in radians\n\n\tconst cos = Math.cos;\n\tconst sin = Math.sin;\n\n\tconst c2 = cos( b / 2 );\n\tconst s2 = sin( b / 2 );\n\n\tconst c13 = cos( ( a + c ) / 2 );\n\tconst s13 = sin( ( a + c ) / 2 );\n\n\tconst c1_3 = cos( ( a - c ) / 2 );\n\tconst s1_3 = sin( ( a - c ) / 2 );\n\n\tconst c3_1 = cos( ( c - a ) / 2 );\n\tconst s3_1 = sin( ( c - a ) / 2 );\n\n\tswitch ( order ) {\n\n\t\tcase 'XYX':\n\t\t\tq.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'YZY':\n\t\t\tq.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'ZXZ':\n\t\t\tq.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'XZX':\n\t\t\tq.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'YXY':\n\t\t\tq.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'ZYZ':\n\t\t\tq.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tconsole.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );\n\n\t}\n\n}\n\nfunction denormalize$1( value, array ) {\n\n\tswitch ( array.constructor ) {\n\n\t\tcase Float32Array:\n\n\t\t\treturn value;\n\n\t\tcase Uint16Array:\n\n\t\t\treturn value / 65535.0;\n\n\t\tcase Uint8Array:\n\n\t\t\treturn value / 255.0;\n\n\t\tcase Int16Array:\n\n\t\t\treturn Math.max( value / 32767.0, - 1.0 );\n\n\t\tcase Int8Array:\n\n\t\t\treturn Math.max( value / 127.0, - 1.0 );\n\n\t\tdefault:\n\n\t\t\tthrow new Error( 'Invalid component type.' );\n\n\t}\n\n}\n\nfunction normalize( value, array ) {\n\n\tswitch ( array.constructor ) {\n\n\t\tcase Float32Array:\n\n\t\t\treturn value;\n\n\t\tcase Uint16Array:\n\n\t\t\treturn Math.round( value * 65535.0 );\n\n\t\tcase Uint8Array:\n\n\t\t\treturn Math.round( value * 255.0 );\n\n\t\tcase Int16Array:\n\n\t\t\treturn Math.round( value * 32767.0 );\n\n\t\tcase Int8Array:\n\n\t\t\treturn Math.round( value * 127.0 );\n\n\t\tdefault:\n\n\t\t\tthrow new Error( 'Invalid component type.' );\n\n\t}\n\n}\n\nvar MathUtils = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tDEG2RAD: DEG2RAD,\n\tRAD2DEG: RAD2DEG,\n\tgenerateUUID: generateUUID,\n\tclamp: clamp,\n\teuclideanModulo: euclideanModulo,\n\tmapLinear: mapLinear,\n\tinverseLerp: inverseLerp,\n\tlerp: lerp,\n\tdamp: damp,\n\tpingpong: pingpong,\n\tsmoothstep: smoothstep,\n\tsmootherstep: smootherstep,\n\trandInt: randInt,\n\trandFloat: randFloat,\n\trandFloatSpread: randFloatSpread,\n\tseededRandom: seededRandom,\n\tdegToRad: degToRad,\n\tradToDeg: radToDeg,\n\tisPowerOfTwo: isPowerOfTwo,\n\tceilPowerOfTwo: ceilPowerOfTwo,\n\tfloorPowerOfTwo: floorPowerOfTwo,\n\tsetQuaternionFromProperEuler: setQuaternionFromProperEuler,\n\tnormalize: normalize,\n\tdenormalize: denormalize$1\n});\n\nclass Vector2 {\n\n\tconstructor( x = 0, y = 0 ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\n\t}\n\n\tget width() {\n\n\t\treturn this.x;\n\n\t}\n\n\tset width( value ) {\n\n\t\tthis.x = value;\n\n\t}\n\n\tget height() {\n\n\t\treturn this.y;\n\n\t}\n\n\tset height( value ) {\n\n\t\tthis.y = value;\n\n\t}\n\n\tset( x, y ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v ) {\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tdivide( v ) {\n\n\t\tthis.x /= v.x;\n\t\tthis.y /= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tconst x = this.x, y = this.y;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];\n\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];\n\n\t\treturn this;\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y;\n\n\t}\n\n\tcross( v ) {\n\n\t\treturn this.x * v.y - this.y * v.x;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tangle() {\n\n\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\tconst angle = Math.atan2( - this.y, - this.x ) + Math.PI;\n\n\t\treturn angle;\n\n\t}\n\n\tdistanceTo( v ) {\n\n\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t}\n\n\tdistanceToSquared( v ) {\n\n\t\tconst dx = this.x - v.x, dy = this.y - v.y;\n\t\treturn dx * dx + dy * dy;\n\n\t}\n\n\tmanhattanDistanceTo( v ) {\n\n\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\n\t\treturn this;\n\n\t}\n\n\trotateAround( center, angle ) {\n\n\t\tconst c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\tconst x = this.x - center.x;\n\t\tconst y = this.y - center.y;\n\n\t\tthis.x = x * c - y * s + center.x;\n\t\tthis.y = x * s + y * c + center.y;\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\n\t}\n\n}\n\nVector2.prototype.isVector2 = true;\n\nclass Matrix3 {\n\n\tconstructor() {\n\n\t\tthis.elements = [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t];\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tset( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tcopy( m ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tte[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];\n\t\tte[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];\n\t\tte[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\textractBasis( xAxis, yAxis, zAxis ) {\n\n\t\txAxis.setFromMatrix3Column( this, 0 );\n\t\tyAxis.setFromMatrix3Column( this, 1 );\n\t\tzAxis.setFromMatrix3Column( this, 2 );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrix4( m ) {\n\n\t\tconst me = m.elements;\n\n\t\tthis.set(\n\n\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( m ) {\n\n\t\treturn this.multiplyMatrices( this, m );\n\n\t}\n\n\tpremultiply( m ) {\n\n\t\treturn this.multiplyMatrices( m, this );\n\n\t}\n\n\tmultiplyMatrices( a, b ) {\n\n\t\tconst ae = a.elements;\n\t\tconst be = b.elements;\n\t\tconst te = this.elements;\n\n\t\tconst a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];\n\t\tconst a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];\n\t\tconst a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];\n\n\t\tconst b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];\n\t\tconst b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];\n\t\tconst b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];\n\n\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;\n\t\tte[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;\n\t\tte[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;\n\n\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;\n\t\tte[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;\n\t\tte[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;\n\n\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;\n\t\tte[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;\n\t\tte[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\treturn this;\n\n\t}\n\n\tdeterminant() {\n\n\t\tconst te = this.elements;\n\n\t\tconst a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t}\n\n\tinvert() {\n\n\t\tconst te = this.elements,\n\n\t\t\tn11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ],\n\t\t\tn12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ],\n\t\t\tn13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ],\n\n\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\tif ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );\n\n\t\tconst detInv = 1 / det;\n\n\t\tte[ 0 ] = t11 * detInv;\n\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\tte[ 3 ] = t12 * detInv;\n\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\tte[ 6 ] = t13 * detInv;\n\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\treturn this;\n\n\t}\n\n\ttranspose() {\n\n\t\tlet tmp;\n\t\tconst m = this.elements;\n\n\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\treturn this;\n\n\t}\n\n\tgetNormalMatrix( matrix4 ) {\n\n\t\treturn this.setFromMatrix4( matrix4 ).invert().transpose();\n\n\t}\n\n\ttransposeIntoArray( r ) {\n\n\t\tconst m = this.elements;\n\n\t\tr[ 0 ] = m[ 0 ];\n\t\tr[ 1 ] = m[ 3 ];\n\t\tr[ 2 ] = m[ 6 ];\n\t\tr[ 3 ] = m[ 1 ];\n\t\tr[ 4 ] = m[ 4 ];\n\t\tr[ 5 ] = m[ 7 ];\n\t\tr[ 6 ] = m[ 2 ];\n\t\tr[ 7 ] = m[ 5 ];\n\t\tr[ 8 ] = m[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetUvTransform( tx, ty, sx, sy, rotation, cx, cy ) {\n\n\t\tconst c = Math.cos( rotation );\n\t\tconst s = Math.sin( rotation );\n\n\t\tthis.set(\n\t\t\tsx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,\n\t\t\t- sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,\n\t\t\t0, 0, 1\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tscale( sx, sy ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;\n\t\tte[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;\n\n\t\treturn this;\n\n\t}\n\n\trotate( theta ) {\n\n\t\tconst c = Math.cos( theta );\n\t\tconst s = Math.sin( theta );\n\n\t\tconst te = this.elements;\n\n\t\tconst a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];\n\t\tconst a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];\n\n\t\tte[ 0 ] = c * a11 + s * a21;\n\t\tte[ 3 ] = c * a12 + s * a22;\n\t\tte[ 6 ] = c * a13 + s * a23;\n\n\t\tte[ 1 ] = - s * a11 + c * a21;\n\t\tte[ 4 ] = - s * a12 + c * a22;\n\t\tte[ 7 ] = - s * a13 + c * a23;\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( tx, ty ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];\n\t\tte[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\tequals( matrix ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = matrix.elements;\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tconst te = this.elements;\n\n\t\tarray[ offset ] = te[ 0 ];\n\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\treturn array;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().fromArray( this.elements );\n\n\t}\n\n}\n\nMatrix3.prototype.isMatrix3 = true;\n\nfunction arrayNeedsUint32( array ) {\n\n\t// assumes larger values usually on last\n\n\tfor ( let i = array.length - 1; i >= 0; -- i ) {\n\n\t\tif ( array[ i ] > 65535 ) return true;\n\n\t}\n\n\treturn false;\n\n}\n\nconst TYPED_ARRAYS = {\n\tInt8Array: Int8Array,\n\tUint8Array: Uint8Array,\n\tUint8ClampedArray: Uint8ClampedArray,\n\tInt16Array: Int16Array,\n\tUint16Array: Uint16Array,\n\tInt32Array: Int32Array,\n\tUint32Array: Uint32Array,\n\tFloat32Array: Float32Array,\n\tFloat64Array: Float64Array\n};\n\nfunction getTypedArray( type, buffer ) {\n\n\treturn new TYPED_ARRAYS[ type ]( buffer );\n\n}\n\nfunction createElementNS( name ) {\n\n\treturn document.createElementNS( 'http://www.w3.org/1999/xhtml', name );\n\n}\n\nfunction SRGBToLinear( c ) {\n\n\treturn ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );\n\n}\n\nfunction LinearToSRGB( c ) {\n\n\treturn ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;\n\n}\n\n// JavaScript RGB-to-RGB transforms, defined as\n// FN[InputColorSpace][OutputColorSpace] callback functions.\nconst FN = {\n\t[ SRGBColorSpace ]: { [ LinearSRGBColorSpace ]: SRGBToLinear },\n\t[ LinearSRGBColorSpace ]: { [ SRGBColorSpace ]: LinearToSRGB },\n};\n\nconst ColorManagement = {\n\n\tlegacyMode: true,\n\n\tget workingColorSpace() {\n\n\t\treturn LinearSRGBColorSpace;\n\n\t},\n\n\tset workingColorSpace( colorSpace ) {\n\n\t\tconsole.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' );\n\n\t},\n\n\tconvert: function ( color, sourceColorSpace, targetColorSpace ) {\n\n\t\tif ( this.legacyMode || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {\n\n\t\t\treturn color;\n\n\t\t}\n\n\t\tif ( FN[ sourceColorSpace ] && FN[ sourceColorSpace ][ targetColorSpace ] !== undefined ) {\n\n\t\t\tconst fn = FN[ sourceColorSpace ][ targetColorSpace ];\n\n\t\t\tcolor.r = fn( color.r );\n\t\t\tcolor.g = fn( color.g );\n\t\t\tcolor.b = fn( color.b );\n\n\t\t\treturn color;\n\n\t\t}\n\n\t\tthrow new Error( 'Unsupported color space conversion.' );\n\n\t},\n\n\tfromWorkingColorSpace: function ( color, targetColorSpace ) {\n\n\t\treturn this.convert( color, this.workingColorSpace, targetColorSpace );\n\n\t},\n\n\ttoWorkingColorSpace: function ( color, sourceColorSpace ) {\n\n\t\treturn this.convert( color, sourceColorSpace, this.workingColorSpace );\n\n\t},\n\n};\n\nconst _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\nconst _rgb = { r: 0, g: 0, b: 0 };\nconst _hslA = { h: 0, s: 0, l: 0 };\nconst _hslB = { h: 0, s: 0, l: 0 };\n\nfunction hue2rgb( p, q, t ) {\n\n\tif ( t < 0 ) t += 1;\n\tif ( t > 1 ) t -= 1;\n\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\tif ( t < 1 / 2 ) return q;\n\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\treturn p;\n\n}\n\nfunction toComponents( source, target ) {\n\n\ttarget.r = source.r;\n\ttarget.g = source.g;\n\ttarget.b = source.b;\n\n\treturn target;\n\n}\n\nclass Color {\n\n\tconstructor( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tset( value ) {\n\n\t\tif ( value && value.isColor ) {\n\n\t\t\tthis.copy( value );\n\n\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\tthis.setHex( value );\n\n\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\tthis.setStyle( value );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.r = scalar;\n\t\tthis.g = scalar;\n\t\tthis.b = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetHex( hex, colorSpace = SRGBColorSpace ) {\n\n\t\thex = Math.floor( hex );\n\n\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) {\n\n\t\tthis.r = r;\n\t\tthis.g = g;\n\t\tthis.b = b;\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetHSL( h, s, l, colorSpace = LinearSRGBColorSpace ) {\n\n\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\th = euclideanModulo( h, 1 );\n\t\ts = clamp( s, 0, 1 );\n\t\tl = clamp( l, 0, 1 );\n\n\t\tif ( s === 0 ) {\n\n\t\t\tthis.r = this.g = this.b = l;\n\n\t\t} else {\n\n\t\t\tconst p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\tconst q = ( 2 * l ) - p;\n\n\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t}\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetStyle( style, colorSpace = SRGBColorSpace ) {\n\n\t\tfunction handleAlpha( string ) {\n\n\t\t\tif ( string === undefined ) return;\n\n\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tlet m;\n\n\t\tif ( m = /^((?:rgb|hsl)a?)\\(([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t// rgb / hsl\n\n\t\t\tlet color;\n\t\t\tconst name = m[ 1 ];\n\t\t\tconst components = m[ 2 ];\n\n\t\t\tswitch ( name ) {\n\n\t\t\t\tcase 'rgb':\n\t\t\t\tcase 'rgba':\n\n\t\t\t\t\tif ( color = /^\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( color = /^\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'hsl':\n\t\t\t\tcase 'hsla':\n\n\t\t\t\t\tif ( color = /^\\s*(\\d*\\.?\\d+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\tconst h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\tconst s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\tconst l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this.setHSL( h, s, l, colorSpace );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t} else if ( m = /^\\#([A-Fa-f\\d]+)$/.exec( style ) ) {\n\n\t\t\t// hex color\n\n\t\t\tconst hex = m[ 1 ];\n\t\t\tconst size = hex.length;\n\n\t\t\tif ( size === 3 ) {\n\n\t\t\t\t// #ff0\n\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\treturn this;\n\n\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t// #ff0000\n\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( style && style.length > 0 ) {\n\n\t\t\treturn this.setColorName( style, colorSpace );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetColorName( style, colorSpace = SRGBColorSpace ) {\n\n\t\t// color keywords\n\t\tconst hex = _colorKeywords[ style.toLowerCase() ];\n\n\t\tif ( hex !== undefined ) {\n\n\t\t\t// red\n\t\t\tthis.setHex( hex, colorSpace );\n\n\t\t} else {\n\n\t\t\t// unknown color\n\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t}\n\n\tcopy( color ) {\n\n\t\tthis.r = color.r;\n\t\tthis.g = color.g;\n\t\tthis.b = color.b;\n\n\t\treturn this;\n\n\t}\n\n\tcopySRGBToLinear( color ) {\n\n\t\tthis.r = SRGBToLinear( color.r );\n\t\tthis.g = SRGBToLinear( color.g );\n\t\tthis.b = SRGBToLinear( color.b );\n\n\t\treturn this;\n\n\t}\n\n\tcopyLinearToSRGB( color ) {\n\n\t\tthis.r = LinearToSRGB( color.r );\n\t\tthis.g = LinearToSRGB( color.g );\n\t\tthis.b = LinearToSRGB( color.b );\n\n\t\treturn this;\n\n\t}\n\n\tconvertSRGBToLinear() {\n\n\t\tthis.copySRGBToLinear( this );\n\n\t\treturn this;\n\n\t}\n\n\tconvertLinearToSRGB() {\n\n\t\tthis.copyLinearToSRGB( this );\n\n\t\treturn this;\n\n\t}\n\n\tgetHex( colorSpace = SRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\treturn clamp( _rgb.r * 255, 0, 255 ) << 16 ^ clamp( _rgb.g * 255, 0, 255 ) << 8 ^ clamp( _rgb.b * 255, 0, 255 ) << 0;\n\n\t}\n\n\tgetHexString( colorSpace = SRGBColorSpace ) {\n\n\t\treturn ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );\n\n\t}\n\n\tgetHSL( target, colorSpace = LinearSRGBColorSpace ) {\n\n\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\tconst r = _rgb.r, g = _rgb.g, b = _rgb.b;\n\n\t\tconst max = Math.max( r, g, b );\n\t\tconst min = Math.min( r, g, b );\n\n\t\tlet hue, saturation;\n\t\tconst lightness = ( min + max ) / 2.0;\n\n\t\tif ( min === max ) {\n\n\t\t\thue = 0;\n\t\t\tsaturation = 0;\n\n\t\t} else {\n\n\t\t\tconst delta = max - min;\n\n\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\tswitch ( max ) {\n\n\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t}\n\n\t\t\thue /= 6;\n\n\t\t}\n\n\t\ttarget.h = hue;\n\t\ttarget.s = saturation;\n\t\ttarget.l = lightness;\n\n\t\treturn target;\n\n\t}\n\n\tgetRGB( target, colorSpace = LinearSRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\ttarget.r = _rgb.r;\n\t\ttarget.g = _rgb.g;\n\t\ttarget.b = _rgb.b;\n\n\t\treturn target;\n\n\t}\n\n\tgetStyle( colorSpace = SRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\tif ( colorSpace !== SRGBColorSpace ) {\n\n\t\t\t// Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).\n\t\t\treturn `color(${ colorSpace } ${ _rgb.r } ${ _rgb.g } ${ _rgb.b })`;\n\n\t\t}\n\n\t\treturn `rgb(${( _rgb.r * 255 ) | 0},${( _rgb.g * 255 ) | 0},${( _rgb.b * 255 ) | 0})`;\n\n\t}\n\n\toffsetHSL( h, s, l ) {\n\n\t\tthis.getHSL( _hslA );\n\n\t\t_hslA.h += h; _hslA.s += s; _hslA.l += l;\n\n\t\tthis.setHSL( _hslA.h, _hslA.s, _hslA.l );\n\n\t\treturn this;\n\n\t}\n\n\tadd( color ) {\n\n\t\tthis.r += color.r;\n\t\tthis.g += color.g;\n\t\tthis.b += color.b;\n\n\t\treturn this;\n\n\t}\n\n\taddColors( color1, color2 ) {\n\n\t\tthis.r = color1.r + color2.r;\n\t\tthis.g = color1.g + color2.g;\n\t\tthis.b = color1.b + color2.b;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.r += s;\n\t\tthis.g += s;\n\t\tthis.b += s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( color ) {\n\n\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( color ) {\n\n\t\tthis.r *= color.r;\n\t\tthis.g *= color.g;\n\t\tthis.b *= color.b;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tthis.r *= s;\n\t\tthis.g *= s;\n\t\tthis.b *= s;\n\n\t\treturn this;\n\n\t}\n\n\tlerp( color, alpha ) {\n\n\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpColors( color1, color2, alpha ) {\n\n\t\tthis.r = color1.r + ( color2.r - color1.r ) * alpha;\n\t\tthis.g = color1.g + ( color2.g - color1.g ) * alpha;\n\t\tthis.b = color1.b + ( color2.b - color1.b ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpHSL( color, alpha ) {\n\n\t\tthis.getHSL( _hslA );\n\t\tcolor.getHSL( _hslB );\n\n\t\tconst h = lerp( _hslA.h, _hslB.h, alpha );\n\t\tconst s = lerp( _hslA.s, _hslB.s, alpha );\n\t\tconst l = lerp( _hslA.l, _hslB.l, alpha );\n\n\t\tthis.setHSL( h, s, l );\n\n\t\treturn this;\n\n\t}\n\n\tequals( c ) {\n\n\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.r = array[ offset ];\n\t\tthis.g = array[ offset + 1 ];\n\t\tthis.b = array[ offset + 2 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.r;\n\t\tarray[ offset + 1 ] = this.g;\n\t\tarray[ offset + 2 ] = this.b;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index ) {\n\n\t\tthis.r = attribute.getX( index );\n\t\tthis.g = attribute.getY( index );\n\t\tthis.b = attribute.getZ( index );\n\n\t\tif ( attribute.normalized === true ) {\n\n\t\t\t// assuming Uint8Array\n\n\t\t\tthis.r /= 255;\n\t\t\tthis.g /= 255;\n\t\t\tthis.b /= 255;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\treturn this.getHex();\n\n\t}\n\n}\n\nColor.NAMES = _colorKeywords;\n\nColor.prototype.isColor = true;\nColor.prototype.r = 1;\nColor.prototype.g = 1;\nColor.prototype.b = 1;\n\nlet _canvas;\n\nclass ImageUtils {\n\n\tstatic getDataURL( image ) {\n\n\t\tif ( /^data:/i.test( image.src ) ) {\n\n\t\t\treturn image.src;\n\n\t\t}\n\n\t\tif ( typeof HTMLCanvasElement == 'undefined' ) {\n\n\t\t\treturn image.src;\n\n\t\t}\n\n\t\tlet canvas;\n\n\t\tif ( image instanceof HTMLCanvasElement ) {\n\n\t\t\tcanvas = image;\n\n\t\t} else {\n\n\t\t\tif ( _canvas === undefined ) _canvas = createElementNS( 'canvas' );\n\n\t\t\t_canvas.width = image.width;\n\t\t\t_canvas.height = image.height;\n\n\t\t\tconst context = _canvas.getContext( '2d' );\n\n\t\t\tif ( image instanceof ImageData ) {\n\n\t\t\t\tcontext.putImageData( image, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t}\n\n\t\t\tcanvas = _canvas;\n\n\t\t}\n\n\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image );\n\n\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t} else {\n\n\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t}\n\n\t}\n\n\tstatic sRGBToLinear( image ) {\n\n\t\tif ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||\n\t\t\t( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||\n\t\t\t( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {\n\n\t\t\tconst canvas = createElementNS( 'canvas' );\n\n\t\t\tcanvas.width = image.width;\n\t\t\tcanvas.height = image.height;\n\n\t\t\tconst context = canvas.getContext( '2d' );\n\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\tconst imageData = context.getImageData( 0, 0, image.width, image.height );\n\t\t\tconst data = imageData.data;\n\n\t\t\tfor ( let i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tdata[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255;\n\n\t\t\t}\n\n\t\t\tcontext.putImageData( imageData, 0, 0 );\n\n\t\t\treturn canvas;\n\n\t\t} else if ( image.data ) {\n\n\t\t\tconst data = image.data.slice( 0 );\n\n\t\t\tfor ( let i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tif ( data instanceof Uint8Array || data instanceof Uint8ClampedArray ) {\n\n\t\t\t\t\tdata[ i ] = Math.floor( SRGBToLinear( data[ i ] / 255 ) * 255 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assuming float\n\n\t\t\t\t\tdata[ i ] = SRGBToLinear( data[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdata: data,\n\t\t\t\twidth: image.width,\n\t\t\t\theight: image.height\n\t\t\t};\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' );\n\t\t\treturn image;\n\n\t\t}\n\n\t}\n\n}\n\nclass Source {\n\n\tconstructor( data = null ) {\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.data = data;\n\n\t\tthis.version = 0;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) {\n\n\t\t\treturn meta.images[ this.uuid ];\n\n\t\t}\n\n\t\tconst output = {\n\t\t\tuuid: this.uuid,\n\t\t\turl: ''\n\t\t};\n\n\t\tconst data = this.data;\n\n\t\tif ( data !== null ) {\n\n\t\t\tlet url;\n\n\t\t\tif ( Array.isArray( data ) ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\turl = [];\n\n\t\t\t\tfor ( let i = 0, l = data.length; i < l; i ++ ) {\n\n\t\t\t\t\tif ( data[ i ].isDataTexture ) {\n\n\t\t\t\t\t\turl.push( serializeImage( data[ i ].image ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\turl.push( serializeImage( data[ i ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// texture\n\n\t\t\t\turl = serializeImage( data );\n\n\t\t\t}\n\n\t\t\toutput.url = url;\n\n\t\t}\n\n\t\tif ( ! isRootObject ) {\n\n\t\t\tmeta.images[ this.uuid ] = output;\n\n\t\t}\n\n\t\treturn output;\n\n\t}\n\n}\n\nfunction serializeImage( image ) {\n\n\tif ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||\n\t\t( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||\n\t\t( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {\n\n\t\t// default images\n\n\t\treturn ImageUtils.getDataURL( image );\n\n\t} else {\n\n\t\tif ( image.data ) {\n\n\t\t\t// images of DataTexture\n\n\t\t\treturn {\n\t\t\t\tdata: Array.prototype.slice.call( image.data ),\n\t\t\t\twidth: image.width,\n\t\t\t\theight: image.height,\n\t\t\t\ttype: image.data.constructor.name\n\t\t\t};\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.Texture: Unable to serialize Texture.' );\n\t\t\treturn {};\n\n\t\t}\n\n\t}\n\n}\n\nSource.prototype.isSource = true;\n\nlet textureId = 0;\n\nclass Texture extends EventDispatcher {\n\n\tconstructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding ) {\n\n\t\tsuper();\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.source = new Source( image );\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping;\n\n\t\tthis.wrapS = wrapS;\n\t\tthis.wrapT = wrapT;\n\n\t\tthis.magFilter = magFilter;\n\t\tthis.minFilter = minFilter;\n\n\t\tthis.anisotropy = anisotropy;\n\n\t\tthis.format = format;\n\t\tthis.internalFormat = null;\n\t\tthis.type = type;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\t\tthis.center = new Vector2( 0, 0 );\n\t\tthis.rotation = 0;\n\n\t\tthis.matrixAutoUpdate = true;\n\t\tthis.matrix = new Matrix3();\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding;\n\n\t\tthis.userData = {};\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t\tthis.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not\n\t\tthis.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)\n\n\t}\n\n\tget image() {\n\n\t\treturn this.source.data;\n\n\t}\n\n\tset image( value ) {\n\n\t\tthis.source.data = value;\n\n\t}\n\n\tupdateMatrix() {\n\n\t\tthis.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.source = source.source;\n\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\tthis.mapping = source.mapping;\n\n\t\tthis.wrapS = source.wrapS;\n\t\tthis.wrapT = source.wrapT;\n\n\t\tthis.magFilter = source.magFilter;\n\t\tthis.minFilter = source.minFilter;\n\n\t\tthis.anisotropy = source.anisotropy;\n\n\t\tthis.format = source.format;\n\t\tthis.internalFormat = source.internalFormat;\n\t\tthis.type = source.type;\n\n\t\tthis.offset.copy( source.offset );\n\t\tthis.repeat.copy( source.repeat );\n\t\tthis.center.copy( source.center );\n\t\tthis.rotation = source.rotation;\n\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\tthis.matrix.copy( source.matrix );\n\n\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\tthis.flipY = source.flipY;\n\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\tthis.encoding = source.encoding;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\tthis.needsUpdate = true;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t}\n\n\t\tconst output = {\n\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Texture',\n\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t},\n\n\t\t\tuuid: this.uuid,\n\t\t\tname: this.name,\n\n\t\t\timage: this.source.toJSON( meta ).uuid,\n\n\t\t\tmapping: this.mapping,\n\n\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\tcenter: [ this.center.x, this.center.y ],\n\t\t\trotation: this.rotation,\n\n\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\tformat: this.format,\n\t\t\ttype: this.type,\n\t\t\tencoding: this.encoding,\n\n\t\t\tminFilter: this.minFilter,\n\t\t\tmagFilter: this.magFilter,\n\t\t\tanisotropy: this.anisotropy,\n\n\t\t\tflipY: this.flipY,\n\n\t\t\tpremultiplyAlpha: this.premultiplyAlpha,\n\t\t\tunpackAlignment: this.unpackAlignment\n\n\t\t};\n\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) output.userData = this.userData;\n\n\t\tif ( ! isRootObject ) {\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t}\n\n\t\treturn output;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n\ttransformUv( uv ) {\n\n\t\tif ( this.mapping !== UVMapping ) return uv;\n\n\t\tuv.applyMatrix3( this.matrix );\n\n\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.flipY ) {\n\n\t\t\tuv.y = 1 - uv.y;\n\n\t\t}\n\n\t\treturn uv;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) {\n\n\t\t\tthis.version ++;\n\t\t\tthis.source.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n}\n\nTexture.DEFAULT_IMAGE = null;\nTexture.DEFAULT_MAPPING = UVMapping;\n\nTexture.prototype.isTexture = true;\n\nclass Vector4 {\n\n\tconstructor( x = 0, y = 0, z = 0, w = 1 ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\t\tthis.w = w;\n\n\t}\n\n\tget width() {\n\n\t\treturn this.z;\n\n\t}\n\n\tset width( value ) {\n\n\t\tthis.z = value;\n\n\t}\n\n\tget height() {\n\n\t\treturn this.w;\n\n\t}\n\n\tset height( value ) {\n\n\t\tthis.w = value;\n\n\t}\n\n\tset( x, y, z, w ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\t\tthis.w = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\t\tthis.z = scalar;\n\t\tthis.w = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetZ( z ) {\n\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetW( w ) {\n\n\t\tthis.w = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tcase 2: this.z = value; break;\n\t\t\tcase 3: this.w = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tcase 2: return this.z;\n\t\t\tcase 3: return this.w;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\t\tthis.z = v.z;\n\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\t\tthis.z += v.z;\n\t\tthis.w += v.w;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\t\tthis.z += s;\n\t\tthis.w += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\t\tthis.z = a.z + b.z;\n\t\tthis.w = a.w + b.w;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\t\tthis.z += v.z * s;\n\t\tthis.w += v.w * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\t\tthis.z -= v.z;\n\t\tthis.w -= v.w;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\t\tthis.z -= s;\n\t\tthis.w -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\t\tthis.z = a.z - b.z;\n\t\tthis.w = a.w - b.w;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v ) {\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\t\tthis.z *= v.z;\n\t\tthis.w *= v.w;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\t\tthis.z *= scalar;\n\t\tthis.w *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z, w = this.w;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tsetAxisAngleFromQuaternion( q ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t// q is assumed to be normalized\n\n\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\tconst s = Math.sqrt( 1 - q.w * q.w );\n\n\t\tif ( s < 0.0001 ) {\n\n\t\t\tthis.x = 1;\n\t\t\tthis.y = 0;\n\t\t\tthis.z = 0;\n\n\t\t} else {\n\n\t\t\tthis.x = q.x / s;\n\t\t\tthis.y = q.y / s;\n\t\t\tthis.z = q.z / s;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetAxisAngleFromRotationMatrix( m ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tlet angle, x, y, z; // variables for result\n\t\tconst epsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\tte = m.elements,\n\n\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t// singularity found\n\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t}\n\n\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\tangle = Math.PI;\n\n\t\t\tconst xx = ( m11 + 1 ) / 2;\n\t\t\tconst yy = ( m22 + 1 ) / 2;\n\t\t\tconst zz = ( m33 + 1 ) / 2;\n\t\t\tconst xy = ( m12 + m21 ) / 4;\n\t\t\tconst xz = ( m13 + m31 ) / 4;\n\t\t\tconst yz = ( m23 + m32 ) / 4;\n\n\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\tx = 0;\n\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\ty = xy / x;\n\t\t\t\t\tz = xz / x;\n\n\t\t\t\t}\n\n\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\ty = 0;\n\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\tx = xy / y;\n\t\t\t\t\tz = yz / y;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\tz = 0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\tx = xz / z;\n\t\t\t\t\ty = yz / z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.set( x, y, z, angle );\n\n\t\t\treturn this; // return 180 deg rotation\n\n\t\t}\n\n\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\tlet s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\tthis.x = ( m32 - m23 ) / s;\n\t\tthis.y = ( m13 - m31 ) / s;\n\t\tthis.z = ( m21 - m12 ) / s;\n\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\treturn this;\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\t\tthis.z = Math.min( this.z, v.z );\n\t\tthis.w = Math.min( this.w, v.w );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\t\tthis.z = Math.max( this.z, v.z );\n\t\tthis.w = Math.max( this.w, v.w );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\t\tthis.z = Math.max( minVal, Math.min( maxVal, this.z ) );\n\t\tthis.w = Math.max( minVal, Math.min( maxVal, this.w ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\t\tthis.z = Math.floor( this.z );\n\t\tthis.w = Math.floor( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\t\tthis.z = Math.ceil( this.z );\n\t\tthis.w = Math.ceil( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\t\tthis.z = Math.round( this.z );\n\t\tthis.w = Math.round( this.w );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\t\tthis.z = - this.z;\n\t\tthis.w = - this.w;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\t\tthis.z = v1.z + ( v2.z - v1.z ) * alpha;\n\t\tthis.w = v1.w + ( v2.w - v1.w ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\t\tthis.z = array[ offset + 2 ];\n\t\tthis.w = array[ offset + 3 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\t\tarray[ offset + 2 ] = this.z;\n\t\tarray[ offset + 3 ] = this.w;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\t\tthis.z = attribute.getZ( index );\n\t\tthis.w = attribute.getW( index );\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\t\tthis.z = Math.random();\n\t\tthis.w = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\t\tyield this.z;\n\t\tyield this.w;\n\n\t}\n\n}\n\nVector4.prototype.isVector4 = true;\n\n/*\n In options, we can specify:\n * Texture parameters for an auto-generated target texture\n * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n*/\nclass WebGLRenderTarget extends EventDispatcher {\n\n\tconstructor( width, height, options = {} ) {\n\n\t\tsuper();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\t\tthis.depth = 1;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\tconst image = { width: width, height: height, depth: 1 };\n\n\t\tthis.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\tthis.texture.flipY = false;\n\t\tthis.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;\n\t\tthis.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null;\n\t\tthis.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;\n\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t\tthis.samples = options.samples !== undefined ? options.samples : 0;\n\n\t}\n\n\tsetSize( width, height, depth = 1 ) {\n\n\t\tif ( this.width !== width || this.height !== height || this.depth !== depth ) {\n\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\t\t\tthis.depth = depth;\n\n\t\t\tthis.texture.image.width = width;\n\t\t\tthis.texture.image.height = height;\n\t\t\tthis.texture.image.depth = depth;\n\n\t\t\tthis.dispose();\n\n\t\t}\n\n\t\tthis.viewport.set( 0, 0, width, height );\n\t\tthis.scissor.set( 0, 0, width, height );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.width = source.width;\n\t\tthis.height = source.height;\n\t\tthis.depth = source.depth;\n\n\t\tthis.viewport.copy( source.viewport );\n\n\t\tthis.texture = source.texture.clone();\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\t// ensure image object is not shared, see #20328\n\n\t\tthis.texture.image = Object.assign( {}, source.texture.image );\n\n\t\tthis.depthBuffer = source.depthBuffer;\n\t\tthis.stencilBuffer = source.stencilBuffer;\n\n\t\tif ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone();\n\n\t\tthis.samples = source.samples;\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n}\n\nWebGLRenderTarget.prototype.isWebGLRenderTarget = true;\n\nclass DataArrayTexture extends Texture {\n\n\tconstructor( data = null, width = 1, height = 1, depth = 1 ) {\n\n\t\tsuper( null );\n\n\t\tthis.image = { data, width, height, depth };\n\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.minFilter = NearestFilter;\n\n\t\tthis.wrapR = ClampToEdgeWrapping;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n}\n\nDataArrayTexture.prototype.isDataArrayTexture = true;\n\nclass WebGLArrayRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( width, height, depth ) {\n\n\t\tsuper( width, height );\n\n\t\tthis.depth = depth;\n\n\t\tthis.texture = new DataArrayTexture( null, width, height, depth );\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t}\n\n}\n\nWebGLArrayRenderTarget.prototype.isWebGLArrayRenderTarget = true;\n\nclass Data3DTexture extends Texture {\n\n\tconstructor( data = null, width = 1, height = 1, depth = 1 ) {\n\n\t\t// We're going to add .setXXX() methods for setting properties later.\n\t\t// Users can still set in DataTexture3D directly.\n\t\t//\n\t\t//\tconst texture = new THREE.DataTexture3D( data, width, height, depth );\n\t\t// \ttexture.anisotropy = 16;\n\t\t//\n\t\t// See #14839\n\n\t\tsuper( null );\n\n\t\tthis.image = { data, width, height, depth };\n\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.minFilter = NearestFilter;\n\n\t\tthis.wrapR = ClampToEdgeWrapping;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n}\n\nData3DTexture.prototype.isData3DTexture = true;\n\nclass WebGL3DRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( width, height, depth ) {\n\n\t\tsuper( width, height );\n\n\t\tthis.depth = depth;\n\n\t\tthis.texture = new Data3DTexture( null, width, height, depth );\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t}\n\n}\n\nWebGL3DRenderTarget.prototype.isWebGL3DRenderTarget = true;\n\nclass WebGLMultipleRenderTargets extends WebGLRenderTarget {\n\n\tconstructor( width, height, count, options = {} ) {\n\n\t\tsuper( width, height, options );\n\n\t\tconst texture = this.texture;\n\n\t\tthis.texture = [];\n\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tthis.texture[ i ] = texture.clone();\n\t\t\tthis.texture[ i ].isRenderTargetTexture = true;\n\n\t\t}\n\n\t}\n\n\tsetSize( width, height, depth = 1 ) {\n\n\t\tif ( this.width !== width || this.height !== height || this.depth !== depth ) {\n\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\t\t\tthis.depth = depth;\n\n\t\t\tfor ( let i = 0, il = this.texture.length; i < il; i ++ ) {\n\n\t\t\t\tthis.texture[ i ].image.width = width;\n\t\t\t\tthis.texture[ i ].image.height = height;\n\t\t\t\tthis.texture[ i ].image.depth = depth;\n\n\t\t\t}\n\n\t\t\tthis.dispose();\n\n\t\t}\n\n\t\tthis.viewport.set( 0, 0, width, height );\n\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.dispose();\n\n\t\tthis.width = source.width;\n\t\tthis.height = source.height;\n\t\tthis.depth = source.depth;\n\n\t\tthis.viewport.set( 0, 0, this.width, this.height );\n\t\tthis.scissor.set( 0, 0, this.width, this.height );\n\n\t\tthis.depthBuffer = source.depthBuffer;\n\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\tthis.depthTexture = source.depthTexture;\n\n\t\tthis.texture.length = 0;\n\n\t\tfor ( let i = 0, il = source.texture.length; i < il; i ++ ) {\n\n\t\t\tthis.texture[ i ] = source.texture[ i ].clone();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nWebGLMultipleRenderTargets.prototype.isWebGLMultipleRenderTargets = true;\n\nclass Quaternion {\n\n\tconstructor( x = 0, y = 0, z = 0, w = 1 ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._w = w;\n\n\t}\n\n\tstatic slerp( qa, qb, qm, t ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.' );\n\t\treturn qm.slerpQuaternions( qa, qb, t );\n\n\t}\n\n\tstatic slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\tlet x0 = src0[ srcOffset0 + 0 ],\n\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\tw0 = src0[ srcOffset0 + 3 ];\n\n\t\tconst x1 = src1[ srcOffset1 + 0 ],\n\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\tif ( t === 0 ) {\n\n\t\t\tdst[ dstOffset + 0 ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( t === 1 ) {\n\n\t\t\tdst[ dstOffset + 0 ] = x1;\n\t\t\tdst[ dstOffset + 1 ] = y1;\n\t\t\tdst[ dstOffset + 2 ] = z1;\n\t\t\tdst[ dstOffset + 3 ] = w1;\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\tlet s = 1 - t;\n\t\t\tconst cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\tconst sin = Math.sqrt( sqrSin ),\n\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t}\n\n\t\t\tconst tDir = t * dir;\n\n\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t// Normalize in case we just did a lerp:\n\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\tconst f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\tx0 *= f;\n\t\t\t\ty0 *= f;\n\t\t\t\tz0 *= f;\n\t\t\t\tw0 *= f;\n\n\t\t\t}\n\n\t\t}\n\n\t\tdst[ dstOffset ] = x0;\n\t\tdst[ dstOffset + 1 ] = y0;\n\t\tdst[ dstOffset + 2 ] = z0;\n\t\tdst[ dstOffset + 3 ] = w0;\n\n\t}\n\n\tstatic multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {\n\n\t\tconst x0 = src0[ srcOffset0 ];\n\t\tconst y0 = src0[ srcOffset0 + 1 ];\n\t\tconst z0 = src0[ srcOffset0 + 2 ];\n\t\tconst w0 = src0[ srcOffset0 + 3 ];\n\n\t\tconst x1 = src1[ srcOffset1 ];\n\t\tconst y1 = src1[ srcOffset1 + 1 ];\n\t\tconst z1 = src1[ srcOffset1 + 2 ];\n\t\tconst w1 = src1[ srcOffset1 + 3 ];\n\n\t\tdst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;\n\t\tdst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;\n\t\tdst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;\n\t\tdst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;\n\n\t\treturn dst;\n\n\t}\n\n\tget x() {\n\n\t\treturn this._x;\n\n\t}\n\n\tset x( value ) {\n\n\t\tthis._x = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget y() {\n\n\t\treturn this._y;\n\n\t}\n\n\tset y( value ) {\n\n\t\tthis._y = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget z() {\n\n\t\treturn this._z;\n\n\t}\n\n\tset z( value ) {\n\n\t\tthis._z = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget w() {\n\n\t\treturn this._w;\n\n\t}\n\n\tset w( value ) {\n\n\t\tthis._w = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tset( x, y, z, w ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._w = w;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t}\n\n\tcopy( quaternion ) {\n\n\t\tthis._x = quaternion.x;\n\t\tthis._y = quaternion.y;\n\t\tthis._z = quaternion.z;\n\t\tthis._w = quaternion.w;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromEuler( euler, update ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\tconst x = euler._x, y = euler._y, z = euler._z, order = euler._order;\n\n\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t//\tcontent/SpinCalc.m\n\n\t\tconst cos = Math.cos;\n\t\tconst sin = Math.sin;\n\n\t\tconst c1 = cos( x / 2 );\n\t\tconst c2 = cos( y / 2 );\n\t\tconst c3 = cos( z / 2 );\n\n\t\tconst s1 = sin( x / 2 );\n\t\tconst s2 = sin( y / 2 );\n\t\tconst s3 = sin( z / 2 );\n\n\t\tswitch ( order ) {\n\n\t\t\tcase 'XYZ':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'YXZ':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZXY':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZYX':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'YZX':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'XZY':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );\n\n\t\t}\n\n\t\tif ( update !== false ) this._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromAxisAngle( axis, angle ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t// assumes axis is normalized\n\n\t\tconst halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\tthis._x = axis.x * s;\n\t\tthis._y = axis.y * s;\n\t\tthis._z = axis.z * s;\n\t\tthis._w = Math.cos( halfAngle );\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromRotationMatrix( m ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tconst te = m.elements,\n\n\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\ttrace = m11 + m22 + m33;\n\n\t\tif ( trace > 0 ) {\n\n\t\t\tconst s = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\tthis._w = 0.25 / s;\n\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\tthis._x = 0.25 * s;\n\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t} else if ( m22 > m33 ) {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\tthis._y = 0.25 * s;\n\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t} else {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\tthis._z = 0.25 * s;\n\n\t\t}\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromUnitVectors( vFrom, vTo ) {\n\n\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\tlet r = vFrom.dot( vTo ) + 1;\n\n\t\tif ( r < Number.EPSILON ) {\n\n\t\t\t// vFrom and vTo point in opposite directions\n\n\t\t\tr = 0;\n\n\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\tthis._x = - vFrom.y;\n\t\t\t\tthis._y = vFrom.x;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = r;\n\n\t\t\t} else {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = - vFrom.z;\n\t\t\t\tthis._z = vFrom.y;\n\t\t\t\tthis._w = r;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3\n\n\t\t\tthis._x = vFrom.y * vTo.z - vFrom.z * vTo.y;\n\t\t\tthis._y = vFrom.z * vTo.x - vFrom.x * vTo.z;\n\t\t\tthis._z = vFrom.x * vTo.y - vFrom.y * vTo.x;\n\t\t\tthis._w = r;\n\n\t\t}\n\n\t\treturn this.normalize();\n\n\t}\n\n\tangleTo( q ) {\n\n\t\treturn 2 * Math.acos( Math.abs( clamp( this.dot( q ), - 1, 1 ) ) );\n\n\t}\n\n\trotateTowards( q, step ) {\n\n\t\tconst angle = this.angleTo( q );\n\n\t\tif ( angle === 0 ) return this;\n\n\t\tconst t = Math.min( 1, step / angle );\n\n\t\tthis.slerp( q, t );\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\treturn this.set( 0, 0, 0, 1 );\n\n\t}\n\n\tinvert() {\n\n\t\t// quaternion is assumed to have unit length\n\n\t\treturn this.conjugate();\n\n\t}\n\n\tconjugate() {\n\n\t\tthis._x *= - 1;\n\t\tthis._y *= - 1;\n\t\tthis._z *= - 1;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t}\n\n\tnormalize() {\n\n\t\tlet l = this.length();\n\n\t\tif ( l === 0 ) {\n\n\t\t\tthis._x = 0;\n\t\t\tthis._y = 0;\n\t\t\tthis._z = 0;\n\t\t\tthis._w = 1;\n\n\t\t} else {\n\n\t\t\tl = 1 / l;\n\n\t\t\tthis._x = this._x * l;\n\t\t\tthis._y = this._y * l;\n\t\t\tthis._z = this._z * l;\n\t\t\tthis._w = this._w * l;\n\n\t\t}\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( q, p ) {\n\n\t\tif ( p !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t}\n\n\t\treturn this.multiplyQuaternions( this, q );\n\n\t}\n\n\tpremultiply( q ) {\n\n\t\treturn this.multiplyQuaternions( q, this );\n\n\t}\n\n\tmultiplyQuaternions( a, b ) {\n\n\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\tconst qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\tconst qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tslerp( qb, t ) {\n\n\t\tif ( t === 0 ) return this;\n\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\tconst x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\tlet cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\tthis._w = - qb._w;\n\t\t\tthis._x = - qb._x;\n\t\t\tthis._y = - qb._y;\n\t\t\tthis._z = - qb._z;\n\n\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t} else {\n\n\t\t\tthis.copy( qb );\n\n\t\t}\n\n\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\tthis._w = w;\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;\n\n\t\tif ( sqrSinHalfTheta <= Number.EPSILON ) {\n\n\t\t\tconst s = 1 - t;\n\t\t\tthis._w = s * w + t * this._w;\n\t\t\tthis._x = s * x + t * this._x;\n\t\t\tthis._y = s * y + t * this._y;\n\t\t\tthis._z = s * z + t * this._z;\n\n\t\t\tthis.normalize();\n\t\t\tthis._onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst sinHalfTheta = Math.sqrt( sqrSinHalfTheta );\n\t\tconst halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\tconst ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tslerpQuaternions( qa, qb, t ) {\n\n\t\treturn this.copy( qa ).slerp( qb, t );\n\n\t}\n\n\trandom() {\n\n\t\t// Derived from http://planning.cs.uiuc.edu/node198.html\n\t\t// Note, this source uses w, x, y, z ordering,\n\t\t// so we swap the order below.\n\n\t\tconst u1 = Math.random();\n\t\tconst sqrt1u1 = Math.sqrt( 1 - u1 );\n\t\tconst sqrtu1 = Math.sqrt( u1 );\n\n\t\tconst u2 = 2 * Math.PI * Math.random();\n\n\t\tconst u3 = 2 * Math.PI * Math.random();\n\n\t\treturn this.set(\n\t\t\tsqrt1u1 * Math.cos( u2 ),\n\t\t\tsqrtu1 * Math.sin( u3 ),\n\t\t\tsqrtu1 * Math.cos( u3 ),\n\t\t\tsqrt1u1 * Math.sin( u2 ),\n\t\t);\n\n\t}\n\n\tequals( quaternion ) {\n\n\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis._x = array[ offset ];\n\t\tthis._y = array[ offset + 1 ];\n\t\tthis._z = array[ offset + 2 ];\n\t\tthis._w = array[ offset + 3 ];\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this._x;\n\t\tarray[ offset + 1 ] = this._y;\n\t\tarray[ offset + 2 ] = this._z;\n\t\tarray[ offset + 3 ] = this._w;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index ) {\n\n\t\tthis._x = attribute.getX( index );\n\t\tthis._y = attribute.getY( index );\n\t\tthis._z = attribute.getZ( index );\n\t\tthis._w = attribute.getW( index );\n\n\t\treturn this;\n\n\t}\n\n\t_onChange( callback ) {\n\n\t\tthis._onChangeCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\t_onChangeCallback() {}\n\n}\n\nQuaternion.prototype.isQuaternion = true;\n\nclass Vector3 {\n\n\tconstructor( x = 0, y = 0, z = 0 ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\n\t}\n\n\tset( x, y, z ) {\n\n\t\tif ( z === undefined ) z = this.z; // sprite.scale.set(x,y)\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\t\tthis.z = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetZ( z ) {\n\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tcase 2: this.z = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tcase 2: return this.z;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\t\tthis.z = v.z;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\t\tthis.z += v.z;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\t\tthis.z += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\t\tthis.z = a.z + b.z;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\t\tthis.z += v.z * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\t\tthis.z -= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\t\tthis.z -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\t\tthis.z = a.z - b.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t}\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\t\tthis.z *= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\t\tthis.z *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyVectors( a, b ) {\n\n\t\tthis.x = a.x * b.x;\n\t\tthis.y = a.y * b.y;\n\t\tthis.z = a.z * b.z;\n\n\t\treturn this;\n\n\t}\n\n\tapplyEuler( euler ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\treturn this.applyQuaternion( _quaternion$4.setFromEuler( euler ) );\n\n\t}\n\n\tapplyAxisAngle( axis, angle ) {\n\n\t\treturn this.applyQuaternion( _quaternion$4.setFromAxisAngle( axis, angle ) );\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\treturn this;\n\n\t}\n\n\tapplyNormalMatrix( m ) {\n\n\t\treturn this.applyMatrix3( m ).normalize();\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tconst w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );\n\n\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;\n\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;\n\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;\n\n\t\treturn this;\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t// calculate quat * vector\n\n\t\tconst ix = qw * x + qy * z - qz * y;\n\t\tconst iy = qw * y + qz * x - qx * z;\n\t\tconst iz = qw * z + qx * y - qy * x;\n\t\tconst iw = - qx * x - qy * y - qz * z;\n\n\t\t// calculate result * inverse quat\n\n\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\treturn this;\n\n\t}\n\n\tproject( camera ) {\n\n\t\treturn this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );\n\n\t}\n\n\tunproject( camera ) {\n\n\t\treturn this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );\n\n\t}\n\n\ttransformDirection( m ) {\n\n\t\t// input: THREE.Matrix4 affine matrix\n\t\t// vector interpreted as a direction\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\treturn this.normalize();\n\n\t}\n\n\tdivide( v ) {\n\n\t\tthis.x /= v.x;\n\t\tthis.y /= v.y;\n\t\tthis.z /= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\t\tthis.z = Math.min( this.z, v.z );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\t\tthis.z = Math.max( this.z, v.z );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\t\tthis.z = Math.max( minVal, Math.min( maxVal, this.z ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\t\tthis.z = Math.floor( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\t\tthis.z = Math.ceil( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\t\tthis.z = Math.round( this.z );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\t\tthis.z = - this.z;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t}\n\n\t// TODO lengthSquared?\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\t\tthis.z = v1.z + ( v2.z - v1.z ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tcross( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\treturn this.crossVectors( v, w );\n\n\t\t}\n\n\t\treturn this.crossVectors( this, v );\n\n\t}\n\n\tcrossVectors( a, b ) {\n\n\t\tconst ax = a.x, ay = a.y, az = a.z;\n\t\tconst bx = b.x, by = b.y, bz = b.z;\n\n\t\tthis.x = ay * bz - az * by;\n\t\tthis.y = az * bx - ax * bz;\n\t\tthis.z = ax * by - ay * bx;\n\n\t\treturn this;\n\n\t}\n\n\tprojectOnVector( v ) {\n\n\t\tconst denominator = v.lengthSq();\n\n\t\tif ( denominator === 0 ) return this.set( 0, 0, 0 );\n\n\t\tconst scalar = v.dot( this ) / denominator;\n\n\t\treturn this.copy( v ).multiplyScalar( scalar );\n\n\t}\n\n\tprojectOnPlane( planeNormal ) {\n\n\t\t_vector$c.copy( this ).projectOnVector( planeNormal );\n\n\t\treturn this.sub( _vector$c );\n\n\t}\n\n\treflect( normal ) {\n\n\t\t// reflect incident vector off plane orthogonal to normal\n\t\t// normal is assumed to have unit length\n\n\t\treturn this.sub( _vector$c.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t}\n\n\tangleTo( v ) {\n\n\t\tconst denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );\n\n\t\tif ( denominator === 0 ) return Math.PI / 2;\n\n\t\tconst theta = this.dot( v ) / denominator;\n\n\t\t// clamp, to handle numerical problems\n\n\t\treturn Math.acos( clamp( theta, - 1, 1 ) );\n\n\t}\n\n\tdistanceTo( v ) {\n\n\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t}\n\n\tdistanceToSquared( v ) {\n\n\t\tconst dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t}\n\n\tmanhattanDistanceTo( v ) {\n\n\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t}\n\n\tsetFromSpherical( s ) {\n\n\t\treturn this.setFromSphericalCoords( s.radius, s.phi, s.theta );\n\n\t}\n\n\tsetFromSphericalCoords( radius, phi, theta ) {\n\n\t\tconst sinPhiRadius = Math.sin( phi ) * radius;\n\n\t\tthis.x = sinPhiRadius * Math.sin( theta );\n\t\tthis.y = Math.cos( phi ) * radius;\n\t\tthis.z = sinPhiRadius * Math.cos( theta );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCylindrical( c ) {\n\n\t\treturn this.setFromCylindricalCoords( c.radius, c.theta, c.y );\n\n\t}\n\n\tsetFromCylindricalCoords( radius, theta, y ) {\n\n\t\tthis.x = radius * Math.sin( theta );\n\t\tthis.y = y;\n\t\tthis.z = radius * Math.cos( theta );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixPosition( m ) {\n\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 12 ];\n\t\tthis.y = e[ 13 ];\n\t\tthis.z = e[ 14 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixScale( m ) {\n\n\t\tconst sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\tconst sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\tconst sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\tthis.x = sx;\n\t\tthis.y = sy;\n\t\tthis.z = sz;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixColumn( m, index ) {\n\n\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t}\n\n\tsetFromMatrix3Column( m, index ) {\n\n\t\treturn this.fromArray( m.elements, index * 3 );\n\n\t}\n\n\tsetFromEuler( e ) {\n\n\t\tthis.x = e._x;\n\t\tthis.y = e._y;\n\t\tthis.z = e._z;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\t\tthis.z = array[ offset + 2 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\t\tarray[ offset + 2 ] = this.z;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\t\tthis.z = attribute.getZ( index );\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\t\tthis.z = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\trandomDirection() {\n\n\t\t// Derived from https://mathworld.wolfram.com/SpherePointPicking.html\n\n\t\tconst u = ( Math.random() - 0.5 ) * 2;\n\t\tconst t = Math.random() * Math.PI * 2;\n\t\tconst f = Math.sqrt( 1 - u ** 2 );\n\n\t\tthis.x = f * Math.cos( t );\n\t\tthis.y = f * Math.sin( t );\n\t\tthis.z = u;\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\t\tyield this.z;\n\n\t}\n\n}\n\nVector3.prototype.isVector3 = true;\n\nconst _vector$c = /*@__PURE__*/ new Vector3();\nconst _quaternion$4 = /*@__PURE__*/ new Quaternion();\n\nclass Box3 {\n\n\tconstructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) {\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tset( min, max ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromArray( array ) {\n\n\t\tlet minX = + Infinity;\n\t\tlet minY = + Infinity;\n\t\tlet minZ = + Infinity;\n\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\tfor ( let i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\tconst x = array[ i ];\n\t\t\tconst y = array[ i + 1 ];\n\t\t\tconst z = array[ i + 2 ];\n\n\t\t\tif ( x < minX ) minX = x;\n\t\t\tif ( y < minY ) minY = y;\n\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\tif ( x > maxX ) maxX = x;\n\t\t\tif ( y > maxY ) maxY = y;\n\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t}\n\n\t\tthis.min.set( minX, minY, minZ );\n\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromBufferAttribute( attribute ) {\n\n\t\tlet minX = + Infinity;\n\t\tlet minY = + Infinity;\n\t\tlet minZ = + Infinity;\n\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\tfor ( let i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\tconst x = attribute.getX( i );\n\t\t\tconst y = attribute.getY( i );\n\t\t\tconst z = attribute.getZ( i );\n\n\t\t\tif ( x < minX ) minX = x;\n\t\t\tif ( y < minY ) minY = y;\n\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\tif ( x > maxX ) maxX = x;\n\t\t\tif ( y > maxY ) maxY = y;\n\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t}\n\n\t\tthis.min.set( minX, minY, minZ );\n\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tthis.makeEmpty();\n\n\t\tfor ( let i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCenterAndSize( center, size ) {\n\n\t\tconst halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 );\n\n\t\tthis.min.copy( center ).sub( halfSize );\n\t\tthis.max.copy( center ).add( halfSize );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromObject( object, precise = false ) {\n\n\t\tthis.makeEmpty();\n\n\t\treturn this.expandByObject( object, precise );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( box ) {\n\n\t\tthis.min.copy( box.min );\n\t\tthis.max.copy( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tmakeEmpty() {\n\n\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\treturn this;\n\n\t}\n\n\tisEmpty() {\n\n\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t}\n\n\tgetCenter( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t}\n\n\tgetSize( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );\n\n\t}\n\n\texpandByPoint( point ) {\n\n\t\tthis.min.min( point );\n\t\tthis.max.max( point );\n\n\t\treturn this;\n\n\t}\n\n\texpandByVector( vector ) {\n\n\t\tthis.min.sub( vector );\n\t\tthis.max.add( vector );\n\n\t\treturn this;\n\n\t}\n\n\texpandByScalar( scalar ) {\n\n\t\tthis.min.addScalar( - scalar );\n\t\tthis.max.addScalar( scalar );\n\n\t\treturn this;\n\n\t}\n\n\texpandByObject( object, precise = false ) {\n\n\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t// accounting for both the object's, and children's, world transforms\n\n\t\tobject.updateWorldMatrix( false, false );\n\n\t\tconst geometry = object.geometry;\n\n\t\tif ( geometry !== undefined ) {\n\n\t\t\tif ( precise && geometry.attributes != undefined && geometry.attributes.position !== undefined ) {\n\n\t\t\t\tconst position = geometry.attributes.position;\n\t\t\t\tfor ( let i = 0, l = position.count; i < l; i ++ ) {\n\n\t\t\t\t\t_vector$b.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );\n\t\t\t\t\tthis.expandByPoint( _vector$b );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( geometry.boundingBox === null ) {\n\n\t\t\t\t\tgeometry.computeBoundingBox();\n\n\t\t\t\t}\n\n\t\t\t\t_box$3.copy( geometry.boundingBox );\n\t\t\t\t_box$3.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tthis.union( _box$3 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst children = object.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tthis.expandByObject( children[ i ], precise );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t}\n\n\tcontainsBox( box ) {\n\n\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t}\n\n\tgetParameter( point, target ) {\n\n\t\t// This can potentially have a divide by zero if the box\n\t\t// has a size dimension of 0.\n\n\t\treturn target.set(\n\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t);\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\t// using 6 splitting planes to rule out intersections.\n\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\t// Find the point on the AABB closest to the sphere center.\n\t\tthis.clampPoint( sphere.center, _vector$b );\n\n\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\treturn _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\tlet min, max;\n\n\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t} else {\n\n\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t}\n\n\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t} else {\n\n\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t}\n\n\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t} else {\n\n\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t}\n\n\t\treturn ( min <= - plane.constant && max >= - plane.constant );\n\n\t}\n\n\tintersectsTriangle( triangle ) {\n\n\t\tif ( this.isEmpty() ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// compute box center and extents\n\t\tthis.getCenter( _center );\n\t\t_extents.subVectors( this.max, _center );\n\n\t\t// translate triangle to aabb origin\n\t\t_v0$2.subVectors( triangle.a, _center );\n\t\t_v1$7.subVectors( triangle.b, _center );\n\t\t_v2$3.subVectors( triangle.c, _center );\n\n\t\t// compute edge vectors for triangle\n\t\t_f0.subVectors( _v1$7, _v0$2 );\n\t\t_f1.subVectors( _v2$3, _v1$7 );\n\t\t_f2.subVectors( _v0$2, _v2$3 );\n\n\t\t// test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb\n\t\t// make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation\n\t\t// axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)\n\t\tlet axes = [\n\t\t\t0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y,\n\t\t\t_f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x,\n\t\t\t- _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0\n\t\t];\n\t\tif ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// test 3 face normals from the aabb\n\t\taxes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];\n\t\tif ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// finally testing the face normal of the triangle\n\t\t// use already existing triangle edge vectors here\n\t\t_triangleNormal.crossVectors( _f0, _f1 );\n\t\taxes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ];\n\n\t\treturn satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents );\n\n\t}\n\n\tclampPoint( point, target ) {\n\n\t\treturn target.copy( point ).clamp( this.min, this.max );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\tconst clampedPoint = _vector$b.copy( point ).clamp( this.min, this.max );\n\n\t\treturn clampedPoint.sub( point ).length();\n\n\t}\n\n\tgetBoundingSphere( target ) {\n\n\t\tthis.getCenter( target.center );\n\n\t\ttarget.radius = this.getSize( _vector$b ).length() * 0.5;\n\n\t\treturn target;\n\n\t}\n\n\tintersect( box ) {\n\n\t\tthis.min.max( box.min );\n\t\tthis.max.min( box.max );\n\n\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\tif ( this.isEmpty() ) this.makeEmpty();\n\n\t\treturn this;\n\n\t}\n\n\tunion( box ) {\n\n\t\tthis.min.min( box.min );\n\t\tthis.max.max( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\t// transform of empty box is an empty box.\n\t\tif ( this.isEmpty() ) return this;\n\n\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t_points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t_points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t_points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t_points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t_points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t_points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t_points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t_points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111\n\n\t\tthis.setFromPoints( _points );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.min.add( offset );\n\t\tthis.max.add( offset );\n\n\t\treturn this;\n\n\t}\n\n\tequals( box ) {\n\n\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t}\n\n}\n\nBox3.prototype.isBox3 = true;\n\nconst _points = [\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3()\n];\n\nconst _vector$b = /*@__PURE__*/ new Vector3();\n\nconst _box$3 = /*@__PURE__*/ new Box3();\n\n// triangle centered vertices\n\nconst _v0$2 = /*@__PURE__*/ new Vector3();\nconst _v1$7 = /*@__PURE__*/ new Vector3();\nconst _v2$3 = /*@__PURE__*/ new Vector3();\n\n// triangle edge vectors\n\nconst _f0 = /*@__PURE__*/ new Vector3();\nconst _f1 = /*@__PURE__*/ new Vector3();\nconst _f2 = /*@__PURE__*/ new Vector3();\n\nconst _center = /*@__PURE__*/ new Vector3();\nconst _extents = /*@__PURE__*/ new Vector3();\nconst _triangleNormal = /*@__PURE__*/ new Vector3();\nconst _testAxis = /*@__PURE__*/ new Vector3();\n\nfunction satForAxes( axes, v0, v1, v2, extents ) {\n\n\tfor ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) {\n\n\t\t_testAxis.fromArray( axes, i );\n\t\t// project the aabb onto the separating axis\n\t\tconst r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z );\n\t\t// project all 3 vertices of the triangle onto the separating axis\n\t\tconst p0 = v0.dot( _testAxis );\n\t\tconst p1 = v1.dot( _testAxis );\n\t\tconst p2 = v2.dot( _testAxis );\n\t\t// actual test, basically see if either of the most extreme of the triangle points intersects r\n\t\tif ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {\n\n\t\t\t// points of the projected triangle are outside the projected half-length of the aabb\n\t\t\t// the axis is separating and we can exit\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\treturn true;\n\n}\n\nconst _box$2 = /*@__PURE__*/ new Box3();\nconst _v1$6 = /*@__PURE__*/ new Vector3();\nconst _toFarthestPoint = /*@__PURE__*/ new Vector3();\nconst _toPoint = /*@__PURE__*/ new Vector3();\n\nclass Sphere {\n\n\tconstructor( center = new Vector3(), radius = - 1 ) {\n\n\t\tthis.center = center;\n\t\tthis.radius = radius;\n\n\t}\n\n\tset( center, radius ) {\n\n\t\tthis.center.copy( center );\n\t\tthis.radius = radius;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points, optionalCenter ) {\n\n\t\tconst center = this.center;\n\n\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\tcenter.copy( optionalCenter );\n\n\t\t} else {\n\n\t\t\t_box$2.setFromPoints( points ).getCenter( center );\n\n\t\t}\n\n\t\tlet maxRadiusSq = 0;\n\n\t\tfor ( let i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t}\n\n\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( sphere ) {\n\n\t\tthis.center.copy( sphere.center );\n\t\tthis.radius = sphere.radius;\n\n\t\treturn this;\n\n\t}\n\n\tisEmpty() {\n\n\t\treturn ( this.radius < 0 );\n\n\t}\n\n\tmakeEmpty() {\n\n\t\tthis.center.set( 0, 0, 0 );\n\t\tthis.radius = - 1;\n\n\t\treturn this;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\tconst radiusSum = this.radius + sphere.radius;\n\n\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsSphere( this );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\treturn Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;\n\n\t}\n\n\tclampPoint( point, target ) {\n\n\t\tconst deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\ttarget.copy( point );\n\n\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\ttarget.sub( this.center ).normalize();\n\t\t\ttarget.multiplyScalar( this.radius ).add( this.center );\n\n\t\t}\n\n\t\treturn target;\n\n\t}\n\n\tgetBoundingBox( target ) {\n\n\t\tif ( this.isEmpty() ) {\n\n\t\t\t// Empty sphere produces empty bounding box\n\t\t\ttarget.makeEmpty();\n\t\t\treturn target;\n\n\t\t}\n\n\t\ttarget.set( this.center, this.center );\n\t\ttarget.expandByScalar( this.radius );\n\n\t\treturn target;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tthis.center.applyMatrix4( matrix );\n\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.center.add( offset );\n\n\t\treturn this;\n\n\t}\n\n\texpandByPoint( point ) {\n\n\t\t// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671\n\n\t\t_toPoint.subVectors( point, this.center );\n\n\t\tconst lengthSq = _toPoint.lengthSq();\n\n\t\tif ( lengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\tconst length = Math.sqrt( lengthSq );\n\t\t\tconst missingRadiusHalf = ( length - this.radius ) * 0.5;\n\n\t\t\t// Nudge this sphere towards the target point. Add half the missing distance to radius,\n\t\t\t// and the other half to position. This gives a tighter enclosure, instead of if\n\t\t\t// the whole missing distance were just added to radius.\n\n\t\t\tthis.center.add( _toPoint.multiplyScalar( missingRadiusHalf / length ) );\n\t\t\tthis.radius += missingRadiusHalf;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tunion( sphere ) {\n\n\t\t// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769\n\n\t\t// To enclose another sphere into this sphere, we only need to enclose two points:\n\t\t// 1) Enclose the farthest point on the other sphere into this sphere.\n\t\t// 2) Enclose the opposite point of the farthest point into this sphere.\n\n\t\t if ( this.center.equals( sphere.center ) === true ) {\n\n\t\t\t _toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius );\n\n\n\t\t} else {\n\n\t\t\t_toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius );\n\n\t\t}\n\n\t\tthis.expandByPoint( _v1$6.copy( sphere.center ).add( _toFarthestPoint ) );\n\t\tthis.expandByPoint( _v1$6.copy( sphere.center ).sub( _toFarthestPoint ) );\n\n\t\treturn this;\n\n\t}\n\n\tequals( sphere ) {\n\n\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nconst _vector$a = /*@__PURE__*/ new Vector3();\nconst _segCenter = /*@__PURE__*/ new Vector3();\nconst _segDir = /*@__PURE__*/ new Vector3();\nconst _diff = /*@__PURE__*/ new Vector3();\n\nconst _edge1 = /*@__PURE__*/ new Vector3();\nconst _edge2 = /*@__PURE__*/ new Vector3();\nconst _normal$1 = /*@__PURE__*/ new Vector3();\n\nclass Ray {\n\n\tconstructor( origin = new Vector3(), direction = new Vector3( 0, 0, - 1 ) ) {\n\n\t\tthis.origin = origin;\n\t\tthis.direction = direction;\n\n\t}\n\n\tset( origin, direction ) {\n\n\t\tthis.origin.copy( origin );\n\t\tthis.direction.copy( direction );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( ray ) {\n\n\t\tthis.origin.copy( ray.origin );\n\t\tthis.direction.copy( ray.direction );\n\n\t\treturn this;\n\n\t}\n\n\tat( t, target ) {\n\n\t\treturn target.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t}\n\n\tlookAt( v ) {\n\n\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\treturn this;\n\n\t}\n\n\trecast( t ) {\n\n\t\tthis.origin.copy( this.at( t, _vector$a ) );\n\n\t\treturn this;\n\n\t}\n\n\tclosestPointToPoint( point, target ) {\n\n\t\ttarget.subVectors( point, this.origin );\n\n\t\tconst directionDistance = target.dot( this.direction );\n\n\t\tif ( directionDistance < 0 ) {\n\n\t\t\treturn target.copy( this.origin );\n\n\t\t}\n\n\t\treturn target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t}\n\n\tdistanceSqToPoint( point ) {\n\n\t\tconst directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t// point behind the ray\n\n\t\tif ( directionDistance < 0 ) {\n\n\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t}\n\n\t\t_vector$a.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\treturn _vector$a.distanceToSquared( point );\n\n\t}\n\n\tdistanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t// It returns the min distance between the ray and the segment\n\t\t// defined by v0 and v1\n\t\t// It can also set two optional targets :\n\t\t// - The closest point on the ray\n\t\t// - The closest point on the segment\n\n\t\t_segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t_segDir.copy( v1 ).sub( v0 ).normalize();\n\t\t_diff.copy( this.origin ).sub( _segCenter );\n\n\t\tconst segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\tconst a01 = - this.direction.dot( _segDir );\n\t\tconst b0 = _diff.dot( this.direction );\n\t\tconst b1 = - _diff.dot( _segDir );\n\t\tconst c = _diff.lengthSq();\n\t\tconst det = Math.abs( 1 - a01 * a01 );\n\t\tlet s0, s1, sqrDist, extDet;\n\n\t\tif ( det > 0 ) {\n\n\t\t\t// The ray and segment are not parallel.\n\n\t\t\ts0 = a01 * b1 - b0;\n\t\t\ts1 = a01 * b0 - b1;\n\t\t\textDet = segExtent * det;\n\n\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\tconst invDet = 1 / det;\n\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// region 5\n\n\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t// region 4\n\n\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t// region 3\n\n\t\t\t\t\ts0 = 0;\n\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// region 2\n\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// Ray and segment are parallel.\n\n\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t}\n\n\t\tif ( optionalPointOnRay ) {\n\n\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t}\n\n\t\tif ( optionalPointOnSegment ) {\n\n\t\t\toptionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter );\n\n\t\t}\n\n\t\treturn sqrDist;\n\n\t}\n\n\tintersectSphere( sphere, target ) {\n\n\t\t_vector$a.subVectors( sphere.center, this.origin );\n\t\tconst tca = _vector$a.dot( this.direction );\n\t\tconst d2 = _vector$a.dot( _vector$a ) - tca * tca;\n\t\tconst radius2 = sphere.radius * sphere.radius;\n\n\t\tif ( d2 > radius2 ) return null;\n\n\t\tconst thc = Math.sqrt( radius2 - d2 );\n\n\t\t// t0 = first intersect point - entrance on front of sphere\n\t\tconst t0 = tca - thc;\n\n\t\t// t1 = second intersect point - exit point on back of sphere\n\t\tconst t1 = tca + thc;\n\n\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t// test to see if t0 is behind the ray:\n\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t// in order to always return an intersect point that is in front of the ray.\n\t\tif ( t0 < 0 ) return this.at( t1, target );\n\n\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\treturn this.at( t0, target );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\treturn this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t}\n\n\tdistanceToPlane( plane ) {\n\n\t\tconst denominator = plane.normal.dot( this.direction );\n\n\t\tif ( denominator === 0 ) {\n\n\t\t\t// line is coplanar, return origin\n\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\treturn 0;\n\n\t\t\t}\n\n\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t// Return if the ray never intersects the plane\n\n\t\treturn t >= 0 ? t : null;\n\n\t}\n\n\tintersectPlane( plane, target ) {\n\n\t\tconst t = this.distanceToPlane( plane );\n\n\t\tif ( t === null ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\treturn this.at( t, target );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\t// check if the ray lies on the plane first\n\n\t\tconst distToPoint = plane.distanceToPoint( this.origin );\n\n\t\tif ( distToPoint === 0 ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tconst denominator = plane.normal.dot( this.direction );\n\n\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\treturn false;\n\n\t}\n\n\tintersectBox( box, target ) {\n\n\t\tlet tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\tconst invdirx = 1 / this.direction.x,\n\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\tconst origin = this.origin;\n\n\t\tif ( invdirx >= 0 ) {\n\n\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t} else {\n\n\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t}\n\n\t\tif ( invdiry >= 0 ) {\n\n\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t} else {\n\n\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t}\n\n\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\tif ( invdirz >= 0 ) {\n\n\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t} else {\n\n\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t}\n\n\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t//return point closest to the ray (positive side)\n\n\t\tif ( tmax < 0 ) return null;\n\n\t\treturn this.at( tmin >= 0 ? tmin : tmax, target );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn this.intersectBox( box, _vector$a ) !== null;\n\n\t}\n\n\tintersectTriangle( a, b, c, backfaceCulling, target ) {\n\n\t\t// Compute the offset origin, edges, and normal.\n\n\t\t// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t_edge1.subVectors( b, a );\n\t\t_edge2.subVectors( c, a );\n\t\t_normal$1.crossVectors( _edge1, _edge2 );\n\n\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\tlet DdN = this.direction.dot( _normal$1 );\n\t\tlet sign;\n\n\t\tif ( DdN > 0 ) {\n\n\t\t\tif ( backfaceCulling ) return null;\n\t\t\tsign = 1;\n\n\t\t} else if ( DdN < 0 ) {\n\n\t\t\tsign = - 1;\n\t\t\tDdN = - DdN;\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t_diff.subVectors( this.origin, a );\n\t\tconst DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) );\n\n\t\t// b1 < 0, no intersection\n\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) );\n\n\t\t// b2 < 0, no intersection\n\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// b1+b2 > 1, no intersection\n\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// Line intersects triangle, check if ray does.\n\t\tconst QdN = - sign * _diff.dot( _normal$1 );\n\n\t\t// t < 0, no intersection\n\t\tif ( QdN < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// Ray intersects triangle.\n\t\treturn this.at( QdN / DdN, target );\n\n\t}\n\n\tapplyMatrix4( matrix4 ) {\n\n\t\tthis.origin.applyMatrix4( matrix4 );\n\t\tthis.direction.transformDirection( matrix4 );\n\n\t\treturn this;\n\n\t}\n\n\tequals( ray ) {\n\n\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nclass Matrix4 {\n\n\tconstructor() {\n\n\t\tthis.elements = [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t];\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tset( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new Matrix4().fromArray( this.elements );\n\n\t}\n\n\tcopy( m ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tte[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];\n\t\tte[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];\n\t\tte[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];\n\t\tte[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];\n\n\t\treturn this;\n\n\t}\n\n\tcopyPosition( m ) {\n\n\t\tconst te = this.elements, me = m.elements;\n\n\t\tte[ 12 ] = me[ 12 ];\n\t\tte[ 13 ] = me[ 13 ];\n\t\tte[ 14 ] = me[ 14 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrix3( m ) {\n\n\t\tconst me = m.elements;\n\n\t\tthis.set(\n\n\t\t\tme[ 0 ], me[ 3 ], me[ 6 ], 0,\n\t\t\tme[ 1 ], me[ 4 ], me[ 7 ], 0,\n\t\t\tme[ 2 ], me[ 5 ], me[ 8 ], 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\textractBasis( xAxis, yAxis, zAxis ) {\n\n\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\treturn this;\n\n\t}\n\n\tmakeBasis( xAxis, yAxis, zAxis ) {\n\n\t\tthis.set(\n\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t0, 0, 0, 1\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\textractRotation( m ) {\n\n\t\t// this method does not support reflection matrices\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tconst scaleX = 1 / _v1$5.setFromMatrixColumn( m, 0 ).length();\n\t\tconst scaleY = 1 / _v1$5.setFromMatrixColumn( m, 1 ).length();\n\t\tconst scaleZ = 1 / _v1$5.setFromMatrixColumn( m, 2 ).length();\n\n\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\t\tte[ 3 ] = 0;\n\n\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\t\tte[ 7 ] = 0;\n\n\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\t\tte[ 11 ] = 0;\n\n\t\tte[ 12 ] = 0;\n\t\tte[ 13 ] = 0;\n\t\tte[ 14 ] = 0;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationFromEuler( euler ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\tconst te = this.elements;\n\n\t\tconst x = euler.x, y = euler.y, z = euler.z;\n\t\tconst a = Math.cos( x ), b = Math.sin( x );\n\t\tconst c = Math.cos( y ), d = Math.sin( y );\n\t\tconst e = Math.cos( z ), f = Math.sin( z );\n\n\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\tconst ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = - c * f;\n\t\t\tte[ 8 ] = d;\n\n\t\t\tte[ 1 ] = af + be * d;\n\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\tte[ 9 ] = - b * c;\n\n\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\tte[ 6 ] = be + af * d;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\tconst ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\tte[ 0 ] = ce + df * b;\n\t\t\tte[ 4 ] = de * b - cf;\n\t\t\tte[ 8 ] = a * d;\n\n\t\t\tte[ 1 ] = a * f;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = - b;\n\n\t\t\tte[ 2 ] = cf * b - de;\n\t\t\tte[ 6 ] = df + ce * b;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\tconst ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\tte[ 0 ] = ce - df * b;\n\t\t\tte[ 4 ] = - a * f;\n\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\tte[ 1 ] = cf + de * b;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\tte[ 2 ] = - a * d;\n\t\t\tte[ 6 ] = b;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\tconst ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = be * d - af;\n\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\tte[ 1 ] = c * f;\n\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\tte[ 2 ] = - d;\n\t\t\tte[ 6 ] = b * c;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\tconst ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\tte[ 1 ] = f;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = - b * e;\n\n\t\t\tte[ 2 ] = - d * e;\n\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\tconst ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = - f;\n\t\t\tte[ 8 ] = d * e;\n\n\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\tte[ 6 ] = b * e;\n\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t}\n\n\t\t// bottom row\n\t\tte[ 3 ] = 0;\n\t\tte[ 7 ] = 0;\n\t\tte[ 11 ] = 0;\n\n\t\t// last column\n\t\tte[ 12 ] = 0;\n\t\tte[ 13 ] = 0;\n\t\tte[ 14 ] = 0;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationFromQuaternion( q ) {\n\n\t\treturn this.compose( _zero, q, _one );\n\n\t}\n\n\tlookAt( eye, target, up ) {\n\n\t\tconst te = this.elements;\n\n\t\t_z.subVectors( eye, target );\n\n\t\tif ( _z.lengthSq() === 0 ) {\n\n\t\t\t// eye and target are in the same position\n\n\t\t\t_z.z = 1;\n\n\t\t}\n\n\t\t_z.normalize();\n\t\t_x.crossVectors( up, _z );\n\n\t\tif ( _x.lengthSq() === 0 ) {\n\n\t\t\t// up and z are parallel\n\n\t\t\tif ( Math.abs( up.z ) === 1 ) {\n\n\t\t\t\t_z.x += 0.0001;\n\n\t\t\t} else {\n\n\t\t\t\t_z.z += 0.0001;\n\n\t\t\t}\n\n\t\t\t_z.normalize();\n\t\t\t_x.crossVectors( up, _z );\n\n\t\t}\n\n\t\t_x.normalize();\n\t\t_y.crossVectors( _z, _x );\n\n\t\tte[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x;\n\t\tte[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y;\n\t\tte[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( m, n ) {\n\n\t\tif ( n !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t}\n\n\t\treturn this.multiplyMatrices( this, m );\n\n\t}\n\n\tpremultiply( m ) {\n\n\t\treturn this.multiplyMatrices( m, this );\n\n\t}\n\n\tmultiplyMatrices( a, b ) {\n\n\t\tconst ae = a.elements;\n\t\tconst be = b.elements;\n\t\tconst te = this.elements;\n\n\t\tconst a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\tconst a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\tconst a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\tconst a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\tconst b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\tconst b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\tconst b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\tconst b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\treturn this;\n\n\t}\n\n\tdeterminant() {\n\n\t\tconst te = this.elements;\n\n\t\tconst n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\tconst n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\tconst n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\tconst n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t//TODO: make this more efficient\n\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\treturn (\n\t\t\tn41 * (\n\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t - n13 * n24 * n32\n\t\t\t\t - n14 * n22 * n33\n\t\t\t\t + n12 * n24 * n33\n\t\t\t\t + n13 * n22 * n34\n\t\t\t\t - n12 * n23 * n34\n\t\t\t) +\n\t\t\tn42 * (\n\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t - n11 * n24 * n33\n\t\t\t\t + n14 * n21 * n33\n\t\t\t\t - n13 * n21 * n34\n\t\t\t\t + n13 * n24 * n31\n\t\t\t\t - n14 * n23 * n31\n\t\t\t) +\n\t\t\tn43 * (\n\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t - n11 * n22 * n34\n\t\t\t\t - n14 * n21 * n32\n\t\t\t\t + n12 * n21 * n34\n\t\t\t\t + n14 * n22 * n31\n\t\t\t\t - n12 * n24 * n31\n\t\t\t) +\n\t\t\tn44 * (\n\t\t\t\t- n13 * n22 * n31\n\t\t\t\t - n11 * n23 * n32\n\t\t\t\t + n11 * n22 * n33\n\t\t\t\t + n13 * n21 * n32\n\t\t\t\t - n12 * n21 * n33\n\t\t\t\t + n12 * n23 * n31\n\t\t\t)\n\n\t\t);\n\n\t}\n\n\ttranspose() {\n\n\t\tconst te = this.elements;\n\t\tlet tmp;\n\n\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\treturn this;\n\n\t}\n\n\tsetPosition( x, y, z ) {\n\n\t\tconst te = this.elements;\n\n\t\tif ( x.isVector3 ) {\n\n\t\t\tte[ 12 ] = x.x;\n\t\t\tte[ 13 ] = x.y;\n\t\t\tte[ 14 ] = x.z;\n\n\t\t} else {\n\n\t\t\tte[ 12 ] = x;\n\t\t\tte[ 13 ] = y;\n\t\t\tte[ 14 ] = z;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tinvert() {\n\n\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\tconst te = this.elements,\n\n\t\t\tn11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ],\n\t\t\tn12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ],\n\t\t\tn13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ],\n\t\t\tn14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ],\n\n\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\tconst det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\tif ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );\n\n\t\tconst detInv = 1 / det;\n\n\t\tte[ 0 ] = t11 * detInv;\n\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\tte[ 4 ] = t12 * detInv;\n\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\tte[ 8 ] = t13 * detInv;\n\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\tte[ 12 ] = t14 * detInv;\n\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\treturn this;\n\n\t}\n\n\tscale( v ) {\n\n\t\tconst te = this.elements;\n\t\tconst x = v.x, y = v.y, z = v.z;\n\n\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\treturn this;\n\n\t}\n\n\tgetMaxScaleOnAxis() {\n\n\t\tconst te = this.elements;\n\n\t\tconst scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\tconst scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\tconst scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t}\n\n\tmakeTranslation( x, y, z ) {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, x,\n\t\t\t0, 1, 0, y,\n\t\t\t0, 0, 1, z,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationX( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, c, - s, 0,\n\t\t\t0, s, c, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationY( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\t c, 0, s, 0,\n\t\t\t 0, 1, 0, 0,\n\t\t\t- s, 0, c, 0,\n\t\t\t 0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationZ( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\tc, - s, 0, 0,\n\t\t\ts, c, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationAxis( axis, angle ) {\n\n\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\tconst c = Math.cos( angle );\n\t\tconst s = Math.sin( angle );\n\t\tconst t = 1 - c;\n\t\tconst x = axis.x, y = axis.y, z = axis.z;\n\t\tconst tx = t * x, ty = t * y;\n\n\t\tthis.set(\n\n\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeScale( x, y, z ) {\n\n\t\tthis.set(\n\n\t\t\tx, 0, 0, 0,\n\t\t\t0, y, 0, 0,\n\t\t\t0, 0, z, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeShear( xy, xz, yx, yz, zx, zy ) {\n\n\t\tthis.set(\n\n\t\t\t1, yx, zx, 0,\n\t\t\txy, 1, zy, 0,\n\t\t\txz, yz, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tcompose( position, quaternion, scale ) {\n\n\t\tconst te = this.elements;\n\n\t\tconst x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;\n\t\tconst x2 = x + x,\ty2 = y + y, z2 = z + z;\n\t\tconst xx = x * x2, xy = x * y2, xz = x * z2;\n\t\tconst yy = y * y2, yz = y * z2, zz = z * z2;\n\t\tconst wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\tconst sx = scale.x, sy = scale.y, sz = scale.z;\n\n\t\tte[ 0 ] = ( 1 - ( yy + zz ) ) * sx;\n\t\tte[ 1 ] = ( xy + wz ) * sx;\n\t\tte[ 2 ] = ( xz - wy ) * sx;\n\t\tte[ 3 ] = 0;\n\n\t\tte[ 4 ] = ( xy - wz ) * sy;\n\t\tte[ 5 ] = ( 1 - ( xx + zz ) ) * sy;\n\t\tte[ 6 ] = ( yz + wx ) * sy;\n\t\tte[ 7 ] = 0;\n\n\t\tte[ 8 ] = ( xz + wy ) * sz;\n\t\tte[ 9 ] = ( yz - wx ) * sz;\n\t\tte[ 10 ] = ( 1 - ( xx + yy ) ) * sz;\n\t\tte[ 11 ] = 0;\n\n\t\tte[ 12 ] = position.x;\n\t\tte[ 13 ] = position.y;\n\t\tte[ 14 ] = position.z;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tdecompose( position, quaternion, scale ) {\n\n\t\tconst te = this.elements;\n\n\t\tlet sx = _v1$5.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\tconst sy = _v1$5.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\tconst sz = _v1$5.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t// if determine is negative, we need to invert one scale\n\t\tconst det = this.determinant();\n\t\tif ( det < 0 ) sx = - sx;\n\n\t\tposition.x = te[ 12 ];\n\t\tposition.y = te[ 13 ];\n\t\tposition.z = te[ 14 ];\n\n\t\t// scale the rotation part\n\t\t_m1$2.copy( this );\n\n\t\tconst invSX = 1 / sx;\n\t\tconst invSY = 1 / sy;\n\t\tconst invSZ = 1 / sz;\n\n\t\t_m1$2.elements[ 0 ] *= invSX;\n\t\t_m1$2.elements[ 1 ] *= invSX;\n\t\t_m1$2.elements[ 2 ] *= invSX;\n\n\t\t_m1$2.elements[ 4 ] *= invSY;\n\t\t_m1$2.elements[ 5 ] *= invSY;\n\t\t_m1$2.elements[ 6 ] *= invSY;\n\n\t\t_m1$2.elements[ 8 ] *= invSZ;\n\t\t_m1$2.elements[ 9 ] *= invSZ;\n\t\t_m1$2.elements[ 10 ] *= invSZ;\n\n\t\tquaternion.setFromRotationMatrix( _m1$2 );\n\n\t\tscale.x = sx;\n\t\tscale.y = sy;\n\t\tscale.z = sz;\n\n\t\treturn this;\n\n\t}\n\n\tmakePerspective( left, right, top, bottom, near, far ) {\n\n\t\tif ( far === undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t}\n\n\t\tconst te = this.elements;\n\t\tconst x = 2 * near / ( right - left );\n\t\tconst y = 2 * near / ( top - bottom );\n\n\t\tconst a = ( right + left ) / ( right - left );\n\t\tconst b = ( top + bottom ) / ( top - bottom );\n\t\tconst c = - ( far + near ) / ( far - near );\n\t\tconst d = - 2 * far * near / ( far - near );\n\n\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\treturn this;\n\n\t}\n\n\tmakeOrthographic( left, right, top, bottom, near, far ) {\n\n\t\tconst te = this.elements;\n\t\tconst w = 1.0 / ( right - left );\n\t\tconst h = 1.0 / ( top - bottom );\n\t\tconst p = 1.0 / ( far - near );\n\n\t\tconst x = ( right + left ) * w;\n\t\tconst y = ( top + bottom ) * h;\n\t\tconst z = ( far + near ) * p;\n\n\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tequals( matrix ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = matrix.elements;\n\n\t\tfor ( let i = 0; i < 16; i ++ ) {\n\n\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tfor ( let i = 0; i < 16; i ++ ) {\n\n\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tconst te = this.elements;\n\n\t\tarray[ offset ] = te[ 0 ];\n\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\treturn array;\n\n\t}\n\n}\n\nMatrix4.prototype.isMatrix4 = true;\n\nconst _v1$5 = /*@__PURE__*/ new Vector3();\nconst _m1$2 = /*@__PURE__*/ new Matrix4();\nconst _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 );\nconst _one = /*@__PURE__*/ new Vector3( 1, 1, 1 );\nconst _x = /*@__PURE__*/ new Vector3();\nconst _y = /*@__PURE__*/ new Vector3();\nconst _z = /*@__PURE__*/ new Vector3();\n\nconst _matrix$1 = /*@__PURE__*/ new Matrix4();\nconst _quaternion$3 = /*@__PURE__*/ new Quaternion();\n\nclass Euler {\n\n\tconstructor( x = 0, y = 0, z = 0, order = Euler.DefaultOrder ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._order = order;\n\n\t}\n\n\tget x() {\n\n\t\treturn this._x;\n\n\t}\n\n\tset x( value ) {\n\n\t\tthis._x = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget y() {\n\n\t\treturn this._y;\n\n\t}\n\n\tset y( value ) {\n\n\t\tthis._y = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget z() {\n\n\t\treturn this._z;\n\n\t}\n\n\tset z( value ) {\n\n\t\tthis._z = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget order() {\n\n\t\treturn this._order;\n\n\t}\n\n\tset order( value ) {\n\n\t\tthis._order = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tset( x, y, z, order = this._order ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._order = order;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t}\n\n\tcopy( euler ) {\n\n\t\tthis._x = euler._x;\n\t\tthis._y = euler._y;\n\t\tthis._z = euler._z;\n\t\tthis._order = euler._order;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromRotationMatrix( m, order = this._order, update = true ) {\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tconst te = m.elements;\n\t\tconst m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\tconst m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\tconst m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\tswitch ( order ) {\n\n\t\t\tcase 'XYZ':\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'YXZ':\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZXY':\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZYX':\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'YZX':\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'XZY':\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );\n\n\t\t}\n\n\t\tthis._order = order;\n\n\t\tif ( update === true ) this._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromQuaternion( q, order, update ) {\n\n\t\t_matrix$1.makeRotationFromQuaternion( q );\n\n\t\treturn this.setFromRotationMatrix( _matrix$1, order, update );\n\n\t}\n\n\tsetFromVector3( v, order = this._order ) {\n\n\t\treturn this.set( v.x, v.y, v.z, order );\n\n\t}\n\n\treorder( newOrder ) {\n\n\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t_quaternion$3.setFromEuler( this );\n\n\t\treturn this.setFromQuaternion( _quaternion$3, newOrder );\n\n\t}\n\n\tequals( euler ) {\n\n\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t}\n\n\tfromArray( array ) {\n\n\t\tthis._x = array[ 0 ];\n\t\tthis._y = array[ 1 ];\n\t\tthis._z = array[ 2 ];\n\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this._x;\n\t\tarray[ offset + 1 ] = this._y;\n\t\tarray[ offset + 2 ] = this._z;\n\t\tarray[ offset + 3 ] = this._order;\n\n\t\treturn array;\n\n\t}\n\n\t_onChange( callback ) {\n\n\t\tthis._onChangeCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\t_onChangeCallback() {}\n\n}\n\nEuler.prototype.isEuler = true;\n\nEuler.DefaultOrder = 'XYZ';\nEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\nclass Layers {\n\n\tconstructor() {\n\n\t\tthis.mask = 1 | 0;\n\n\t}\n\n\tset( channel ) {\n\n\t\tthis.mask = ( 1 << channel | 0 ) >>> 0;\n\n\t}\n\n\tenable( channel ) {\n\n\t\tthis.mask |= 1 << channel | 0;\n\n\t}\n\n\tenableAll() {\n\n\t\tthis.mask = 0xffffffff | 0;\n\n\t}\n\n\ttoggle( channel ) {\n\n\t\tthis.mask ^= 1 << channel | 0;\n\n\t}\n\n\tdisable( channel ) {\n\n\t\tthis.mask &= ~ ( 1 << channel | 0 );\n\n\t}\n\n\tdisableAll() {\n\n\t\tthis.mask = 0;\n\n\t}\n\n\ttest( layers ) {\n\n\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t}\n\n\tisEnabled( channel ) {\n\n\t\treturn ( this.mask & ( 1 << channel | 0 ) ) !== 0;\n\n\t}\n\n}\n\nlet _object3DId = 0;\n\nconst _v1$4 = /*@__PURE__*/ new Vector3();\nconst _q1 = /*@__PURE__*/ new Quaternion();\nconst _m1$1 = /*@__PURE__*/ new Matrix4();\nconst _target = /*@__PURE__*/ new Vector3();\n\nconst _position$3 = /*@__PURE__*/ new Vector3();\nconst _scale$2 = /*@__PURE__*/ new Vector3();\nconst _quaternion$2 = /*@__PURE__*/ new Quaternion();\n\nconst _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );\nconst _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );\nconst _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );\n\nconst _addedEvent = { type: 'added' };\nconst _removedEvent = { type: 'removed' };\n\nclass Object3D extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tObject.defineProperty( this, 'id', { value: _object3DId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tconst position = new Vector3();\n\t\tconst rotation = new Euler();\n\t\tconst quaternion = new Quaternion();\n\t\tconst scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation._onChange( onRotationChange );\n\t\tquaternion._onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.animations = [];\n\n\t\tthis.userData = {};\n\n\t}\n\n\tonBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {}\n\n\tonAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tthis.matrix.premultiply( matrix );\n\n\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\tthis.quaternion.premultiply( q );\n\n\t\treturn this;\n\n\t}\n\n\tsetRotationFromAxisAngle( axis, angle ) {\n\n\t\t// assumes axis is normalized\n\n\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t}\n\n\tsetRotationFromEuler( euler ) {\n\n\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t}\n\n\tsetRotationFromMatrix( m ) {\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t}\n\n\tsetRotationFromQuaternion( q ) {\n\n\t\t// assumes q is normalized\n\n\t\tthis.quaternion.copy( q );\n\n\t}\n\n\trotateOnAxis( axis, angle ) {\n\n\t\t// rotate object on axis in object space\n\t\t// axis is assumed to be normalized\n\n\t\t_q1.setFromAxisAngle( axis, angle );\n\n\t\tthis.quaternion.multiply( _q1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateOnWorldAxis( axis, angle ) {\n\n\t\t// rotate object on axis in world space\n\t\t// axis is assumed to be normalized\n\t\t// method assumes no rotated parent\n\n\t\t_q1.setFromAxisAngle( axis, angle );\n\n\t\tthis.quaternion.premultiply( _q1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateX( angle ) {\n\n\t\treturn this.rotateOnAxis( _xAxis, angle );\n\n\t}\n\n\trotateY( angle ) {\n\n\t\treturn this.rotateOnAxis( _yAxis, angle );\n\n\t}\n\n\trotateZ( angle ) {\n\n\t\treturn this.rotateOnAxis( _zAxis, angle );\n\n\t}\n\n\ttranslateOnAxis( axis, distance ) {\n\n\t\t// translate object by distance along axis in object space\n\t\t// axis is assumed to be normalized\n\n\t\t_v1$4.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\tthis.position.add( _v1$4.multiplyScalar( distance ) );\n\n\t\treturn this;\n\n\t}\n\n\ttranslateX( distance ) {\n\n\t\treturn this.translateOnAxis( _xAxis, distance );\n\n\t}\n\n\ttranslateY( distance ) {\n\n\t\treturn this.translateOnAxis( _yAxis, distance );\n\n\t}\n\n\ttranslateZ( distance ) {\n\n\t\treturn this.translateOnAxis( _zAxis, distance );\n\n\t}\n\n\tlocalToWorld( vector ) {\n\n\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t}\n\n\tworldToLocal( vector ) {\n\n\t\treturn vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() );\n\n\t}\n\n\tlookAt( x, y, z ) {\n\n\t\t// This method does not support objects having non-uniformly-scaled parent(s)\n\n\t\tif ( x.isVector3 ) {\n\n\t\t\t_target.copy( x );\n\n\t\t} else {\n\n\t\t\t_target.set( x, y, z );\n\n\t\t}\n\n\t\tconst parent = this.parent;\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\t_position$3.setFromMatrixPosition( this.matrixWorld );\n\n\t\tif ( this.isCamera || this.isLight ) {\n\n\t\t\t_m1$1.lookAt( _position$3, _target, this.up );\n\n\t\t} else {\n\n\t\t\t_m1$1.lookAt( _target, _position$3, this.up );\n\n\t\t}\n\n\t\tthis.quaternion.setFromRotationMatrix( _m1$1 );\n\n\t\tif ( parent ) {\n\n\t\t\t_m1$1.extractRotation( parent.matrixWorld );\n\t\t\t_q1.setFromRotationMatrix( _m1$1 );\n\t\t\tthis.quaternion.premultiply( _q1.invert() );\n\n\t\t}\n\n\t}\n\n\tadd( object ) {\n\n\t\tif ( arguments.length > 1 ) {\n\n\t\t\tfor ( let i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tif ( object === this ) {\n\n\t\t\tconsole.error( 'THREE.Object3D.add: object can\\'t be added as a child of itself.', object );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tif ( object && object.isObject3D ) {\n\n\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\tobject.parent.remove( object );\n\n\t\t\t}\n\n\t\t\tobject.parent = this;\n\t\t\tthis.children.push( object );\n\n\t\t\tobject.dispatchEvent( _addedEvent );\n\n\t\t} else {\n\n\t\t\tconsole.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tremove( object ) {\n\n\t\tif ( arguments.length > 1 ) {\n\n\t\t\tfor ( let i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst index = this.children.indexOf( object );\n\n\t\tif ( index !== - 1 ) {\n\n\t\t\tobject.parent = null;\n\t\t\tthis.children.splice( index, 1 );\n\n\t\t\tobject.dispatchEvent( _removedEvent );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tremoveFromParent() {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( parent !== null ) {\n\n\t\t\tparent.remove( this );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclear() {\n\n\t\tfor ( let i = 0; i < this.children.length; i ++ ) {\n\n\t\t\tconst object = this.children[ i ];\n\n\t\t\tobject.parent = null;\n\n\t\t\tobject.dispatchEvent( _removedEvent );\n\n\t\t}\n\n\t\tthis.children.length = 0;\n\n\t\treturn this;\n\n\n\t}\n\n\tattach( object ) {\n\n\t\t// adds object as a child of this, while maintaining the object's world transform\n\n\t\t// Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\t_m1$1.copy( this.matrixWorld ).invert();\n\n\t\tif ( object.parent !== null ) {\n\n\t\t\tobject.parent.updateWorldMatrix( true, false );\n\n\t\t\t_m1$1.multiply( object.parent.matrixWorld );\n\n\t\t}\n\n\t\tobject.applyMatrix4( _m1$1 );\n\n\t\tthis.add( object );\n\n\t\tobject.updateWorldMatrix( false, true );\n\n\t\treturn this;\n\n\t}\n\n\tgetObjectById( id ) {\n\n\t\treturn this.getObjectByProperty( 'id', id );\n\n\t}\n\n\tgetObjectByName( name ) {\n\n\t\treturn this.getObjectByProperty( 'name', name );\n\n\t}\n\n\tgetObjectByProperty( name, value ) {\n\n\t\tif ( this[ name ] === value ) return this;\n\n\t\tfor ( let i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\tconst child = this.children[ i ];\n\t\t\tconst object = child.getObjectByProperty( name, value );\n\n\t\t\tif ( object !== undefined ) {\n\n\t\t\t\treturn object;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn undefined;\n\n\t}\n\n\tgetWorldPosition( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\treturn target.setFromMatrixPosition( this.matrixWorld );\n\n\t}\n\n\tgetWorldQuaternion( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tthis.matrixWorld.decompose( _position$3, target, _scale$2 );\n\n\t\treturn target;\n\n\t}\n\n\tgetWorldScale( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tthis.matrixWorld.decompose( _position$3, _quaternion$2, target );\n\n\t\treturn target;\n\n\t}\n\n\tgetWorldDirection( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tconst e = this.matrixWorld.elements;\n\n\t\treturn target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();\n\n\t}\n\n\traycast( /* raycaster, intersects */ ) {}\n\n\ttraverse( callback ) {\n\n\t\tcallback( this );\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].traverse( callback );\n\n\t\t}\n\n\t}\n\n\ttraverseVisible( callback ) {\n\n\t\tif ( this.visible === false ) return;\n\n\t\tcallback( this );\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t}\n\n\t}\n\n\ttraverseAncestors( callback ) {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( parent !== null ) {\n\n\t\t\tcallback( parent );\n\n\t\t\tparent.traverseAncestors( callback );\n\n\t\t}\n\n\t}\n\n\tupdateMatrix() {\n\n\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tif ( this.matrixWorldNeedsUpdate || force ) {\n\n\t\t\tif ( this.parent === null ) {\n\n\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t} else {\n\n\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t}\n\n\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\tforce = true;\n\n\t\t}\n\n\t\t// update children\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t}\n\n\t}\n\n\tupdateWorldMatrix( updateParents, updateChildren ) {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( updateParents === true && parent !== null ) {\n\n\t\t\tparent.updateWorldMatrix( true, false );\n\n\t\t}\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tif ( this.parent === null ) {\n\n\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t} else {\n\n\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t}\n\n\t\t// update children\n\n\t\tif ( updateChildren === true ) {\n\n\t\t\tconst children = this.children;\n\n\t\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateWorldMatrix( false, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\t// meta is a string when called from JSON.stringify\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tconst output = {};\n\n\t\t// meta is a hash used to collect geometries, materials.\n\t\t// not providing it implies that this is the root object\n\t\t// being serialized.\n\t\tif ( isRootObject ) {\n\n\t\t\t// initialize meta obj\n\t\t\tmeta = {\n\t\t\t\tgeometries: {},\n\t\t\t\tmaterials: {},\n\t\t\t\ttextures: {},\n\t\t\t\timages: {},\n\t\t\t\tshapes: {},\n\t\t\t\tskeletons: {},\n\t\t\t\tanimations: {},\n\t\t\t\tnodes: {}\n\t\t\t};\n\n\t\t\toutput.metadata = {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Object',\n\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t};\n\n\t\t}\n\n\t\t// standard Object3D serialization\n\n\t\tconst object = {};\n\n\t\tobject.uuid = this.uuid;\n\t\tobject.type = this.type;\n\n\t\tif ( this.name !== '' ) object.name = this.name;\n\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\tif ( this.visible === false ) object.visible = false;\n\t\tif ( this.frustumCulled === false ) object.frustumCulled = false;\n\t\tif ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\n\t\tobject.layers = this.layers.mask;\n\t\tobject.matrix = this.matrix.toArray();\n\n\t\tif ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;\n\n\t\t// object specific properties\n\n\t\tif ( this.isInstancedMesh ) {\n\n\t\t\tobject.type = 'InstancedMesh';\n\t\t\tobject.count = this.count;\n\t\t\tobject.instanceMatrix = this.instanceMatrix.toJSON();\n\t\t\tif ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON();\n\n\t\t}\n\n\t\t//\n\n\t\tfunction serialize( library, element ) {\n\n\t\t\tif ( library[ element.uuid ] === undefined ) {\n\n\t\t\t\tlibrary[ element.uuid ] = element.toJSON( meta );\n\n\t\t\t}\n\n\t\t\treturn element.uuid;\n\n\t\t}\n\n\t\tif ( this.isScene ) {\n\n\t\t\tif ( this.background ) {\n\n\t\t\t\tif ( this.background.isColor ) {\n\n\t\t\t\t\tobject.background = this.background.toJSON();\n\n\t\t\t\t} else if ( this.background.isTexture ) {\n\n\t\t\t\t\tobject.background = this.background.toJSON( meta ).uuid;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.environment && this.environment.isTexture ) {\n\n\t\t\t\tobject.environment = this.environment.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t} else if ( this.isMesh || this.isLine || this.isPoints ) {\n\n\t\t\tobject.geometry = serialize( meta.geometries, this.geometry );\n\n\t\t\tconst parameters = this.geometry.parameters;\n\n\t\t\tif ( parameters !== undefined && parameters.shapes !== undefined ) {\n\n\t\t\t\tconst shapes = parameters.shapes;\n\n\t\t\t\tif ( Array.isArray( shapes ) ) {\n\n\t\t\t\t\tfor ( let i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tconst shape = shapes[ i ];\n\n\t\t\t\t\t\tserialize( meta.shapes, shape );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tserialize( meta.shapes, shapes );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.isSkinnedMesh ) {\n\n\t\t\tobject.bindMode = this.bindMode;\n\t\t\tobject.bindMatrix = this.bindMatrix.toArray();\n\n\t\t\tif ( this.skeleton !== undefined ) {\n\n\t\t\t\tserialize( meta.skeletons, this.skeleton );\n\n\t\t\t\tobject.skeleton = this.skeleton.uuid;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.material !== undefined ) {\n\n\t\t\tif ( Array.isArray( this.material ) ) {\n\n\t\t\t\tconst uuids = [];\n\n\t\t\t\tfor ( let i = 0, l = this.material.length; i < l; i ++ ) {\n\n\t\t\t\t\tuuids.push( serialize( meta.materials, this.material[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = uuids;\n\n\t\t\t} else {\n\n\t\t\t\tobject.material = serialize( meta.materials, this.material );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.children.length > 0 ) {\n\n\t\t\tobject.children = [];\n\n\t\t\tfor ( let i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.animations.length > 0 ) {\n\n\t\t\tobject.animations = [];\n\n\t\t\tfor ( let i = 0; i < this.animations.length; i ++ ) {\n\n\t\t\t\tconst animation = this.animations[ i ];\n\n\t\t\t\tobject.animations.push( serialize( meta.animations, animation ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( isRootObject ) {\n\n\t\t\tconst geometries = extractFromCache( meta.geometries );\n\t\t\tconst materials = extractFromCache( meta.materials );\n\t\t\tconst textures = extractFromCache( meta.textures );\n\t\t\tconst images = extractFromCache( meta.images );\n\t\t\tconst shapes = extractFromCache( meta.shapes );\n\t\t\tconst skeletons = extractFromCache( meta.skeletons );\n\t\t\tconst animations = extractFromCache( meta.animations );\n\t\t\tconst nodes = extractFromCache( meta.nodes );\n\n\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\tif ( images.length > 0 ) output.images = images;\n\t\t\tif ( shapes.length > 0 ) output.shapes = shapes;\n\t\t\tif ( skeletons.length > 0 ) output.skeletons = skeletons;\n\t\t\tif ( animations.length > 0 ) output.animations = animations;\n\t\t\tif ( nodes.length > 0 ) output.nodes = nodes;\n\n\t\t}\n\n\t\toutput.object = object;\n\n\t\treturn output;\n\n\t\t// extract data from the cache hash\n\t\t// remove metadata on each item\n\t\t// and return as array\n\t\tfunction extractFromCache( cache ) {\n\n\t\t\tconst values = [];\n\t\t\tfor ( const key in cache ) {\n\n\t\t\t\tconst data = cache[ key ];\n\t\t\t\tdelete data.metadata;\n\t\t\t\tvalues.push( data );\n\n\t\t\t}\n\n\t\t\treturn values;\n\n\t\t}\n\n\t}\n\n\tclone( recursive ) {\n\n\t\treturn new this.constructor().copy( this, recursive );\n\n\t}\n\n\tcopy( source, recursive = true ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.up.copy( source.up );\n\n\t\tthis.position.copy( source.position );\n\t\tthis.rotation.order = source.rotation.order;\n\t\tthis.quaternion.copy( source.quaternion );\n\t\tthis.scale.copy( source.scale );\n\n\t\tthis.matrix.copy( source.matrix );\n\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\tthis.layers.mask = source.layers.mask;\n\t\tthis.visible = source.visible;\n\n\t\tthis.castShadow = source.castShadow;\n\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\tthis.frustumCulled = source.frustumCulled;\n\t\tthis.renderOrder = source.renderOrder;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tfor ( let i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\tconst child = source.children[ i ];\n\t\t\t\tthis.add( child.clone() );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nObject3D.DefaultUp = new Vector3( 0, 1, 0 );\nObject3D.DefaultMatrixAutoUpdate = true;\n\nObject3D.prototype.isObject3D = true;\n\nconst _v0$1 = /*@__PURE__*/ new Vector3();\nconst _v1$3 = /*@__PURE__*/ new Vector3();\nconst _v2$2 = /*@__PURE__*/ new Vector3();\nconst _v3$1 = /*@__PURE__*/ new Vector3();\n\nconst _vab = /*@__PURE__*/ new Vector3();\nconst _vac = /*@__PURE__*/ new Vector3();\nconst _vbc = /*@__PURE__*/ new Vector3();\nconst _vap = /*@__PURE__*/ new Vector3();\nconst _vbp = /*@__PURE__*/ new Vector3();\nconst _vcp = /*@__PURE__*/ new Vector3();\n\nclass Triangle {\n\n\tconstructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t}\n\n\tstatic getNormal( a, b, c, target ) {\n\n\t\ttarget.subVectors( c, b );\n\t\t_v0$1.subVectors( a, b );\n\t\ttarget.cross( _v0$1 );\n\n\t\tconst targetLengthSq = target.lengthSq();\n\t\tif ( targetLengthSq > 0 ) {\n\n\t\t\treturn target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) );\n\n\t\t}\n\n\t\treturn target.set( 0, 0, 0 );\n\n\t}\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tstatic getBarycoord( point, a, b, c, target ) {\n\n\t\t_v0$1.subVectors( c, a );\n\t\t_v1$3.subVectors( b, a );\n\t\t_v2$2.subVectors( point, a );\n\n\t\tconst dot00 = _v0$1.dot( _v0$1 );\n\t\tconst dot01 = _v0$1.dot( _v1$3 );\n\t\tconst dot02 = _v0$1.dot( _v2$2 );\n\t\tconst dot11 = _v1$3.dot( _v1$3 );\n\t\tconst dot12 = _v1$3.dot( _v2$2 );\n\n\t\tconst denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t// collinear or singular triangle\n\t\tif ( denom === 0 ) {\n\n\t\t\t// arbitrary location outside of triangle?\n\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\treturn target.set( - 2, - 1, - 1 );\n\n\t\t}\n\n\t\tconst invDenom = 1 / denom;\n\t\tconst u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\tconst v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t// barycentric coordinates must always sum to 1\n\t\treturn target.set( 1 - u - v, v, u );\n\n\t}\n\n\tstatic containsPoint( point, a, b, c ) {\n\n\t\tthis.getBarycoord( point, a, b, c, _v3$1 );\n\n\t\treturn ( _v3$1.x >= 0 ) && ( _v3$1.y >= 0 ) && ( ( _v3$1.x + _v3$1.y ) <= 1 );\n\n\t}\n\n\tstatic getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) {\n\n\t\tthis.getBarycoord( point, p1, p2, p3, _v3$1 );\n\n\t\ttarget.set( 0, 0 );\n\t\ttarget.addScaledVector( uv1, _v3$1.x );\n\t\ttarget.addScaledVector( uv2, _v3$1.y );\n\t\ttarget.addScaledVector( uv3, _v3$1.z );\n\n\t\treturn target;\n\n\t}\n\n\tstatic isFrontFacing( a, b, c, direction ) {\n\n\t\t_v0$1.subVectors( c, b );\n\t\t_v1$3.subVectors( a, b );\n\n\t\t// strictly front facing\n\t\treturn ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false;\n\n\t}\n\n\tset( a, b, c ) {\n\n\t\tthis.a.copy( a );\n\t\tthis.b.copy( b );\n\t\tthis.c.copy( c );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPointsAndIndices( points, i0, i1, i2 ) {\n\n\t\tthis.a.copy( points[ i0 ] );\n\t\tthis.b.copy( points[ i1 ] );\n\t\tthis.c.copy( points[ i2 ] );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromAttributeAndIndices( attribute, i0, i1, i2 ) {\n\n\t\tthis.a.fromBufferAttribute( attribute, i0 );\n\t\tthis.b.fromBufferAttribute( attribute, i1 );\n\t\tthis.c.fromBufferAttribute( attribute, i2 );\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( triangle ) {\n\n\t\tthis.a.copy( triangle.a );\n\t\tthis.b.copy( triangle.b );\n\t\tthis.c.copy( triangle.c );\n\n\t\treturn this;\n\n\t}\n\n\tgetArea() {\n\n\t\t_v0$1.subVectors( this.c, this.b );\n\t\t_v1$3.subVectors( this.a, this.b );\n\n\t\treturn _v0$1.cross( _v1$3 ).length() * 0.5;\n\n\t}\n\n\tgetMidpoint( target ) {\n\n\t\treturn target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t}\n\n\tgetNormal( target ) {\n\n\t\treturn Triangle.getNormal( this.a, this.b, this.c, target );\n\n\t}\n\n\tgetPlane( target ) {\n\n\t\treturn target.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t}\n\n\tgetBarycoord( point, target ) {\n\n\t\treturn Triangle.getBarycoord( point, this.a, this.b, this.c, target );\n\n\t}\n\n\tgetUV( point, uv1, uv2, uv3, target ) {\n\n\t\treturn Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t}\n\n\tisFrontFacing( direction ) {\n\n\t\treturn Triangle.isFrontFacing( this.a, this.b, this.c, direction );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsTriangle( this );\n\n\t}\n\n\tclosestPointToPoint( p, target ) {\n\n\t\tconst a = this.a, b = this.b, c = this.c;\n\t\tlet v, w;\n\n\t\t// algorithm thanks to Real-Time Collision Detection by Christer Ericson,\n\t\t// published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,\n\t\t// under the accompanying license; see chapter 5.1.5 for detailed explanation.\n\t\t// basically, we're distinguishing which of the voronoi regions of the triangle\n\t\t// the point lies in with the minimum amount of redundant computation.\n\n\t\t_vab.subVectors( b, a );\n\t\t_vac.subVectors( c, a );\n\t\t_vap.subVectors( p, a );\n\t\tconst d1 = _vab.dot( _vap );\n\t\tconst d2 = _vac.dot( _vap );\n\t\tif ( d1 <= 0 && d2 <= 0 ) {\n\n\t\t\t// vertex region of A; barycentric coords (1, 0, 0)\n\t\t\treturn target.copy( a );\n\n\t\t}\n\n\t\t_vbp.subVectors( p, b );\n\t\tconst d3 = _vab.dot( _vbp );\n\t\tconst d4 = _vac.dot( _vbp );\n\t\tif ( d3 >= 0 && d4 <= d3 ) {\n\n\t\t\t// vertex region of B; barycentric coords (0, 1, 0)\n\t\t\treturn target.copy( b );\n\n\t\t}\n\n\t\tconst vc = d1 * d4 - d3 * d2;\n\t\tif ( vc <= 0 && d1 >= 0 && d3 <= 0 ) {\n\n\t\t\tv = d1 / ( d1 - d3 );\n\t\t\t// edge region of AB; barycentric coords (1-v, v, 0)\n\t\t\treturn target.copy( a ).addScaledVector( _vab, v );\n\n\t\t}\n\n\t\t_vcp.subVectors( p, c );\n\t\tconst d5 = _vab.dot( _vcp );\n\t\tconst d6 = _vac.dot( _vcp );\n\t\tif ( d6 >= 0 && d5 <= d6 ) {\n\n\t\t\t// vertex region of C; barycentric coords (0, 0, 1)\n\t\t\treturn target.copy( c );\n\n\t\t}\n\n\t\tconst vb = d5 * d2 - d1 * d6;\n\t\tif ( vb <= 0 && d2 >= 0 && d6 <= 0 ) {\n\n\t\t\tw = d2 / ( d2 - d6 );\n\t\t\t// edge region of AC; barycentric coords (1-w, 0, w)\n\t\t\treturn target.copy( a ).addScaledVector( _vac, w );\n\n\t\t}\n\n\t\tconst va = d3 * d6 - d5 * d4;\n\t\tif ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) {\n\n\t\t\t_vbc.subVectors( c, b );\n\t\t\tw = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );\n\t\t\t// edge region of BC; barycentric coords (0, 1-w, w)\n\t\t\treturn target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC\n\n\t\t}\n\n\t\t// face region\n\t\tconst denom = 1 / ( va + vb + vc );\n\t\t// u = va * denom\n\t\tv = vb * denom;\n\t\tw = vc * denom;\n\n\t\treturn target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w );\n\n\t}\n\n\tequals( triangle ) {\n\n\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t}\n\n}\n\nlet materialId = 0;\n\nclass Material extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.vertexColors = false;\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.stencilWriteMask = 0xff;\n\t\tthis.stencilFunc = AlwaysStencilFunc;\n\t\tthis.stencilRef = 0;\n\t\tthis.stencilFuncMask = 0xff;\n\t\tthis.stencilFail = KeepStencilOp;\n\t\tthis.stencilZFail = KeepStencilOp;\n\t\tthis.stencilZPass = KeepStencilOp;\n\t\tthis.stencilWrite = false;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.shadowSide = null;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.dithering = false;\n\n\t\tthis.alphaToCoverage = false;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.visible = true;\n\n\t\tthis.toneMapped = true;\n\n\t\tthis.userData = {};\n\n\t\tthis.version = 0;\n\n\t\tthis._alphaTest = 0;\n\n\t}\n\n\tget alphaTest() {\n\n\t\treturn this._alphaTest;\n\n\t}\n\n\tset alphaTest( value ) {\n\n\t\tif ( this._alphaTest > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._alphaTest = value;\n\n\t}\n\n\tonBuild( /* shaderobject, renderer */ ) {}\n\n\tonBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}\n\n\tonBeforeCompile( /* shaderobject, renderer */ ) {}\n\n\tcustomProgramCacheKey() {\n\n\t\treturn this.onBeforeCompile.toString();\n\n\t}\n\n\tsetValues( values ) {\n\n\t\tif ( values === undefined ) return;\n\n\t\tfor ( const key in values ) {\n\n\t\t\tconst newValue = values[ key ];\n\n\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Material: \\'' + key + '\\' parameter is undefined.' );\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// for backward compatibility if shading is set in the constructor\n\t\t\tif ( key === 'shading' ) {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );\n\t\t\t\tthis.flatShading = ( newValue === FlatShading ) ? true : false;\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tconst currentValue = this[ key ];\n\n\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': \\'' + key + '\\' is not a property of this material.' );\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t} else {\n\n\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( isRootObject ) {\n\n\t\t\tmeta = {\n\t\t\t\ttextures: {},\n\t\t\t\timages: {}\n\t\t\t};\n\n\t\t}\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Material',\n\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t}\n\t\t};\n\n\t\t// standard Material serialization\n\t\tdata.uuid = this.uuid;\n\t\tdata.type = this.type;\n\n\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\tif ( this.sheen !== undefined ) data.sheen = this.sheen;\n\t\tif ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();\n\t\tif ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;\n\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\tif ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;\n\n\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\tif ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;\n\t\tif ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();\n\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\tif ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;\n\t\tif ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;\n\n\t\tif ( this.clearcoatMap && this.clearcoatMap.isTexture ) {\n\n\t\t\tdata.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {\n\n\t\t\tdata.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {\n\n\t\t\tdata.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;\n\t\t\tdata.clearcoatNormalScale = this.clearcoatNormalScale.toArray();\n\n\t\t}\n\n\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\tif ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;\n\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\n\t\tif ( this.lightMap && this.lightMap.isTexture ) {\n\n\t\t\tdata.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tdata.lightMapIntensity = this.lightMapIntensity;\n\n\t\t}\n\n\t\tif ( this.aoMap && this.aoMap.isTexture ) {\n\n\t\t\tdata.aoMap = this.aoMap.toJSON( meta ).uuid;\n\t\t\tdata.aoMapIntensity = this.aoMapIntensity;\n\n\t\t}\n\n\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t}\n\n\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\tdata.normalMapType = this.normalMapType;\n\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t}\n\n\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t}\n\n\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\t\tif ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;\n\t\tif ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;\n\n\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.combine !== undefined ) data.combine = this.combine;\n\n\t\t}\n\n\t\tif ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;\n\t\tif ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;\n\t\tif ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;\n\n\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.transmission !== undefined ) data.transmission = this.transmission;\n\t\tif ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;\n\t\tif ( this.thickness !== undefined ) data.thickness = this.thickness;\n\t\tif ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;\n\t\tif ( this.attenuationDistance !== undefined ) data.attenuationDistance = this.attenuationDistance;\n\t\tif ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();\n\n\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\tif ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;\n\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\tif ( this.vertexColors ) data.vertexColors = true;\n\n\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\tdata.depthFunc = this.depthFunc;\n\t\tdata.depthTest = this.depthTest;\n\t\tdata.depthWrite = this.depthWrite;\n\t\tdata.colorWrite = this.colorWrite;\n\n\t\tdata.stencilWrite = this.stencilWrite;\n\t\tdata.stencilWriteMask = this.stencilWriteMask;\n\t\tdata.stencilFunc = this.stencilFunc;\n\t\tdata.stencilRef = this.stencilRef;\n\t\tdata.stencilFuncMask = this.stencilFuncMask;\n\t\tdata.stencilFail = this.stencilFail;\n\t\tdata.stencilZFail = this.stencilZFail;\n\t\tdata.stencilZPass = this.stencilZPass;\n\n\t\t// rotation (SpriteMaterial)\n\t\tif ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;\n\n\t\tif ( this.polygonOffset === true ) data.polygonOffset = true;\n\t\tif ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;\n\t\tif ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;\n\n\t\tif ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;\n\t\tif ( this.dashSize !== undefined ) data.dashSize = this.dashSize;\n\t\tif ( this.gapSize !== undefined ) data.gapSize = this.gapSize;\n\t\tif ( this.scale !== undefined ) data.scale = this.scale;\n\n\t\tif ( this.dithering === true ) data.dithering = true;\n\n\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\tif ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage;\n\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\n\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\tif ( this.flatShading === true ) data.flatShading = this.flatShading;\n\n\t\tif ( this.visible === false ) data.visible = false;\n\n\t\tif ( this.toneMapped === false ) data.toneMapped = false;\n\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;\n\n\t\t// TODO: Copied from Object3D.toJSON\n\n\t\tfunction extractFromCache( cache ) {\n\n\t\t\tconst values = [];\n\n\t\t\tfor ( const key in cache ) {\n\n\t\t\t\tconst data = cache[ key ];\n\t\t\t\tdelete data.metadata;\n\t\t\t\tvalues.push( data );\n\n\t\t\t}\n\n\t\t\treturn values;\n\n\t\t}\n\n\t\tif ( isRootObject ) {\n\n\t\t\tconst textures = extractFromCache( meta.textures );\n\t\t\tconst images = extractFromCache( meta.images );\n\n\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.fog = source.fog;\n\n\t\tthis.blending = source.blending;\n\t\tthis.side = source.side;\n\t\tthis.vertexColors = source.vertexColors;\n\n\t\tthis.opacity = source.opacity;\n\t\tthis.transparent = source.transparent;\n\n\t\tthis.blendSrc = source.blendSrc;\n\t\tthis.blendDst = source.blendDst;\n\t\tthis.blendEquation = source.blendEquation;\n\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\tthis.depthFunc = source.depthFunc;\n\t\tthis.depthTest = source.depthTest;\n\t\tthis.depthWrite = source.depthWrite;\n\n\t\tthis.stencilWriteMask = source.stencilWriteMask;\n\t\tthis.stencilFunc = source.stencilFunc;\n\t\tthis.stencilRef = source.stencilRef;\n\t\tthis.stencilFuncMask = source.stencilFuncMask;\n\t\tthis.stencilFail = source.stencilFail;\n\t\tthis.stencilZFail = source.stencilZFail;\n\t\tthis.stencilZPass = source.stencilZPass;\n\t\tthis.stencilWrite = source.stencilWrite;\n\n\t\tconst srcPlanes = source.clippingPlanes;\n\t\tlet dstPlanes = null;\n\n\t\tif ( srcPlanes !== null ) {\n\n\t\t\tconst n = srcPlanes.length;\n\t\t\tdstPlanes = new Array( n );\n\n\t\t\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.clippingPlanes = dstPlanes;\n\t\tthis.clipIntersection = source.clipIntersection;\n\t\tthis.clipShadows = source.clipShadows;\n\n\t\tthis.shadowSide = source.shadowSide;\n\n\t\tthis.colorWrite = source.colorWrite;\n\n\t\tthis.precision = source.precision;\n\n\t\tthis.polygonOffset = source.polygonOffset;\n\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\tthis.dithering = source.dithering;\n\n\t\tthis.alphaTest = source.alphaTest;\n\t\tthis.alphaToCoverage = source.alphaToCoverage;\n\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\tthis.visible = source.visible;\n\n\t\tthis.toneMapped = source.toneMapped;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n}\n\nMaterial.prototype.isMaterial = true;\n\nMaterial.fromType = function ( /*type*/ ) {\n\n\t// TODO: Behavior added in Materials.js\n\n\treturn null;\n\n};\n\nclass MeshBasicMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\treturn this;\n\n\t}\n\n}\n\nMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\nconst _vector$9 = /*@__PURE__*/ new Vector3();\nconst _vector2$1 = /*@__PURE__*/ new Vector2();\n\nclass BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.name = '';\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.usage = StaticDrawUsage;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tonUploadCallback() {}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\tsetUsage( value ) {\n\n\t\tthis.usage = value;\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\t\tthis.array = new source.array.constructor( source.array );\n\t\tthis.itemSize = source.itemSize;\n\t\tthis.count = source.count;\n\t\tthis.normalized = source.normalized;\n\n\t\tthis.usage = source.usage;\n\n\t\treturn this;\n\n\t}\n\n\tcopyAt( index1, attribute, index2 ) {\n\n\t\tindex1 *= this.itemSize;\n\t\tindex2 *= attribute.itemSize;\n\n\t\tfor ( let i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyArray( array ) {\n\n\t\tthis.array.set( array );\n\n\t\treturn this;\n\n\t}\n\n\tcopyColorsArray( colors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\tlet color = colors[ i ];\n\n\t\t\tif ( color === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\tcolor = new Color();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = color.r;\n\t\t\tarray[ offset ++ ] = color.g;\n\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector2sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector2();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector3sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector3();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector4sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector4();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tif ( this.itemSize === 2 ) {\n\n\t\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t\t_vector2$1.fromBufferAttribute( this, i );\n\t\t\t\t_vector2$1.applyMatrix3( m );\n\n\t\t\t\tthis.setXY( i, _vector2$1.x, _vector2$1.y );\n\n\t\t\t}\n\n\t\t} else if ( this.itemSize === 3 ) {\n\n\t\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t\t_vector$9.fromBufferAttribute( this, i );\n\t\t\t\t_vector$9.applyMatrix3( m );\n\n\t\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.applyMatrix4( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyNormalMatrix( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.applyNormalMatrix( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttransformDirection( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.transformDirection( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tset( value, offset = 0 ) {\n\n\t\tthis.array.set( value, offset );\n\n\t\treturn this;\n\n\t}\n\n\tgetX( index ) {\n\n\t\treturn this.array[ index * this.itemSize ];\n\n\t}\n\n\tsetX( index, x ) {\n\n\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\treturn this;\n\n\t}\n\n\tgetY( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t}\n\n\tsetY( index, y ) {\n\n\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tgetZ( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t}\n\n\tsetZ( index, z ) {\n\n\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tgetW( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t}\n\n\tsetW( index, w ) {\n\n\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetXY( index, x, y ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZ( index, x, y, z ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\t\tthis.array[ index + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZW( index, x, y, z, w ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\t\tthis.array[ index + 2 ] = z;\n\t\tthis.array[ index + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tonUpload( callback ) {\n\n\t\tthis.onUploadCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\titemSize: this.itemSize,\n\t\t\ttype: this.array.constructor.name,\n\t\t\tarray: Array.prototype.slice.call( this.array ),\n\t\t\tnormalized: this.normalized\n\t\t};\n\n\t\tif ( this.name !== '' ) data.name = this.name;\n\t\tif ( this.usage !== StaticDrawUsage ) data.usage = this.usage;\n\t\tif ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange;\n\n\t\treturn data;\n\n\t}\n\n}\n\nBufferAttribute.prototype.isBufferAttribute = true;\n\n//\n\nclass Int8BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int8Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint8BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint8Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint8ClampedBufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint8ClampedArray( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Int16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int16Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint16Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Int32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Float16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint16Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nFloat16BufferAttribute.prototype.isFloat16BufferAttribute = true;\n\nclass Float32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Float32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Float64BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Float64Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nlet _id$1 = 0;\n\nconst _m1 = /*@__PURE__*/ new Matrix4();\nconst _obj = /*@__PURE__*/ new Object3D();\nconst _offset = /*@__PURE__*/ new Vector3();\nconst _box$1 = /*@__PURE__*/ new Box3();\nconst _boxMorphTargets = /*@__PURE__*/ new Box3();\nconst _vector$8 = /*@__PURE__*/ new Vector3();\n\nclass BufferGeometry extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tObject.defineProperty( this, 'id', { value: _id$1 ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\t\tthis.morphTargetsRelative = false;\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t\tthis.userData = {};\n\n\t}\n\n\tgetIndex() {\n\n\t\treturn this.index;\n\n\t}\n\n\tsetIndex( index ) {\n\n\t\tif ( Array.isArray( index ) ) {\n\n\t\t\tthis.index = new ( arrayNeedsUint32( index ) ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t} else {\n\n\t\t\tthis.index = index;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetAttribute( name ) {\n\n\t\treturn this.attributes[ name ];\n\n\t}\n\n\tsetAttribute( name, attribute ) {\n\n\t\tthis.attributes[ name ] = attribute;\n\n\t\treturn this;\n\n\t}\n\n\tdeleteAttribute( name ) {\n\n\t\tdelete this.attributes[ name ];\n\n\t\treturn this;\n\n\t}\n\n\thasAttribute( name ) {\n\n\t\treturn this.attributes[ name ] !== undefined;\n\n\t}\n\n\taddGroup( start, count, materialIndex = 0 ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t}\n\n\tclearGroups() {\n\n\t\tthis.groups = [];\n\n\t}\n\n\tsetDrawRange( start, count ) {\n\n\t\tthis.drawRange.start = start;\n\t\tthis.drawRange.count = count;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tconst position = this.attributes.position;\n\n\t\tif ( position !== undefined ) {\n\n\t\t\tposition.applyMatrix4( matrix );\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t}\n\n\t\tconst normal = this.attributes.normal;\n\n\t\tif ( normal !== undefined ) {\n\n\t\t\tconst normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tnormal.applyNormalMatrix( normalMatrix );\n\n\t\t\tnormal.needsUpdate = true;\n\n\t\t}\n\n\t\tconst tangent = this.attributes.tangent;\n\n\t\tif ( tangent !== undefined ) {\n\n\t\t\ttangent.transformDirection( matrix );\n\n\t\t\ttangent.needsUpdate = true;\n\n\t\t}\n\n\t\tif ( this.boundingBox !== null ) {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t}\n\n\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\t_m1.makeRotationFromQuaternion( q );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateX( angle ) {\n\n\t\t// rotate geometry around world x-axis\n\n\t\t_m1.makeRotationX( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateY( angle ) {\n\n\t\t// rotate geometry around world y-axis\n\n\t\t_m1.makeRotationY( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateZ( angle ) {\n\n\t\t// rotate geometry around world z-axis\n\n\t\t_m1.makeRotationZ( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( x, y, z ) {\n\n\t\t// translate geometry\n\n\t\t_m1.makeTranslation( x, y, z );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\tscale( x, y, z ) {\n\n\t\t// scale geometry\n\n\t\t_m1.makeScale( x, y, z );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\tlookAt( vector ) {\n\n\t\t_obj.lookAt( vector );\n\n\t\t_obj.updateMatrix();\n\n\t\tthis.applyMatrix4( _obj.matrix );\n\n\t\treturn this;\n\n\t}\n\n\tcenter() {\n\n\t\tthis.computeBoundingBox();\n\n\t\tthis.boundingBox.getCenter( _offset ).negate();\n\n\t\tthis.translate( _offset.x, _offset.y, _offset.z );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tconst position = [];\n\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst point = points[ i ];\n\t\t\tposition.push( point.x, point.y, point.z || 0 );\n\n\t\t}\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );\n\n\t\treturn this;\n\n\t}\n\n\tcomputeBoundingBox() {\n\n\t\tif ( this.boundingBox === null ) {\n\n\t\t\tthis.boundingBox = new Box3();\n\n\t\t}\n\n\t\tconst position = this.attributes.position;\n\t\tconst morphAttributesPosition = this.morphAttributes.position;\n\n\t\tif ( position && position.isGLBufferAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set \"mesh.frustumCulled\" to \"false\".', this );\n\n\t\t\tthis.boundingBox.set(\n\t\t\t\tnew Vector3( - Infinity, - Infinity, - Infinity ),\n\t\t\t\tnew Vector3( + Infinity, + Infinity, + Infinity )\n\t\t\t);\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( position !== undefined ) {\n\n\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\t_box$1.setFromBufferAttribute( morphAttribute );\n\n\t\t\t\t\tif ( this.morphTargetsRelative ) {\n\n\t\t\t\t\t\t_vector$8.addVectors( this.boundingBox.min, _box$1.min );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _vector$8 );\n\n\t\t\t\t\t\t_vector$8.addVectors( this.boundingBox.max, _box$1.max );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _vector$8 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _box$1.min );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _box$1.max );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t}\n\n\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t}\n\n\t}\n\n\tcomputeBoundingSphere() {\n\n\t\tif ( this.boundingSphere === null ) {\n\n\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t}\n\n\t\tconst position = this.attributes.position;\n\t\tconst morphAttributesPosition = this.morphAttributes.position;\n\n\t\tif ( position && position.isGLBufferAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set \"mesh.frustumCulled\" to \"false\".', this );\n\n\t\t\tthis.boundingSphere.set( new Vector3(), Infinity );\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( position ) {\n\n\t\t\t// first, find the center of the bounding sphere\n\n\t\t\tconst center = this.boundingSphere.center;\n\n\t\t\t_box$1.setFromBufferAttribute( position );\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\t_boxMorphTargets.setFromBufferAttribute( morphAttribute );\n\n\t\t\t\t\tif ( this.morphTargetsRelative ) {\n\n\t\t\t\t\t\t_vector$8.addVectors( _box$1.min, _boxMorphTargets.min );\n\t\t\t\t\t\t_box$1.expandByPoint( _vector$8 );\n\n\t\t\t\t\t\t_vector$8.addVectors( _box$1.max, _boxMorphTargets.max );\n\t\t\t\t\t\t_box$1.expandByPoint( _vector$8 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_box$1.expandByPoint( _boxMorphTargets.min );\n\t\t\t\t\t\t_box$1.expandByPoint( _boxMorphTargets.max );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_box$1.getCenter( center );\n\n\t\t\t// second, try to find a boundingSphere with a radius smaller than the\n\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\tlet maxRadiusSq = 0;\n\n\t\t\tfor ( let i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t_vector$8.fromBufferAttribute( position, i );\n\n\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );\n\n\t\t\t}\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\tconst morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t\t\t\tfor ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) {\n\n\t\t\t\t\t\t_vector$8.fromBufferAttribute( morphAttribute, j );\n\n\t\t\t\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t\t\t\t_offset.fromBufferAttribute( position, j );\n\t\t\t\t\t\t\t_vector$8.add( _offset );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tcomputeTangents() {\n\n\t\tconst index = this.index;\n\t\tconst attributes = this.attributes;\n\n\t\t// based on http://www.terathon.com/code/tangent.html\n\t\t// (per vertex tangents)\n\n\t\tif ( index === null ||\n\t\t\t attributes.position === undefined ||\n\t\t\t attributes.normal === undefined ||\n\t\t\t attributes.uv === undefined ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst indices = index.array;\n\t\tconst positions = attributes.position.array;\n\t\tconst normals = attributes.normal.array;\n\t\tconst uvs = attributes.uv.array;\n\n\t\tconst nVertices = positions.length / 3;\n\n\t\tif ( this.hasAttribute( 'tangent' ) === false ) {\n\n\t\t\tthis.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );\n\n\t\t}\n\n\t\tconst tangents = this.getAttribute( 'tangent' ).array;\n\n\t\tconst tan1 = [], tan2 = [];\n\n\t\tfor ( let i = 0; i < nVertices; i ++ ) {\n\n\t\t\ttan1[ i ] = new Vector3();\n\t\t\ttan2[ i ] = new Vector3();\n\n\t\t}\n\n\t\tconst vA = new Vector3(),\n\t\t\tvB = new Vector3(),\n\t\t\tvC = new Vector3(),\n\n\t\t\tuvA = new Vector2(),\n\t\t\tuvB = new Vector2(),\n\t\t\tuvC = new Vector2(),\n\n\t\t\tsdir = new Vector3(),\n\t\t\ttdir = new Vector3();\n\n\t\tfunction handleTriangle( a, b, c ) {\n\n\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\tvB.sub( vA );\n\t\t\tvC.sub( vA );\n\n\t\t\tuvB.sub( uvA );\n\t\t\tuvC.sub( uvA );\n\n\t\t\tconst r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y );\n\n\t\t\t// silently ignore degenerate uv triangles having coincident or colinear vertices\n\n\t\t\tif ( ! isFinite( r ) ) return;\n\n\t\t\tsdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r );\n\t\t\ttdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r );\n\n\t\t\ttan1[ a ].add( sdir );\n\t\t\ttan1[ b ].add( sdir );\n\t\t\ttan1[ c ].add( sdir );\n\n\t\t\ttan2[ a ].add( tdir );\n\t\t\ttan2[ b ].add( tdir );\n\t\t\ttan2[ c ].add( tdir );\n\n\t\t}\n\n\t\tlet groups = this.groups;\n\n\t\tif ( groups.length === 0 ) {\n\n\t\t\tgroups = [ {\n\t\t\t\tstart: 0,\n\t\t\t\tcount: indices.length\n\t\t\t} ];\n\n\t\t}\n\n\t\tfor ( let i = 0, il = groups.length; i < il; ++ i ) {\n\n\t\t\tconst group = groups[ i ];\n\n\t\t\tconst start = group.start;\n\t\t\tconst count = group.count;\n\n\t\t\tfor ( let j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\thandleTriangle(\n\t\t\t\t\tindices[ j + 0 ],\n\t\t\t\t\tindices[ j + 1 ],\n\t\t\t\t\tindices[ j + 2 ]\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst tmp = new Vector3(), tmp2 = new Vector3();\n\t\tconst n = new Vector3(), n2 = new Vector3();\n\n\t\tfunction handleVertex( v ) {\n\n\t\t\tn.fromArray( normals, v * 3 );\n\t\t\tn2.copy( n );\n\n\t\t\tconst t = tan1[ v ];\n\n\t\t\t// Gram-Schmidt orthogonalize\n\n\t\t\ttmp.copy( t );\n\t\t\ttmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();\n\n\t\t\t// Calculate handedness\n\n\t\t\ttmp2.crossVectors( n2, t );\n\t\t\tconst test = tmp2.dot( tan2[ v ] );\n\t\t\tconst w = ( test < 0.0 ) ? - 1.0 : 1.0;\n\n\t\t\ttangents[ v * 4 ] = tmp.x;\n\t\t\ttangents[ v * 4 + 1 ] = tmp.y;\n\t\t\ttangents[ v * 4 + 2 ] = tmp.z;\n\t\t\ttangents[ v * 4 + 3 ] = w;\n\n\t\t}\n\n\t\tfor ( let i = 0, il = groups.length; i < il; ++ i ) {\n\n\t\t\tconst group = groups[ i ];\n\n\t\t\tconst start = group.start;\n\t\t\tconst count = group.count;\n\n\t\t\tfor ( let j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\thandleVertex( indices[ j + 0 ] );\n\t\t\t\thandleVertex( indices[ j + 1 ] );\n\t\t\t\thandleVertex( indices[ j + 2 ] );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tcomputeVertexNormals() {\n\n\t\tconst index = this.index;\n\t\tconst positionAttribute = this.getAttribute( 'position' );\n\n\t\tif ( positionAttribute !== undefined ) {\n\n\t\t\tlet normalAttribute = this.getAttribute( 'normal' );\n\n\t\t\tif ( normalAttribute === undefined ) {\n\n\t\t\t\tnormalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );\n\t\t\t\tthis.setAttribute( 'normal', normalAttribute );\n\n\t\t\t} else {\n\n\t\t\t\t// reset existing normals to zero\n\n\t\t\t\tfor ( let i = 0, il = normalAttribute.count; i < il; i ++ ) {\n\n\t\t\t\t\tnormalAttribute.setXYZ( i, 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\tconst nA = new Vector3(), nB = new Vector3(), nC = new Vector3();\n\t\t\tconst cb = new Vector3(), ab = new Vector3();\n\n\t\t\t// indexed elements\n\n\t\t\tif ( index ) {\n\n\t\t\t\tfor ( let i = 0, il = index.count; i < il; i += 3 ) {\n\n\t\t\t\t\tconst vA = index.getX( i + 0 );\n\t\t\t\t\tconst vB = index.getX( i + 1 );\n\t\t\t\t\tconst vC = index.getX( i + 2 );\n\n\t\t\t\t\tpA.fromBufferAttribute( positionAttribute, vA );\n\t\t\t\t\tpB.fromBufferAttribute( positionAttribute, vB );\n\t\t\t\t\tpC.fromBufferAttribute( positionAttribute, vC );\n\n\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tnA.fromBufferAttribute( normalAttribute, vA );\n\t\t\t\t\tnB.fromBufferAttribute( normalAttribute, vB );\n\t\t\t\t\tnC.fromBufferAttribute( normalAttribute, vC );\n\n\t\t\t\t\tnA.add( cb );\n\t\t\t\t\tnB.add( cb );\n\t\t\t\t\tnC.add( cb );\n\n\t\t\t\t\tnormalAttribute.setXYZ( vA, nA.x, nA.y, nA.z );\n\t\t\t\t\tnormalAttribute.setXYZ( vB, nB.x, nB.y, nB.z );\n\t\t\t\t\tnormalAttribute.setXYZ( vC, nC.x, nC.y, nC.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\tfor ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) {\n\n\t\t\t\t\tpA.fromBufferAttribute( positionAttribute, i + 0 );\n\t\t\t\t\tpB.fromBufferAttribute( positionAttribute, i + 1 );\n\t\t\t\t\tpC.fromBufferAttribute( positionAttribute, i + 2 );\n\n\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tnormalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z );\n\t\t\t\t\tnormalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z );\n\t\t\t\t\tnormalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.normalizeNormals();\n\n\t\t\tnormalAttribute.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n\tmerge( geometry, offset ) {\n\n\t\tif ( ! ( geometry && geometry.isBufferGeometry ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( offset === undefined ) {\n\n\t\t\toffset = 0;\n\n\t\t\tconsole.warn(\n\t\t\t\t'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. '\n\t\t\t\t+ 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'\n\t\t\t);\n\n\t\t}\n\n\t\tconst attributes = this.attributes;\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\tconst attribute1 = attributes[ key ];\n\t\t\tconst attributeArray1 = attribute1.array;\n\n\t\t\tconst attribute2 = geometry.attributes[ key ];\n\t\t\tconst attributeArray2 = attribute2.array;\n\n\t\t\tconst attributeOffset = attribute2.itemSize * offset;\n\t\t\tconst length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset );\n\n\t\t\tfor ( let i = 0, j = attributeOffset; i < length; i ++, j ++ ) {\n\n\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tnormalizeNormals() {\n\n\t\tconst normals = this.attributes.normal;\n\n\t\tfor ( let i = 0, il = normals.count; i < il; i ++ ) {\n\n\t\t\t_vector$8.fromBufferAttribute( normals, i );\n\n\t\t\t_vector$8.normalize();\n\n\t\t\tnormals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );\n\n\t\t}\n\n\t}\n\n\ttoNonIndexed() {\n\n\t\tfunction convertBufferAttribute( attribute, indices ) {\n\n\t\t\tconst array = attribute.array;\n\t\t\tconst itemSize = attribute.itemSize;\n\t\t\tconst normalized = attribute.normalized;\n\n\t\t\tconst array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\tlet index = 0, index2 = 0;\n\n\t\t\tfor ( let i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\tindex = indices[ i ] * attribute.data.stride + attribute.offset;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new BufferAttribute( array2, itemSize, normalized );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.index === null ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst geometry2 = new BufferGeometry();\n\n\t\tconst indices = this.index.array;\n\t\tconst attributes = this.attributes;\n\n\t\t// attributes\n\n\t\tfor ( const name in attributes ) {\n\n\t\t\tconst attribute = attributes[ name ];\n\n\t\t\tconst newAttribute = convertBufferAttribute( attribute, indices );\n\n\t\t\tgeometry2.setAttribute( name, newAttribute );\n\n\t\t}\n\n\t\t// morph attributes\n\n\t\tconst morphAttributes = this.morphAttributes;\n\n\t\tfor ( const name in morphAttributes ) {\n\n\t\t\tconst morphArray = [];\n\t\t\tconst morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\tfor ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {\n\n\t\t\t\tconst attribute = morphAttribute[ i ];\n\n\t\t\t\tconst newAttribute = convertBufferAttribute( attribute, indices );\n\n\t\t\t\tmorphArray.push( newAttribute );\n\n\t\t\t}\n\n\t\t\tgeometry2.morphAttributes[ name ] = morphArray;\n\n\t\t}\n\n\t\tgeometry2.morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t// groups\n\n\t\tconst groups = this.groups;\n\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst group = groups[ i ];\n\t\t\tgeometry2.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn geometry2;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t}\n\t\t};\n\n\t\t// standard BufferGeometry serialization\n\n\t\tdata.uuid = this.uuid;\n\t\tdata.type = this.type;\n\t\tif ( this.name !== '' ) data.name = this.name;\n\t\tif ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;\n\n\t\tif ( this.parameters !== undefined ) {\n\n\t\t\tconst parameters = this.parameters;\n\n\t\t\tfor ( const key in parameters ) {\n\n\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t\t// for simplicity the code assumes attributes are not shared across geometries, see #15811\n\n\t\tdata.data = { attributes: {} };\n\n\t\tconst index = this.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tdata.data.index = {\n\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\tarray: Array.prototype.slice.call( index.array )\n\t\t\t};\n\n\t\t}\n\n\t\tconst attributes = this.attributes;\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tconst attribute = attributes[ key ];\n\n\t\t\tdata.data.attributes[ key ] = attribute.toJSON( data.data );\n\n\t\t}\n\n\t\tconst morphAttributes = {};\n\t\tlet hasMorphAttributes = false;\n\n\t\tfor ( const key in this.morphAttributes ) {\n\n\t\t\tconst attributeArray = this.morphAttributes[ key ];\n\n\t\t\tconst array = [];\n\n\t\t\tfor ( let i = 0, il = attributeArray.length; i < il; i ++ ) {\n\n\t\t\t\tconst attribute = attributeArray[ i ];\n\n\t\t\t\tarray.push( attribute.toJSON( data.data ) );\n\n\t\t\t}\n\n\t\t\tif ( array.length > 0 ) {\n\n\t\t\t\tmorphAttributes[ key ] = array;\n\n\t\t\t\thasMorphAttributes = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( hasMorphAttributes ) {\n\n\t\t\tdata.data.morphAttributes = morphAttributes;\n\t\t\tdata.data.morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t}\n\n\t\tconst groups = this.groups;\n\n\t\tif ( groups.length > 0 ) {\n\n\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t}\n\n\t\tconst boundingSphere = this.boundingSphere;\n\n\t\tif ( boundingSphere !== null ) {\n\n\t\t\tdata.data.boundingSphere = {\n\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\tradius: boundingSphere.radius\n\t\t\t};\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tclone() {\n\n\t\t return new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\t// reset\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\t\tthis.morphAttributes = {};\n\t\tthis.groups = [];\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// used for storing cloned, shared data\n\n\t\tconst data = {};\n\n\t\t// name\n\n\t\tthis.name = source.name;\n\n\t\t// index\n\n\t\tconst index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone( data ) );\n\n\t\t}\n\n\t\t// attributes\n\n\t\tconst attributes = source.attributes;\n\n\t\tfor ( const name in attributes ) {\n\n\t\t\tconst attribute = attributes[ name ];\n\t\t\tthis.setAttribute( name, attribute.clone( data ) );\n\n\t\t}\n\n\t\t// morph attributes\n\n\t\tconst morphAttributes = source.morphAttributes;\n\n\t\tfor ( const name in morphAttributes ) {\n\n\t\t\tconst array = [];\n\t\t\tconst morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\tfor ( let i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\tarray.push( morphAttribute[ i ].clone( data ) );\n\n\t\t\t}\n\n\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t}\n\n\t\tthis.morphTargetsRelative = source.morphTargetsRelative;\n\n\t\t// groups\n\n\t\tconst groups = source.groups;\n\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\t// bounding box\n\n\t\tconst boundingBox = source.boundingBox;\n\n\t\tif ( boundingBox !== null ) {\n\n\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t}\n\n\t\t// bounding sphere\n\n\t\tconst boundingSphere = source.boundingSphere;\n\n\t\tif ( boundingSphere !== null ) {\n\n\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t}\n\n\t\t// draw range\n\n\t\tthis.drawRange.start = source.drawRange.start;\n\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t// user data\n\n\t\tthis.userData = source.userData;\n\n\t\t// geometry generator parameters\n\n\t\tif ( source.parameters !== undefined ) this.parameters = Object.assign( {}, source.parameters );\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n}\n\nBufferGeometry.prototype.isBufferGeometry = true;\n\nconst _inverseMatrix$2 = /*@__PURE__*/ new Matrix4();\nconst _ray$2 = /*@__PURE__*/ new Ray();\nconst _sphere$3 = /*@__PURE__*/ new Sphere();\n\nconst _vA$1 = /*@__PURE__*/ new Vector3();\nconst _vB$1 = /*@__PURE__*/ new Vector3();\nconst _vC$1 = /*@__PURE__*/ new Vector3();\n\nconst _tempA = /*@__PURE__*/ new Vector3();\nconst _tempB = /*@__PURE__*/ new Vector3();\nconst _tempC = /*@__PURE__*/ new Vector3();\n\nconst _morphA = /*@__PURE__*/ new Vector3();\nconst _morphB = /*@__PURE__*/ new Vector3();\nconst _morphC = /*@__PURE__*/ new Vector3();\n\nconst _uvA$1 = /*@__PURE__*/ new Vector2();\nconst _uvB$1 = /*@__PURE__*/ new Vector2();\nconst _uvC$1 = /*@__PURE__*/ new Vector2();\n\nconst _intersectionPoint = /*@__PURE__*/ new Vector3();\nconst _intersectionPointWorld = /*@__PURE__*/ new Vector3();\n\nclass Mesh extends Object3D {\n\n\tconstructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry;\n\t\tthis.material = material;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tif ( source.morphTargetInfluences !== undefined ) {\n\n\t\t\tthis.morphTargetInfluences = source.morphTargetInfluences.slice();\n\n\t\t}\n\n\t\tif ( source.morphTargetDictionary !== undefined ) {\n\n\t\t\tthis.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );\n\n\t\t}\n\n\t\tthis.material = source.material;\n\t\tthis.geometry = source.geometry;\n\n\t\treturn this;\n\n\t}\n\n\tupdateMorphTargets() {\n\n\t\tconst geometry = this.geometry;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tconst morphAttributes = geometry.morphAttributes;\n\t\t\tconst keys = Object.keys( morphAttributes );\n\n\t\t\tif ( keys.length > 0 ) {\n\n\t\t\t\tconst morphAttribute = morphAttributes[ keys[ 0 ] ];\n\n\t\t\t\tif ( morphAttribute !== undefined ) {\n\n\t\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\t\tfor ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {\n\n\t\t\t\t\t\tconst name = morphAttribute[ m ].name || String( m );\n\n\t\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\t\tthis.morphTargetDictionary[ name ] = m;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst morphTargets = geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst material = this.material;\n\t\tconst matrixWorld = this.matrixWorld;\n\n\t\tif ( material === undefined ) return;\n\n\t\t// Checking boundingSphere distance to ray\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere$3.copy( geometry.boundingSphere );\n\t\t_sphere$3.applyMatrix4( matrixWorld );\n\n\t\tif ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;\n\n\t\t//\n\n\t\t_inverseMatrix$2.copy( matrixWorld ).invert();\n\t\t_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );\n\n\t\t// Check boundingBox before continuing\n\n\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\tif ( _ray$2.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t}\n\n\t\tlet intersection;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tconst index = geometry.index;\n\t\t\tconst position = geometry.attributes.position;\n\t\t\tconst morphPosition = geometry.morphAttributes.position;\n\t\t\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\t\t\tconst uv = geometry.attributes.uv;\n\t\t\tconst uv2 = geometry.attributes.uv2;\n\t\t\tconst groups = geometry.groups;\n\t\t\tconst drawRange = geometry.drawRange;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\t// indexed buffer geometry\n\n\t\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\t\tfor ( let i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tconst group = groups[ i ];\n\t\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\t\tconst start = Math.max( group.start, drawRange.start );\n\t\t\t\t\t\tconst end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) );\n\n\t\t\t\t\t\tfor ( let j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\tconst a = index.getX( j );\n\t\t\t\t\t\t\tconst b = index.getX( j + 1 );\n\t\t\t\t\t\t\tconst c = index.getX( j + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics\n\t\t\t\t\t\t\t\tintersection.face.materialIndex = group.materialIndex;\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\t\t\tconst end = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\t\t\tfor ( let i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\t\t\tconst a = index.getX( i );\n\t\t\t\t\t\tconst b = index.getX( i + 1 );\n\t\t\t\t\t\tconst c = index.getX( i + 2 );\n\n\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\t\tfor ( let i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tconst group = groups[ i ];\n\t\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\t\tconst start = Math.max( group.start, drawRange.start );\n\t\t\t\t\t\tconst end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) );\n\n\t\t\t\t\t\tfor ( let j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\tconst a = j;\n\t\t\t\t\t\t\tconst b = j + 1;\n\t\t\t\t\t\t\tconst c = j + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics\n\t\t\t\t\t\t\t\tintersection.face.materialIndex = group.materialIndex;\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\t\t\tconst end = Math.min( position.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\t\t\tfor ( let i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\t\t\tconst a = i;\n\t\t\t\t\t\tconst b = i + 1;\n\t\t\t\t\t\tconst c = i + 2;\n\n\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\tconsole.error( 'THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );\n\n\t\t}\n\n\t}\n\n}\n\nMesh.prototype.isMesh = true;\n\nfunction checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {\n\n\tlet intersect;\n\n\tif ( material.side === BackSide ) {\n\n\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t} else {\n\n\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t}\n\n\tif ( intersect === null ) return null;\n\n\t_intersectionPointWorld.copy( point );\n\t_intersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\tconst distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );\n\n\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\treturn {\n\t\tdistance: distance,\n\t\tpoint: _intersectionPointWorld.clone(),\n\t\tobject: object\n\t};\n\n}\n\nfunction checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {\n\n\t_vA$1.fromBufferAttribute( position, a );\n\t_vB$1.fromBufferAttribute( position, b );\n\t_vC$1.fromBufferAttribute( position, c );\n\n\tconst morphInfluences = object.morphTargetInfluences;\n\n\tif ( morphPosition && morphInfluences ) {\n\n\t\t_morphA.set( 0, 0, 0 );\n\t\t_morphB.set( 0, 0, 0 );\n\t\t_morphC.set( 0, 0, 0 );\n\n\t\tfor ( let i = 0, il = morphPosition.length; i < il; i ++ ) {\n\n\t\t\tconst influence = morphInfluences[ i ];\n\t\t\tconst morphAttribute = morphPosition[ i ];\n\n\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t_tempA.fromBufferAttribute( morphAttribute, a );\n\t\t\t_tempB.fromBufferAttribute( morphAttribute, b );\n\t\t\t_tempC.fromBufferAttribute( morphAttribute, c );\n\n\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t_morphA.addScaledVector( _tempA, influence );\n\t\t\t\t_morphB.addScaledVector( _tempB, influence );\n\t\t\t\t_morphC.addScaledVector( _tempC, influence );\n\n\t\t\t} else {\n\n\t\t\t\t_morphA.addScaledVector( _tempA.sub( _vA$1 ), influence );\n\t\t\t\t_morphB.addScaledVector( _tempB.sub( _vB$1 ), influence );\n\t\t\t\t_morphC.addScaledVector( _tempC.sub( _vC$1 ), influence );\n\n\t\t\t}\n\n\t\t}\n\n\t\t_vA$1.add( _morphA );\n\t\t_vB$1.add( _morphB );\n\t\t_vC$1.add( _morphC );\n\n\t}\n\n\tif ( object.isSkinnedMesh ) {\n\n\t\tobject.boneTransform( a, _vA$1 );\n\t\tobject.boneTransform( b, _vB$1 );\n\t\tobject.boneTransform( c, _vC$1 );\n\n\t}\n\n\tconst intersection = checkIntersection( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint );\n\n\tif ( intersection ) {\n\n\t\tif ( uv ) {\n\n\t\t\t_uvA$1.fromBufferAttribute( uv, a );\n\t\t\t_uvB$1.fromBufferAttribute( uv, b );\n\t\t\t_uvC$1.fromBufferAttribute( uv, c );\n\n\t\t\tintersection.uv = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() );\n\n\t\t}\n\n\t\tif ( uv2 ) {\n\n\t\t\t_uvA$1.fromBufferAttribute( uv2, a );\n\t\t\t_uvB$1.fromBufferAttribute( uv2, b );\n\t\t\t_uvC$1.fromBufferAttribute( uv2, c );\n\n\t\t\tintersection.uv2 = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() );\n\n\t\t}\n\n\t\tconst face = {\n\t\t\ta: a,\n\t\t\tb: b,\n\t\t\tc: c,\n\t\t\tnormal: new Vector3(),\n\t\t\tmaterialIndex: 0\n\t\t};\n\n\t\tTriangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal );\n\n\t\tintersection.face = face;\n\n\t}\n\n\treturn intersection;\n\n}\n\nclass BoxGeometry extends BufferGeometry {\n\n\tconstructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tconst scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments );\n\t\theightSegments = Math.floor( heightSegments );\n\t\tdepthSegments = Math.floor( depthSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tlet numberOfVertices = 0;\n\t\tlet groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tconst segmentWidth = width / gridX;\n\t\t\tconst segmentHeight = height / gridY;\n\n\t\t\tconst widthHalf = width / 2;\n\t\t\tconst heightHalf = height / 2;\n\t\t\tconst depthHalf = depth / 2;\n\n\t\t\tconst gridX1 = gridX + 1;\n\t\t\tconst gridY1 = gridY + 1;\n\n\t\t\tlet vertexCounter = 0;\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( let iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tconst y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( let ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tconst x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( let iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( let ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tconst a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tconst b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tconst c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tconst d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments );\n\n\t}\n\n}\n\n/**\n * Uniform Utilities\n */\n\nfunction cloneUniforms( src ) {\n\n\tconst dst = {};\n\n\tfor ( const u in src ) {\n\n\t\tdst[ u ] = {};\n\n\t\tfor ( const p in src[ u ] ) {\n\n\t\t\tconst property = src[ u ][ p ];\n\n\t\t\tif ( property && ( property.isColor ||\n\t\t\t\tproperty.isMatrix3 || property.isMatrix4 ||\n\t\t\t\tproperty.isVector2 || property.isVector3 || property.isVector4 ||\n\t\t\t\tproperty.isTexture || property.isQuaternion ) ) {\n\n\t\t\t\tdst[ u ][ p ] = property.clone();\n\n\t\t\t} else if ( Array.isArray( property ) ) {\n\n\t\t\t\tdst[ u ][ p ] = property.slice();\n\n\t\t\t} else {\n\n\t\t\t\tdst[ u ][ p ] = property;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn dst;\n\n}\n\nfunction mergeUniforms( uniforms ) {\n\n\tconst merged = {};\n\n\tfor ( let u = 0; u < uniforms.length; u ++ ) {\n\n\t\tconst tmp = cloneUniforms( uniforms[ u ] );\n\n\t\tfor ( const p in tmp ) {\n\n\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t}\n\n\t}\n\n\treturn merged;\n\n}\n\n// Legacy\n\nconst UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms };\n\nvar default_vertex = \"void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}\";\n\nvar default_fragment = \"void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}\";\n\nclass ShaderMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = default_vertex;\n\t\tthis.fragmentShader = default_fragment;\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\t\tthis.uniformsNeedUpdate = false;\n\n\t\tthis.glslVersion = null;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = cloneUniforms( source.uniforms );\n\n\t\tthis.defines = Object.assign( {}, source.defines );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.extensions = Object.assign( {}, source.extensions );\n\n\t\tthis.glslVersion = source.glslVersion;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.glslVersion = this.glslVersion;\n\t\tdata.uniforms = {};\n\n\t\tfor ( const name in this.uniforms ) {\n\n\t\t\tconst uniform = this.uniforms[ name ];\n\t\t\tconst value = uniform.value;\n\n\t\t\tif ( value && value.isTexture ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 't',\n\t\t\t\t\tvalue: value.toJSON( meta ).uuid\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isColor ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'c',\n\t\t\t\t\tvalue: value.getHex()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector2 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v2',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector3 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v3',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector4 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v4',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isMatrix3 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'm3',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isMatrix4 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'm4',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\tvalue: value\n\t\t\t\t};\n\n\t\t\t\t// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;\n\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\tconst extensions = {};\n\n\t\tfor ( const key in this.extensions ) {\n\n\t\t\tif ( this.extensions[ key ] === true ) extensions[ key ] = true;\n\n\t\t}\n\n\t\tif ( Object.keys( extensions ).length > 0 ) data.extensions = extensions;\n\n\t\treturn data;\n\n\t}\n\n}\n\nShaderMaterial.prototype.isShaderMaterial = true;\n\nclass Camera extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\n\t\tthis.projectionMatrix = new Matrix4();\n\t\tthis.projectionMatrixInverse = new Matrix4();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\t\tthis.projectionMatrixInverse.copy( source.projectionMatrixInverse );\n\n\t\treturn this;\n\n\t}\n\n\tgetWorldDirection( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tconst e = this.matrixWorld.elements;\n\n\t\treturn target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t\tthis.matrixWorldInverse.copy( this.matrixWorld ).invert();\n\n\t}\n\n\tupdateWorldMatrix( updateParents, updateChildren ) {\n\n\t\tsuper.updateWorldMatrix( updateParents, updateChildren );\n\n\t\tthis.matrixWorldInverse.copy( this.matrixWorld ).invert();\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nCamera.prototype.isCamera = true;\n\nclass PerspectiveCamera extends Camera {\n\n\tconstructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near;\n\t\tthis.far = far;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.fov = source.fov;\n\t\tthis.zoom = source.zoom;\n\n\t\tthis.near = source.near;\n\t\tthis.far = source.far;\n\t\tthis.focus = source.focus;\n\n\t\tthis.aspect = source.aspect;\n\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\tthis.filmGauge = source.filmGauge;\n\t\tthis.filmOffset = source.filmOffset;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t *\n\t * The default film gauge is 35, so that the focal length can be specified for\n\t * a 35mm (full frame) camera.\n\t *\n\t * Values for focal length and film gauge must have the same unit.\n\t */\n\tsetFocalLength( focalLength ) {\n\n\t\t/** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */\n\t\tconst vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\tthis.fov = RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\t/**\n\t * Calculates the focal length from the current .fov and .filmGauge.\n\t */\n\tgetFocalLength() {\n\n\t\tconst vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov );\n\n\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t}\n\n\tgetEffectiveFOV() {\n\n\t\treturn RAD2DEG * 2 * Math.atan(\n\t\t\tMath.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t}\n\n\tgetFilmWidth() {\n\n\t\t// film not completely covered in portrait format (aspect < 1)\n\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t}\n\n\tgetFilmHeight() {\n\n\t\t// film not completely covered in landscape format (aspect > 1)\n\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t}\n\n\t/**\n\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t * multi-monitor/multi-machine setups.\n\t *\n\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t * the monitors are in grid like this\n\t *\n\t * +---+---+---+\n\t * | A | B | C |\n\t * +---+---+---+\n\t * | D | E | F |\n\t * +---+---+---+\n\t *\n\t * then for each monitor you would call it like this\n\t *\n\t * const w = 1920;\n\t * const h = 1080;\n\t * const fullWidth = w * 3;\n\t * const fullHeight = h * 2;\n\t *\n\t * --A--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t * --B--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t * --C--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t * --D--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t * --E--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t * --F--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t *\n\t * Note there is no reason monitors have to be the same size or in a grid.\n\t */\n\tsetViewOffset( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\tif ( this.view === null ) {\n\n\t\t\tthis.view = {\n\t\t\t\tenabled: true,\n\t\t\t\tfullWidth: 1,\n\t\t\t\tfullHeight: 1,\n\t\t\t\toffsetX: 0,\n\t\t\t\toffsetY: 0,\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1\n\t\t\t};\n\n\t\t}\n\n\t\tthis.view.enabled = true;\n\t\tthis.view.fullWidth = fullWidth;\n\t\tthis.view.fullHeight = fullHeight;\n\t\tthis.view.offsetX = x;\n\t\tthis.view.offsetY = y;\n\t\tthis.view.width = width;\n\t\tthis.view.height = height;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tclearViewOffset() {\n\n\t\tif ( this.view !== null ) {\n\n\t\t\tthis.view.enabled = false;\n\n\t\t}\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tupdateProjectionMatrix() {\n\n\t\tconst near = this.near;\n\t\tlet top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom;\n\t\tlet height = 2 * top;\n\t\tlet width = this.aspect * height;\n\t\tlet left = - 0.5 * width;\n\t\tconst view = this.view;\n\n\t\tif ( this.view !== null && this.view.enabled ) {\n\n\t\t\tconst fullWidth = view.fullWidth,\n\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\twidth *= view.width / fullWidth;\n\t\t\theight *= view.height / fullHeight;\n\n\t\t}\n\n\t\tconst skew = this.filmOffset;\n\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\tthis.projectionMatrixInverse.copy( this.projectionMatrix ).invert();\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.fov = this.fov;\n\t\tdata.object.zoom = this.zoom;\n\n\t\tdata.object.near = this.near;\n\t\tdata.object.far = this.far;\n\t\tdata.object.focus = this.focus;\n\n\t\tdata.object.aspect = this.aspect;\n\n\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\tdata.object.filmGauge = this.filmGauge;\n\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\treturn data;\n\n\t}\n\n}\n\nPerspectiveCamera.prototype.isPerspectiveCamera = true;\n\nconst fov = 90, aspect = 1;\n\nclass CubeCamera extends Object3D {\n\n\tconstructor( near, far, renderTarget ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tif ( renderTarget.isWebGLCubeRenderTarget !== true ) {\n\n\t\t\tconsole.error( 'THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis.renderTarget = renderTarget;\n\n\t\tconst cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.layers = this.layers;\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tconst cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.layers = this.layers;\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tconst cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.layers = this.layers;\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tconst cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.layers = this.layers;\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tconst cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.layers = this.layers;\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tconst cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.layers = this.layers;\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t}\n\n\tupdate( renderer, scene ) {\n\n\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\tconst renderTarget = this.renderTarget;\n\n\t\tconst [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children;\n\n\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\tconst currentOutputEncoding = renderer.outputEncoding;\n\t\tconst currentToneMapping = renderer.toneMapping;\n\t\tconst currentXrEnabled = renderer.xr.enabled;\n\n\t\trenderer.outputEncoding = LinearEncoding;\n\t\trenderer.toneMapping = NoToneMapping;\n\t\trenderer.xr.enabled = false;\n\n\t\tconst generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\trenderer.setRenderTarget( renderTarget, 0 );\n\t\trenderer.render( scene, cameraPX );\n\n\t\trenderer.setRenderTarget( renderTarget, 1 );\n\t\trenderer.render( scene, cameraNX );\n\n\t\trenderer.setRenderTarget( renderTarget, 2 );\n\t\trenderer.render( scene, cameraPY );\n\n\t\trenderer.setRenderTarget( renderTarget, 3 );\n\t\trenderer.render( scene, cameraNY );\n\n\t\trenderer.setRenderTarget( renderTarget, 4 );\n\t\trenderer.render( scene, cameraPZ );\n\n\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\trenderer.setRenderTarget( renderTarget, 5 );\n\t\trenderer.render( scene, cameraNZ );\n\n\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\trenderer.outputEncoding = currentOutputEncoding;\n\t\trenderer.toneMapping = currentToneMapping;\n\t\trenderer.xr.enabled = currentXrEnabled;\n\n\t\trenderTarget.texture.needsPMREMUpdate = true;\n\n\t}\n\n}\n\nclass CubeTexture extends Texture {\n\n\tconstructor( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tsuper( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tget images() {\n\n\t\treturn this.image;\n\n\t}\n\n\tset images( value ) {\n\n\t\tthis.image = value;\n\n\t}\n\n}\n\nCubeTexture.prototype.isCubeTexture = true;\n\nclass WebGLCubeRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( size, options = {} ) {\n\n\t\tsuper( size, size, options );\n\n\t\tconst image = { width: size, height: size, depth: 1 };\n\t\tconst images = [ image, image, image, image, image, image ];\n\n\t\tthis.texture = new CubeTexture( images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\t// By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)\n\t\t// in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,\n\t\t// in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.\n\n\t\t// three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped\n\t\t// and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture\n\t\t// as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\tthis.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;\n\t\tthis.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;\n\n\t}\n\n\tfromEquirectangularTexture( renderer, texture ) {\n\n\t\tthis.texture.type = texture.type;\n\t\tthis.texture.encoding = texture.encoding;\n\n\t\tthis.texture.generateMipmaps = texture.generateMipmaps;\n\t\tthis.texture.minFilter = texture.minFilter;\n\t\tthis.texture.magFilter = texture.magFilter;\n\n\t\tconst shader = {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t},\n\n\t\t\tvertexShader: /* glsl */`\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\tfragmentShader: /* glsl */`\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t`\n\t\t};\n\n\t\tconst geometry = new BoxGeometry( 5, 5, 5 );\n\n\t\tconst material = new ShaderMaterial( {\n\n\t\t\tname: 'CubemapFromEquirect',\n\n\t\t\tuniforms: cloneUniforms( shader.uniforms ),\n\t\t\tvertexShader: shader.vertexShader,\n\t\t\tfragmentShader: shader.fragmentShader,\n\t\t\tside: BackSide,\n\t\t\tblending: NoBlending\n\n\t\t} );\n\n\t\tmaterial.uniforms.tEquirect.value = texture;\n\n\t\tconst mesh = new Mesh( geometry, material );\n\n\t\tconst currentMinFilter = texture.minFilter;\n\n\t\t// Avoid blurred poles\n\t\tif ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;\n\n\t\tconst camera = new CubeCamera( 1, 10, this );\n\t\tcamera.update( renderer, mesh );\n\n\t\ttexture.minFilter = currentMinFilter;\n\n\t\tmesh.geometry.dispose();\n\t\tmesh.material.dispose();\n\n\t\treturn this;\n\n\t}\n\n\tclear( renderer, color, depth, stencil ) {\n\n\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\trenderer.setRenderTarget( this, i );\n\n\t\t\trenderer.clear( color, depth, stencil );\n\n\t\t}\n\n\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t}\n\n}\n\nWebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;\n\nconst _vector1 = /*@__PURE__*/ new Vector3();\nconst _vector2 = /*@__PURE__*/ new Vector3();\nconst _normalMatrix = /*@__PURE__*/ new Matrix3();\n\nclass Plane {\n\n\tconstructor( normal = new Vector3( 1, 0, 0 ), constant = 0 ) {\n\n\t\t// normal is assumed to be normalized\n\n\t\tthis.normal = normal;\n\t\tthis.constant = constant;\n\n\t}\n\n\tset( normal, constant ) {\n\n\t\tthis.normal.copy( normal );\n\t\tthis.constant = constant;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponents( x, y, z, w ) {\n\n\t\tthis.normal.set( x, y, z );\n\t\tthis.constant = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromNormalAndCoplanarPoint( normal, point ) {\n\n\t\tthis.normal.copy( normal );\n\t\tthis.constant = - point.dot( this.normal );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCoplanarPoints( a, b, c ) {\n\n\t\tconst normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();\n\n\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( plane ) {\n\n\t\tthis.normal.copy( plane.normal );\n\t\tthis.constant = plane.constant;\n\n\t\treturn this;\n\n\t}\n\n\tnormalize() {\n\n\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\tconst inverseNormalLength = 1.0 / this.normal.length();\n\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\tthis.constant *= inverseNormalLength;\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.constant *= - 1;\n\t\tthis.normal.negate();\n\n\t\treturn this;\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn this.normal.dot( point ) + this.constant;\n\n\t}\n\n\tdistanceToSphere( sphere ) {\n\n\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t}\n\n\tprojectPoint( point, target ) {\n\n\t\treturn target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );\n\n\t}\n\n\tintersectLine( line, target ) {\n\n\t\tconst direction = line.delta( _vector1 );\n\n\t\tconst denominator = this.normal.dot( direction );\n\n\t\tif ( denominator === 0 ) {\n\n\t\t\t// line is coplanar, return origin\n\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\treturn target.copy( line.start );\n\n\t\t\t}\n\n\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\treturn target.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t}\n\n\tintersectsLine( line ) {\n\n\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\tconst startSign = this.distanceToPoint( line.start );\n\t\tconst endSign = this.distanceToPoint( line.end );\n\n\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsPlane( this );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\treturn sphere.intersectsPlane( this );\n\n\t}\n\n\tcoplanarPoint( target ) {\n\n\t\treturn target.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t}\n\n\tapplyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\tconst normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );\n\n\t\tconst referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );\n\n\t\tconst normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.constant -= offset.dot( this.normal );\n\n\t\treturn this;\n\n\t}\n\n\tequals( plane ) {\n\n\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nPlane.prototype.isPlane = true;\n\nconst _sphere$2 = /*@__PURE__*/ new Sphere();\nconst _vector$7 = /*@__PURE__*/ new Vector3();\n\nclass Frustum {\n\n\tconstructor( p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane() ) {\n\n\t\tthis.planes = [ p0, p1, p2, p3, p4, p5 ];\n\n\t}\n\n\tset( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tconst planes = this.planes;\n\n\t\tplanes[ 0 ].copy( p0 );\n\t\tplanes[ 1 ].copy( p1 );\n\t\tplanes[ 2 ].copy( p2 );\n\t\tplanes[ 3 ].copy( p3 );\n\t\tplanes[ 4 ].copy( p4 );\n\t\tplanes[ 5 ].copy( p5 );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( frustum ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetFromProjectionMatrix( m ) {\n\n\t\tconst planes = this.planes;\n\t\tconst me = m.elements;\n\t\tconst me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\tconst me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\tconst me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\tconst me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\treturn this;\n\n\t}\n\n\tintersectsObject( object ) {\n\n\t\tconst geometry = object.geometry;\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere$2.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );\n\n\t\treturn this.intersectsSphere( _sphere$2 );\n\n\t}\n\n\tintersectsSprite( sprite ) {\n\n\t\t_sphere$2.center.set( 0, 0, 0 );\n\t\t_sphere$2.radius = 0.7071067811865476;\n\t\t_sphere$2.applyMatrix4( sprite.matrixWorld );\n\n\t\treturn this.intersectsSphere( _sphere$2 );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\tconst planes = this.planes;\n\t\tconst center = sphere.center;\n\t\tconst negRadius = - sphere.radius;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tconst distance = planes[ i ].distanceToPoint( center );\n\n\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tconst plane = planes[ i ];\n\n\t\t\t// corner at max distance\n\n\t\t\t_vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t_vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t_vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\tif ( plane.distanceToPoint( _vector$7 ) < 0 ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nfunction WebGLAnimation() {\n\n\tlet context = null;\n\tlet isAnimating = false;\n\tlet animationLoop = null;\n\tlet requestId = null;\n\n\tfunction onAnimationFrame( time, frame ) {\n\n\t\tanimationLoop( time, frame );\n\n\t\trequestId = context.requestAnimationFrame( onAnimationFrame );\n\n\t}\n\n\treturn {\n\n\t\tstart: function () {\n\n\t\t\tif ( isAnimating === true ) return;\n\t\t\tif ( animationLoop === null ) return;\n\n\t\t\trequestId = context.requestAnimationFrame( onAnimationFrame );\n\n\t\t\tisAnimating = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tcontext.cancelAnimationFrame( requestId );\n\n\t\t\tisAnimating = false;\n\n\t\t},\n\n\t\tsetAnimationLoop: function ( callback ) {\n\n\t\t\tanimationLoop = callback;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n}\n\nfunction WebGLAttributes( gl, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tconst buffers = new WeakMap();\n\n\tfunction createBuffer( attribute, bufferType ) {\n\n\t\tconst array = attribute.array;\n\t\tconst usage = attribute.usage;\n\n\t\tconst buffer = gl.createBuffer();\n\n\t\tgl.bindBuffer( bufferType, buffer );\n\t\tgl.bufferData( bufferType, array, usage );\n\n\t\tattribute.onUploadCallback();\n\n\t\tlet type;\n\n\t\tif ( array instanceof Float32Array ) {\n\n\t\t\ttype = 5126;\n\n\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\tif ( attribute.isFloat16BufferAttribute ) {\n\n\t\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\t\ttype = 5131;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.' );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\ttype = 5123;\n\n\t\t\t}\n\n\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\ttype = 5122;\n\n\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\ttype = 5125;\n\n\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\ttype = 5124;\n\n\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\ttype = 5120;\n\n\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\ttype = 5121;\n\n\t\t} else if ( array instanceof Uint8ClampedArray ) {\n\n\t\t\ttype = 5121;\n\n\t\t} else {\n\n\t\t\tthrow new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array );\n\n\t\t}\n\n\t\treturn {\n\t\t\tbuffer: buffer,\n\t\t\ttype: type,\n\t\t\tbytesPerElement: array.BYTES_PER_ELEMENT,\n\t\t\tversion: attribute.version\n\t\t};\n\n\t}\n\n\tfunction updateBuffer( buffer, attribute, bufferType ) {\n\n\t\tconst array = attribute.array;\n\t\tconst updateRange = attribute.updateRange;\n\n\t\tgl.bindBuffer( bufferType, buffer );\n\n\t\tif ( updateRange.count === - 1 ) {\n\n\t\t\t// Not using update ranges\n\n\t\t\tgl.bufferSubData( bufferType, 0, array );\n\n\t\t} else {\n\n\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\tgl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,\n\t\t\t\t\tarray, updateRange.offset, updateRange.count );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,\n\t\t\t\t\tarray.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );\n\n\t\t\t}\n\n\t\t\tupdateRange.count = - 1; // reset range\n\n\t\t}\n\n\t}\n\n\t//\n\n\tfunction get( attribute ) {\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\treturn buffers.get( attribute );\n\n\t}\n\n\tfunction remove( attribute ) {\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\tconst data = buffers.get( attribute );\n\n\t\tif ( data ) {\n\n\t\t\tgl.deleteBuffer( data.buffer );\n\n\t\t\tbuffers.delete( attribute );\n\n\t\t}\n\n\t}\n\n\tfunction update( attribute, bufferType ) {\n\n\t\tif ( attribute.isGLBufferAttribute ) {\n\n\t\t\tconst cached = buffers.get( attribute );\n\n\t\t\tif ( ! cached || cached.version < attribute.version ) {\n\n\t\t\t\tbuffers.set( attribute, {\n\t\t\t\t\tbuffer: attribute.buffer,\n\t\t\t\t\ttype: attribute.type,\n\t\t\t\t\tbytesPerElement: attribute.elementSize,\n\t\t\t\t\tversion: attribute.version\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\tconst data = buffers.get( attribute );\n\n\t\tif ( data === undefined ) {\n\n\t\t\tbuffers.set( attribute, createBuffer( attribute, bufferType ) );\n\n\t\t} else if ( data.version < attribute.version ) {\n\n\t\t\tupdateBuffer( data.buffer, attribute, bufferType );\n\n\t\t\tdata.version = attribute.version;\n\n\t\t}\n\n\t}\n\n\treturn {\n\n\t\tget: get,\n\t\tremove: remove,\n\t\tupdate: update\n\n\t};\n\n}\n\nclass PlaneGeometry extends BufferGeometry {\n\n\tconstructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) {\n\n\t\tsuper();\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tconst width_half = width / 2;\n\t\tconst height_half = height / 2;\n\n\t\tconst gridX = Math.floor( widthSegments );\n\t\tconst gridY = Math.floor( heightSegments );\n\n\t\tconst gridX1 = gridX + 1;\n\t\tconst gridY1 = gridY + 1;\n\n\t\tconst segment_width = width / gridX;\n\t\tconst segment_height = height / gridY;\n\n\t\t//\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tfor ( let iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tconst y = iy * segment_height - height_half;\n\n\t\t\tfor ( let ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tconst x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( let ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tconst a = ix + gridX1 * iy;\n\t\t\t\tconst b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tconst c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tconst d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new PlaneGeometry( data.width, data.height, data.widthSegments, data.heightSegments );\n\n\t}\n\n}\n\nvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\";\n\nvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\";\n\nvar alphatest_fragment = \"#ifdef USE_ALPHATEST\\n\\tif ( diffuseColor.a < alphaTest ) discard;\\n#endif\";\n\nvar alphatest_pars_fragment = \"#ifdef USE_ALPHATEST\\n\\tuniform float alphaTest;\\n#endif\";\n\nvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( STANDARD )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\\n\\t#endif\\n#endif\";\n\nvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\nvar begin_vertex = \"vec3 transformed = vec3( position );\";\n\nvar beginnormal_vertex = \"vec3 objectNormal = vec3( normal );\\n#ifdef USE_TANGENT\\n\\tvec3 objectTangent = vec3( tangent.xyz );\\n#endif\";\n\nvar bsdfs = \"vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\\n\\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\\n\\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\\n}\\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNL = saturate( dot( normal, lightDir ) );\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\\n\\tvec3 F = F_Schlick( f0, f90, dotVH );\\n\\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( V * D );\\n}\\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\\n\\tfloat dotNV = saturate( dot( N, V ) );\\n\\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\\n\\tfloat l = length( f );\\n\\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\\n}\\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\\n\\tfloat x = dot( v1, v2 );\\n\\tfloat y = abs( x );\\n\\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\\n\\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\\n\\tfloat v = a / b;\\n\\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\\n\\treturn cross( v1, v2 ) * theta_sintheta;\\n}\\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\\n\\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\\n\\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\\n\\tvec3 lightNormal = cross( v1, v2 );\\n\\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\\n\\tvec3 T1, T2;\\n\\tT1 = normalize( V - N * dot( V, N ) );\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\\n\\tvec3 coords[ 4 ];\\n\\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\\n\\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\\n\\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\\n\\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\\n\\tcoords[ 0 ] = normalize( coords[ 0 ] );\\n\\tcoords[ 1 ] = normalize( coords[ 1 ] );\\n\\tcoords[ 2 ] = normalize( coords[ 2 ] );\\n\\tcoords[ 3 ] = normalize( coords[ 3 ] );\\n\\tvec3 vectorFormFactor = vec3( 0.0 );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\\n\\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\\n\\treturn vec3( result );\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\n#if defined( USE_SHEEN )\\nfloat D_Charlie( float roughness, float dotNH ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tfloat invAlpha = 1.0 / alpha;\\n\\tfloat cos2h = dotNH * dotNH;\\n\\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\\n\\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\\n}\\nfloat V_Neubelt( float dotNV, float dotNL ) {\\n\\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\\n}\\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNL = saturate( dot( normal, lightDir ) );\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat D = D_Charlie( sheenRoughness, dotNH );\\n\\tfloat V = V_Neubelt( dotNV, dotNL );\\n\\treturn sheenColor * ( D * V );\\n}\\n#endif\";\n\nvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\\n\\t\\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\\n\\t\\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\";\n\nvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvec4 plane;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\\n\\t\\tplane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\t#pragma unroll_loop_start\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\\n\\t\\t\\tplane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\t#pragma unroll_loop_end\\n\\t\\tif ( clipped ) discard;\\n\\t#endif\\n#endif\";\n\nvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvarying vec3 vClipPosition;\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\";\n\nvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvarying vec3 vClipPosition;\\n#endif\";\n\nvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvClipPosition = - mvPosition.xyz;\\n#endif\";\n\nvar color_fragment = \"#if defined( USE_COLOR_ALPHA )\\n\\tdiffuseColor *= vColor;\\n#elif defined( USE_COLOR )\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\nvar color_pars_fragment = \"#if defined( USE_COLOR_ALPHA )\\n\\tvarying vec4 vColor;\\n#elif defined( USE_COLOR )\\n\\tvarying vec3 vColor;\\n#endif\";\n\nvar color_pars_vertex = \"#if defined( USE_COLOR_ALPHA )\\n\\tvarying vec4 vColor;\\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\\n\\tvarying vec3 vColor;\\n#endif\";\n\nvar color_vertex = \"#if defined( USE_COLOR_ALPHA )\\n\\tvColor = vec4( 1.0 );\\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\\n\\tvColor = vec3( 1.0 );\\n#endif\\n#ifdef USE_COLOR\\n\\tvColor *= color;\\n#endif\\n#ifdef USE_INSTANCING_COLOR\\n\\tvColor.xyz *= instanceColor.xyz;\\n#endif\";\n\nvar common = \"#define PI 3.141592653589793\\n#define PI2 6.283185307179586\\n#define PI_HALF 1.5707963267948966\\n#define RECIPROCAL_PI 0.3183098861837907\\n#define RECIPROCAL_PI2 0.15915494309189535\\n#define EPSILON 1e-6\\n#ifndef saturate\\n#define saturate( a ) clamp( a, 0.0, 1.0 )\\n#endif\\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract( sin( sn ) * c );\\n}\\n#ifdef HIGH_PRECISION\\n\\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\\n#else\\n\\tfloat precisionSafeLength( vec3 v ) {\\n\\t\\tfloat maxComponent = max3( abs( v ) );\\n\\t\\treturn length( v / maxComponent ) * maxComponent;\\n\\t}\\n#endif\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n#ifdef USE_CLEARCOAT\\n\\tvec3 clearcoatNormal;\\n#endif\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nmat3 transposeMat3( const in mat3 m ) {\\n\\tmat3 tmp;\\n\\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\\n\\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\\n\\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\\n\\treturn tmp;\\n}\\nfloat linearToRelativeLuminance( const in vec3 color ) {\\n\\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\\n\\treturn dot( weights, color.rgb );\\n}\\nbool isPerspectiveMatrix( mat4 m ) {\\n\\treturn m[ 2 ][ 3 ] == - 1.0;\\n}\\nvec2 equirectUv( in vec3 dir ) {\\n\\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\\n\\treturn vec2( u, v );\\n}\";\n\nvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n\\t#define cubeUV_minMipLevel 4.0\\n\\t#define cubeUV_minTileSize 16.0\\n\\tfloat getFace( vec3 direction ) {\\n\\t\\tvec3 absDirection = abs( direction );\\n\\t\\tfloat face = - 1.0;\\n\\t\\tif ( absDirection.x > absDirection.z ) {\\n\\t\\t\\tif ( absDirection.x > absDirection.y )\\n\\t\\t\\t\\tface = direction.x > 0.0 ? 0.0 : 3.0;\\n\\t\\t\\telse\\n\\t\\t\\t\\tface = direction.y > 0.0 ? 1.0 : 4.0;\\n\\t\\t} else {\\n\\t\\t\\tif ( absDirection.z > absDirection.y )\\n\\t\\t\\t\\tface = direction.z > 0.0 ? 2.0 : 5.0;\\n\\t\\t\\telse\\n\\t\\t\\t\\tface = direction.y > 0.0 ? 1.0 : 4.0;\\n\\t\\t}\\n\\t\\treturn face;\\n\\t}\\n\\tvec2 getUV( vec3 direction, float face ) {\\n\\t\\tvec2 uv;\\n\\t\\tif ( face == 0.0 ) {\\n\\t\\t\\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\\n\\t\\t} else if ( face == 1.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\\n\\t\\t} else if ( face == 2.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\\n\\t\\t} else if ( face == 3.0 ) {\\n\\t\\t\\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\\n\\t\\t} else if ( face == 4.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\\n\\t\\t} else {\\n\\t\\t\\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\\n\\t\\t}\\n\\t\\treturn 0.5 * ( uv + 1.0 );\\n\\t}\\n\\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\\n\\t\\tfloat face = getFace( direction );\\n\\t\\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\\n\\t\\tmipInt = max( mipInt, cubeUV_minMipLevel );\\n\\t\\tfloat faceSize = exp2( mipInt );\\n\\t\\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5;\\n\\t\\tif ( face > 2.0 ) {\\n\\t\\t\\tuv.y += faceSize;\\n\\t\\t\\tface -= 3.0;\\n\\t\\t}\\n\\t\\tuv.x += face * faceSize;\\n\\t\\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\\n\\t\\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\\n\\t\\tuv.x *= CUBEUV_TEXEL_WIDTH;\\n\\t\\tuv.y *= CUBEUV_TEXEL_HEIGHT;\\n\\t\\t#ifdef texture2DGradEXT\\n\\t\\t\\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn texture2D( envMap, uv ).rgb;\\n\\t\\t#endif\\n\\t}\\n\\t#define r0 1.0\\n\\t#define v0 0.339\\n\\t#define m0 - 2.0\\n\\t#define r1 0.8\\n\\t#define v1 0.276\\n\\t#define m1 - 1.0\\n\\t#define r4 0.4\\n\\t#define v4 0.046\\n\\t#define m4 2.0\\n\\t#define r5 0.305\\n\\t#define v5 0.016\\n\\t#define m5 3.0\\n\\t#define r6 0.21\\n\\t#define v6 0.0038\\n\\t#define m6 4.0\\n\\tfloat roughnessToMip( float roughness ) {\\n\\t\\tfloat mip = 0.0;\\n\\t\\tif ( roughness >= r1 ) {\\n\\t\\t\\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\\n\\t\\t} else if ( roughness >= r4 ) {\\n\\t\\t\\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\\n\\t\\t} else if ( roughness >= r5 ) {\\n\\t\\t\\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\\n\\t\\t} else if ( roughness >= r6 ) {\\n\\t\\t\\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\\n\\t\\t} else {\\n\\t\\t\\tmip = - 2.0 * log2( 1.16 * roughness );\\t\\t}\\n\\t\\treturn mip;\\n\\t}\\n\\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\\n\\t\\tfloat mip = clamp( roughnessToMip( roughness ), m0, CUBEUV_MAX_MIP );\\n\\t\\tfloat mipF = fract( mip );\\n\\t\\tfloat mipInt = floor( mip );\\n\\t\\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\\n\\t\\tif ( mipF == 0.0 ) {\\n\\t\\t\\treturn vec4( color0, 1.0 );\\n\\t\\t} else {\\n\\t\\t\\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\\n\\t\\t\\treturn vec4( mix( color0, color1, mipF ), 1.0 );\\n\\t\\t}\\n\\t}\\n#endif\";\n\nvar defaultnormal_vertex = \"vec3 transformedNormal = objectNormal;\\n#ifdef USE_INSTANCING\\n\\tmat3 m = mat3( instanceMatrix );\\n\\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\\n\\ttransformedNormal = m * transformedNormal;\\n#endif\\ntransformedNormal = normalMatrix * transformedNormal;\\n#ifdef FLIP_SIDED\\n\\ttransformedNormal = - transformedNormal;\\n#endif\\n#ifdef USE_TANGENT\\n\\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\\n\\t#ifdef FLIP_SIDED\\n\\t\\ttransformedTangent = - transformedTangent;\\n\\t#endif\\n#endif\";\n\nvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\";\n\nvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\\n#endif\";\n\nvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\";\n\nvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\";\n\nvar encodings_fragment = \"gl_FragColor = linearToOutputTexel( gl_FragColor );\";\n\nvar encodings_pars_fragment = \"vec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\\n}\";\n\nvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvec3 cameraToFrag;\\n\\t\\tif ( isOrthographic ) {\\n\\t\\t\\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\\n\\t\\t} else {\\n\\t\\t\\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\\n\\t\\t}\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\";\n\nvar envmap_common_pars_fragment = \"#ifdef USE_ENVMAP\\n\\tuniform float envMapIntensity;\\n\\tuniform float flipEnvMap;\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\t\\n#endif\";\n\nvar envmap_pars_fragment = \"#ifdef USE_ENVMAP\\n\\tuniform float reflectivity;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\t#define ENV_WORLDPOS\\n\\t#endif\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\";\n\nvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\\n\\t\\t#define ENV_WORLDPOS\\n\\t#endif\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\t\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\";\n\nvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex;\\n\\t\\tif ( isOrthographic ) {\\n\\t\\t\\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\\n\\t\\t} else {\\n\\t\\t\\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\t}\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar fog_vertex = \"#ifdef USE_FOG\\n\\tvFogDepth = - mvPosition.z;\\n#endif\";\n\nvar fog_pars_vertex = \"#ifdef USE_FOG\\n\\tvarying float vFogDepth;\\n#endif\";\n\nvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\";\n\nvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float vFogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\";\n\nvar gradientmap_pars_fragment = \"#ifdef USE_GRADIENTMAP\\n\\tuniform sampler2D gradientMap;\\n#endif\\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\tfloat dotNL = dot( normal, lightDirection );\\n\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t#ifdef USE_GRADIENTMAP\\n\\t\\treturn vec3( texture2D( gradientMap, coord ).r );\\n\\t#else\\n\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t#endif\\n}\";\n\nvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\\n\\treflectedLight.indirectDiffuse += lightMapIrradiance;\\n#endif\";\n\nvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\nvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\nvIndirectFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n\\tvIndirectBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\\n#ifdef DOUBLE_SIDED\\n\\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\\n\\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\";\n\nvar lights_pars_begin = \"uniform bool receiveShadow;\\nuniform vec3 ambientLightColor;\\nuniform vec3 lightProbe[ 9 ];\\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\\n\\tfloat x = normal.x, y = normal.y, z = normal.z;\\n\\tvec3 result = shCoefficients[ 0 ] * 0.886227;\\n\\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\\n\\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\\n\\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\\n\\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\\n\\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\\n\\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\\n\\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\\n\\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\\n\\treturn result;\\n}\\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\\n\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\\n\\treturn irradiance;\\n}\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\treturn irradiance;\\n}\\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\tif ( cutoffDistance > 0.0 ) {\\n\\t\\t\\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t}\\n\\t\\treturn distanceFalloff;\\n\\t#else\\n\\t\\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\\n\\t\\t\\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t#endif\\n}\\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\\n\\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tlight.color = directionalLight.color;\\n\\t\\tlight.direction = directionalLight.direction;\\n\\t\\tlight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tlight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tlight.color = pointLight.color;\\n\\t\\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tlight.visible = ( light.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tlight.direction = normalize( lVector );\\n\\t\\tfloat angleCos = dot( light.direction, spotLight.direction );\\n\\t\\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\tif ( spotAttenuation > 0.0 ) {\\n\\t\\t\\tfloat lightDistance = length( lVector );\\n\\t\\t\\tlight.color = spotLight.color * spotAttenuation;\\n\\t\\t\\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tlight.visible = ( light.color != vec3( 0.0 ) );\\n\\t\\t} else {\\n\\t\\t\\tlight.color = vec3( 0.0 );\\n\\t\\t\\tlight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltc_1;\\tuniform sampler2D ltc_2;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\\n\\t\\tfloat dotNL = dot( normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\";\n\nvar envmap_physical_pars_fragment = \"#if defined( USE_ENVMAP )\\n\\tvec3 getIBLIrradiance( const in vec3 normal ) {\\n\\t\\t#if defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\\n\\t\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t\\t#else\\n\\t\\t\\treturn vec3( 0.0 );\\n\\t\\t#endif\\n\\t}\\n\\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\\n\\t\\t#if defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 reflectVec = reflect( - viewDir, normal );\\n\\t\\t\\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\\n\\t\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\\n\\t\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t\\t#else\\n\\t\\t\\treturn vec3( 0.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar lights_toon_fragment = \"ToonMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\";\n\nvar lights_toon_pars_fragment = \"varying vec3 vViewPosition;\\nstruct ToonMaterial {\\n\\tvec3 diffuseColor;\\n};\\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Toon\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Toon\\n#define Material_LightProbeLOD( material )\\t(0)\";\n\nvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\";\n\nvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\nstruct BlinnPhongMaterial {\\n\\tvec3 diffuseColor;\\n\\tvec3 specularColor;\\n\\tfloat specularShininess;\\n\\tfloat specularStrength;\\n};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\";\n\nvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\\nmaterial.roughness = min( material.roughness, 1.0 );\\n#ifdef IOR\\n\\t#ifdef SPECULAR\\n\\t\\tfloat specularIntensityFactor = specularIntensity;\\n\\t\\tvec3 specularColorFactor = specularColor;\\n\\t\\t#ifdef USE_SPECULARINTENSITYMAP\\n\\t\\t\\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\\n\\t\\t#endif\\n\\t\\t#ifdef USE_SPECULARCOLORMAP\\n\\t\\t\\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\\n\\t\\t#endif\\n\\t\\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\\n\\t#else\\n\\t\\tfloat specularIntensityFactor = 1.0;\\n\\t\\tvec3 specularColorFactor = vec3( 1.0 );\\n\\t\\tmaterial.specularF90 = 1.0;\\n\\t#endif\\n\\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.specularF90 = 1.0;\\n#endif\\n#ifdef USE_CLEARCOAT\\n\\tmaterial.clearcoat = clearcoat;\\n\\tmaterial.clearcoatRoughness = clearcoatRoughness;\\n\\tmaterial.clearcoatF0 = vec3( 0.04 );\\n\\tmaterial.clearcoatF90 = 1.0;\\n\\t#ifdef USE_CLEARCOATMAP\\n\\t\\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\\n\\t#endif\\n\\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\\n\\t\\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\\n\\t#endif\\n\\tmaterial.clearcoat = saturate( material.clearcoat );\\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\\n\\tmaterial.clearcoatRoughness += geometryRoughness;\\n\\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\\n#endif\\n#ifdef USE_SHEEN\\n\\tmaterial.sheenColor = sheenColor;\\n\\t#ifdef USE_SHEENCOLORMAP\\n\\t\\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\\n\\t#endif\\n\\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\\n\\t#ifdef USE_SHEENROUGHNESSMAP\\n\\t\\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\\n\\t#endif\\n#endif\";\n\nvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3 diffuseColor;\\n\\tfloat roughness;\\n\\tvec3 specularColor;\\n\\tfloat specularF90;\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tfloat clearcoat;\\n\\t\\tfloat clearcoatRoughness;\\n\\t\\tvec3 clearcoatF0;\\n\\t\\tfloat clearcoatF90;\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tvec3 sheenColor;\\n\\t\\tfloat sheenRoughness;\\n\\t#endif\\n};\\nvec3 clearcoatSpecular = vec3( 0.0 );\\nvec3 sheenSpecular = vec3( 0.0 );\\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat r2 = roughness * roughness;\\n\\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\\n\\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\\n\\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\\n\\treturn saturate( DG * RECIPROCAL_PI );\\n}\\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\\n\\treturn fab;\\n}\\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\\n\\tvec2 fab = DFGApprox( normal, viewDir, roughness );\\n\\treturn specularColor * fab.x + specularF90 * fab.y;\\n}\\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\\n\\tvec2 fab = DFGApprox( normal, viewDir, roughness );\\n\\tvec3 FssEss = specularColor * fab.x + specularF90 * fab.y;\\n\\tfloat Ess = fab.x + fab.y;\\n\\tfloat Ems = 1.0 - Ess;\\n\\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\\n\\tsingleScatter += FssEss;\\n\\tmultiScatter += Fms * Ems;\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 normal = geometry.normal;\\n\\t\\tvec3 viewDir = geometry.viewDir;\\n\\t\\tvec3 position = geometry.position;\\n\\t\\tvec3 lightPos = rectAreaLight.position;\\n\\t\\tvec3 halfWidth = rectAreaLight.halfWidth;\\n\\t\\tvec3 halfHeight = rectAreaLight.halfHeight;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.roughness;\\n\\t\\tvec3 rectCoords[ 4 ];\\n\\t\\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\\t\\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\\n\\t\\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\\n\\t\\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\\n\\t\\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\\n\\t\\tvec4 t1 = texture2D( ltc_1, uv );\\n\\t\\tvec4 t2 = texture2D( ltc_2, uv );\\n\\t\\tmat3 mInv = mat3(\\n\\t\\t\\tvec3( t1.x, 0, t1.y ),\\n\\t\\t\\tvec3( 0, 1, 0 ),\\n\\t\\t\\tvec3( t1.z, 0, t1.w )\\n\\t\\t);\\n\\t\\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\\n\\t\\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\\n\\t\\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\\n\\t\\tvec3 ccIrradiance = dotNLcc * directLight.color;\\n\\t\\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\\n\\t#endif\\n\\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\\n\\t#endif\\n\\tvec3 singleScattering = vec3( 0.0 );\\n\\tvec3 multiScattering = vec3( 0.0 );\\n\\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\\n\\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\\n\\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\\n\\treflectedLight.indirectSpecular += radiance * singleScattering;\\n\\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\\n\\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\";\n\nvar lights_fragment_begin = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\\n#ifdef USE_CLEARCOAT\\n\\tgeometry.clearcoatNormal = clearcoatNormal;\\n#endif\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\\n\\tPointLightShadow pointLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointLightInfo( pointLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\\n\\t\\tpointLightShadow = pointLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\\n\\tSpotLightShadow spotLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotLightInfo( spotLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\\n\\t\\tspotLightShadow = spotLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\\n\\tDirectionalLightShadow directionalLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\\n\\t\\tdirectionalLightShadow = directionalLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 iblIrradiance = vec3( 0.0 );\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\tirradiance += getLightProbeIrradiance( lightProbe, geometry.normal );\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\t#pragma unroll_loop_start\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\\n\\t\\t}\\n\\t\\t#pragma unroll_loop_end\\n\\t#endif\\n#endif\\n#if defined( RE_IndirectSpecular )\\n\\tvec3 radiance = vec3( 0.0 );\\n\\tvec3 clearcoatRadiance = vec3( 0.0 );\\n#endif\";\n\nvar lights_fragment_maps = \"#if defined( RE_IndirectDiffuse )\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\t\\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tiblIrradiance += getIBLIrradiance( geometry.normal );\\n\\t#endif\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\\n\\t#endif\\n#endif\";\n\nvar lights_fragment_end = \"#if defined( RE_IndirectDiffuse )\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( RE_IndirectSpecular )\\n\\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\\n#endif\";\n\nvar logdepthbuf_fragment = \"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\\n\\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\\n#endif\";\n\nvar logdepthbuf_pars_fragment = \"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\\n\\tuniform float logDepthBufFC;\\n\\tvarying float vFragDepth;\\n\\tvarying float vIsPerspective;\\n#endif\";\n\nvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t\\tvarying float vIsPerspective;\\n\\t#else\\n\\t\\tuniform float logDepthBufFC;\\n\\t#endif\\n#endif\";\n\nvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t\\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\\n\\t#else\\n\\t\\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\\n\\t\\t\\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\\n\\t\\t\\tgl_Position.z *= gl_Position.w;\\n\\t\\t}\\n\\t#endif\\n#endif\";\n\nvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 sampledDiffuseColor = texture2D( map, vUv );\\n\\t#ifdef DECODE_VIDEO_TEXTURE\\n\\t\\tsampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );\\n\\t#endif\\n\\tdiffuseColor *= sampledDiffuseColor;\\n#endif\";\n\nvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\";\n\nvar map_particle_fragment = \"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\\n\\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\\n#endif\\n#ifdef USE_MAP\\n\\tdiffuseColor *= texture2D( map, uv );\\n#endif\\n#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\\n#endif\";\n\nvar map_particle_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\\n\\tuniform mat3 uvTransform;\\n#endif\\n#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\";\n\nvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.b;\\n#endif\";\n\nvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\nvar morphcolor_vertex = \"#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE )\\n\\tvColor *= morphTargetBaseInfluence;\\n\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t#if defined( USE_COLOR_ALPHA )\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\\n\\t\\t#elif defined( USE_COLOR )\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal *= morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\\n\\t\\t}\\n\\t#else\\n\\t\\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\\n\\t\\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\\n\\t\\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\\n\\t\\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\\n\\t#endif\\n#endif\";\n\nvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\tuniform float morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\\n\\t\\tuniform sampler2DArray morphTargetsTexture;\\n\\t\\tuniform ivec2 morphTargetsTextureSize;\\n\\t\\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\\n\\t\\t\\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\\n\\t\\t\\tint y = texelIndex / morphTargetsTextureSize.x;\\n\\t\\t\\tint x = texelIndex - y * morphTargetsTextureSize.x;\\n\\t\\t\\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\\n\\t\\t\\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\\n\\t\\t}\\n\\t#else\\n\\t\\t#ifndef USE_MORPHNORMALS\\n\\t\\t\\tuniform float morphTargetInfluences[ 8 ];\\n\\t\\t#else\\n\\t\\t\\tuniform float morphTargetInfluences[ 4 ];\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed *= morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\\n\\t\\t}\\n\\t#else\\n\\t\\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\\n\\t\\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\\n\\t\\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\\n\\t\\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\\n\\t\\t#ifndef USE_MORPHNORMALS\\n\\t\\t\\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\\n\\t\\t\\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\\n\\t\\t\\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\\n\\t\\t\\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar normal_fragment_begin = \"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\\n#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tnormal = normal * faceDirection;\\n\\t#endif\\n\\t#ifdef USE_TANGENT\\n\\t\\tvec3 tangent = normalize( vTangent );\\n\\t\\tvec3 bitangent = normalize( vBitangent );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\ttangent = tangent * faceDirection;\\n\\t\\t\\tbitangent = bitangent * faceDirection;\\n\\t\\t#endif\\n\\t\\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\\n\\t\\t\\tmat3 vTBN = mat3( tangent, bitangent, normal );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\nvec3 geometryNormal = normal;\";\n\nvar normal_fragment_maps = \"#ifdef OBJECTSPACE_NORMALMAP\\n\\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t#ifdef FLIP_SIDED\\n\\t\\tnormal = - normal;\\n\\t#endif\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tnormal = normal * faceDirection;\\n\\t#endif\\n\\tnormal = normalize( normalMatrix * normal );\\n#elif defined( TANGENTSPACE_NORMALMAP )\\n\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\tmapN.xy *= normalScale;\\n\\t#ifdef USE_TANGENT\\n\\t\\tnormal = normalize( vTBN * mapN );\\n\\t#else\\n\\t\\tnormal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\\n\\t#endif\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\\n#endif\";\n\nvar normal_pars_fragment = \"#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n\\t#ifdef USE_TANGENT\\n\\t\\tvarying vec3 vTangent;\\n\\t\\tvarying vec3 vBitangent;\\n\\t#endif\\n#endif\";\n\nvar normal_pars_vertex = \"#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n\\t#ifdef USE_TANGENT\\n\\t\\tvarying vec3 vTangent;\\n\\t\\tvarying vec3 vBitangent;\\n\\t#endif\\n#endif\";\n\nvar normal_vertex = \"#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n\\t#ifdef USE_TANGENT\\n\\t\\tvTangent = normalize( transformedTangent );\\n\\t\\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\\n\\t#endif\\n#endif\";\n\nvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n#endif\\n#ifdef OBJECTSPACE_NORMALMAP\\n\\tuniform mat3 normalMatrix;\\n#endif\\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\\n\\t\\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\\n\\t\\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 N = surf_norm;\\n\\t\\tvec3 q1perp = cross( q1, N );\\n\\t\\tvec3 q0perp = cross( N, q0 );\\n\\t\\tvec3 T = q1perp * st0.x + q0perp * st1.x;\\n\\t\\tvec3 B = q1perp * st0.y + q0perp * st1.y;\\n\\t\\tfloat det = max( dot( T, T ), dot( B, B ) );\\n\\t\\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\\n\\t\\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\\n\\t}\\n#endif\";\n\nvar clearcoat_normal_fragment_begin = \"#ifdef USE_CLEARCOAT\\n\\tvec3 clearcoatNormal = geometryNormal;\\n#endif\";\n\nvar clearcoat_normal_fragment_maps = \"#ifdef USE_CLEARCOAT_NORMALMAP\\n\\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\\n\\tclearcoatMapN.xy *= clearcoatNormalScale;\\n\\t#ifdef USE_TANGENT\\n\\t\\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\\n\\t#else\\n\\t\\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\\n\\t#endif\\n#endif\";\n\nvar clearcoat_pars_fragment = \"#ifdef USE_CLEARCOATMAP\\n\\tuniform sampler2D clearcoatMap;\\n#endif\\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\\n\\tuniform sampler2D clearcoatRoughnessMap;\\n#endif\\n#ifdef USE_CLEARCOAT_NORMALMAP\\n\\tuniform sampler2D clearcoatNormalMap;\\n\\tuniform vec2 clearcoatNormalScale;\\n#endif\";\n\nvar output_fragment = \"#ifdef OPAQUE\\ndiffuseColor.a = 1.0;\\n#endif\\n#ifdef USE_TRANSMISSION\\ndiffuseColor.a *= transmissionAlpha + 0.1;\\n#endif\\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\";\n\nvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 2.0 * rgb.xyz - 1.0;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nvec4 pack2HalfToRGBA( vec2 v ) {\\n\\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\\n\\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\\n}\\nvec2 unpackRGBATo2Half( vec4 v ) {\\n\\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\";\n\nvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\";\n\nvar project_vertex = \"vec4 mvPosition = vec4( transformed, 1.0 );\\n#ifdef USE_INSTANCING\\n\\tmvPosition = instanceMatrix * mvPosition;\\n#endif\\nmvPosition = modelViewMatrix * mvPosition;\\ngl_Position = projectionMatrix * mvPosition;\";\n\nvar dithering_fragment = \"#ifdef DITHERING\\n\\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\\n#endif\";\n\nvar dithering_pars_fragment = \"#ifdef DITHERING\\n\\tvec3 dithering( vec3 color ) {\\n\\t\\tfloat grid_position = rand( gl_FragCoord.xy );\\n\\t\\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\\n\\t\\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\\n\\t\\treturn color + dither_shift_RGB;\\n\\t}\\n#endif\";\n\nvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.g;\\n#endif\";\n\nvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\nvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tstruct DirectionalLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tstruct SpotLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tstruct PointLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t\\tfloat shadowCameraNear;\\n\\t\\t\\tfloat shadowCameraFar;\\n\\t\\t};\\n\\t\\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\\n\\t\\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\\n\\t}\\n\\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\\n\\t\\tfloat occlusion = 1.0;\\n\\t\\tvec2 distribution = texture2DDistribution( shadow, uv );\\n\\t\\tfloat hard_shadow = step( compare , distribution.x );\\n\\t\\tif (hard_shadow != 1.0 ) {\\n\\t\\t\\tfloat distance = compare - distribution.x ;\\n\\t\\t\\tfloat variance = max( 0.00000, distribution.y * distribution.y );\\n\\t\\t\\tfloat softness_probability = variance / (variance + distance * distance );\\t\\t\\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\\t\\t\\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\\n\\t\\t}\\n\\t\\treturn occlusion;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tfloat shadow = 1.0;\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx2 = dx0 / 2.0;\\n\\t\\t\\tfloat dy2 = dy0 / 2.0;\\n\\t\\t\\tfloat dx3 = dx1 / 2.0;\\n\\t\\t\\tfloat dy3 = dy1 / 2.0;\\n\\t\\t\\tshadow = (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 17.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx = texelSize.x;\\n\\t\\t\\tfloat dy = texelSize.y;\\n\\t\\t\\tvec2 uv = shadowCoord.xy;\\n\\t\\t\\tvec2 f = fract( uv * shadowMapSize + 0.5 );\\n\\t\\t\\tuv -= f * texelSize;\\n\\t\\t\\tshadow = (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.x ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.x ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.y ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.y ) +\\n\\t\\t\\t\\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t\\t f.x ),\\n\\t\\t\\t\\t\\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t\\t f.x ),\\n\\t\\t\\t\\t\\t f.y )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_VSM )\\n\\t\\t\\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#else\\n\\t\\t\\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn shadow;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\\t\\tdp += shadowBias;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tstruct DirectionalLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tstruct SpotLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tstruct PointLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t\\tfloat shadowCameraNear;\\n\\t\\t\\tfloat shadowCameraFar;\\n\\t\\t};\\n\\t\\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t#endif\\n#endif\";\n\nvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\tvec4 shadowWorldPosition;\\n\\t#endif\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n#endif\";\n\nvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\tDirectionalLightShadow directionalLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\tSpotLightShadow spotLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tspotLight = spotLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\tPointLightShadow pointLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tpointLight = pointLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\";\n\nvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\nvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform highp sampler2D boneTexture;\\n\\t\\tuniform int boneTextureSize;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureSize ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureSize ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureSize );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureSize );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\";\n\nvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\ttransformed = ( bindMatrixInverse * skinned ).xyz;\\n#endif\";\n\nvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n\\t#ifdef USE_TANGENT\\n\\t\\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\\n\\t#endif\\n#endif\";\n\nvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\nvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\nvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n\\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\";\n\nvar tonemapping_pars_fragment = \"#ifndef saturate\\n#define saturate( a ) clamp( a, 0.0, 1.0 )\\n#endif\\nuniform float toneMappingExposure;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\nvec3 RRTAndODTFit( vec3 v ) {\\n\\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\\n\\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\\n\\treturn a / b;\\n}\\nvec3 ACESFilmicToneMapping( vec3 color ) {\\n\\tconst mat3 ACESInputMat = mat3(\\n\\t\\tvec3( 0.59719, 0.07600, 0.02840 ),\\t\\tvec3( 0.35458, 0.90834, 0.13383 ),\\n\\t\\tvec3( 0.04823, 0.01566, 0.83777 )\\n\\t);\\n\\tconst mat3 ACESOutputMat = mat3(\\n\\t\\tvec3( 1.60475, -0.10208, -0.00327 ),\\t\\tvec3( -0.53108, 1.10813, -0.07276 ),\\n\\t\\tvec3( -0.07367, -0.00605, 1.07602 )\\n\\t);\\n\\tcolor *= toneMappingExposure / 0.6;\\n\\tcolor = ACESInputMat * color;\\n\\tcolor = RRTAndODTFit( color );\\n\\tcolor = ACESOutputMat * color;\\n\\treturn saturate( color );\\n}\\nvec3 CustomToneMapping( vec3 color ) { return color; }\";\n\nvar transmission_fragment = \"#ifdef USE_TRANSMISSION\\n\\tfloat transmissionAlpha = 1.0;\\n\\tfloat transmissionFactor = transmission;\\n\\tfloat thicknessFactor = thickness;\\n\\t#ifdef USE_TRANSMISSIONMAP\\n\\t\\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\\n\\t#endif\\n\\t#ifdef USE_THICKNESSMAP\\n\\t\\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\\n\\t#endif\\n\\tvec3 pos = vWorldPosition;\\n\\tvec3 v = normalize( cameraPosition - pos );\\n\\tvec3 n = inverseTransformDirection( normal, viewMatrix );\\n\\tvec4 transmission = getIBLVolumeRefraction(\\n\\t\\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\\n\\t\\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\\n\\t\\tattenuationColor, attenuationDistance );\\n\\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\\n\\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\\n#endif\";\n\nvar transmission_pars_fragment = \"#ifdef USE_TRANSMISSION\\n\\tuniform float transmission;\\n\\tuniform float thickness;\\n\\tuniform float attenuationDistance;\\n\\tuniform vec3 attenuationColor;\\n\\t#ifdef USE_TRANSMISSIONMAP\\n\\t\\tuniform sampler2D transmissionMap;\\n\\t#endif\\n\\t#ifdef USE_THICKNESSMAP\\n\\t\\tuniform sampler2D thicknessMap;\\n\\t#endif\\n\\tuniform vec2 transmissionSamplerSize;\\n\\tuniform sampler2D transmissionSamplerMap;\\n\\tuniform mat4 modelMatrix;\\n\\tuniform mat4 projectionMatrix;\\n\\tvarying vec3 vWorldPosition;\\n\\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\\n\\t\\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\\n\\t\\tvec3 modelScale;\\n\\t\\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\\n\\t\\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\\n\\t\\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\\n\\t\\treturn normalize( refractionVector ) * thickness * modelScale;\\n\\t}\\n\\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\\n\\t\\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\\n\\t}\\n\\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\\n\\t\\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\\n\\t\\t#ifdef texture2DLodEXT\\n\\t\\t\\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\\n\\t\\t#else\\n\\t\\t\\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\\n\\t\\t#endif\\n\\t}\\n\\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\\n\\t\\tif ( attenuationDistance == 0.0 ) {\\n\\t\\t\\treturn radiance;\\n\\t\\t} else {\\n\\t\\t\\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\\n\\t\\t\\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\\t\\t\\treturn transmittance * radiance;\\n\\t\\t}\\n\\t}\\n\\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\\n\\t\\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\\n\\t\\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\\n\\t\\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\\n\\t\\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\\n\\t\\tvec3 refractedRayExit = position + transmissionRay;\\n\\t\\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\\n\\t\\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\\n\\t\\trefractionCoords += 1.0;\\n\\t\\trefractionCoords /= 2.0;\\n\\t\\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\\n\\t\\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\\n\\t\\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\\n\\t\\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\\n\\t}\\n#endif\";\n\nvar uv_pars_fragment = \"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\\n\\tvarying vec2 vUv;\\n#endif\";\n\nvar uv_pars_vertex = \"#ifdef USE_UV\\n\\t#ifdef UVS_VERTEX_ONLY\\n\\t\\tvec2 vUv;\\n\\t#else\\n\\t\\tvarying vec2 vUv;\\n\\t#endif\\n\\tuniform mat3 uvTransform;\\n#endif\";\n\nvar uv_vertex = \"#ifdef USE_UV\\n\\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\\n#endif\";\n\nvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\nvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n\\tuniform mat3 uv2Transform;\\n#endif\";\n\nvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\\n#endif\";\n\nvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\\n\\tvec4 worldPosition = vec4( transformed, 1.0 );\\n\\t#ifdef USE_INSTANCING\\n\\t\\tworldPosition = instanceMatrix * worldPosition;\\n\\t#endif\\n\\tworldPosition = modelMatrix * worldPosition;\\n#endif\";\n\nconst vertex$g = \"varying vec2 vUv;\\nuniform mat3 uvTransform;\\nvoid main() {\\n\\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\\n\\tgl_Position = vec4( position.xy, 1.0, 1.0 );\\n}\";\n\nconst fragment$g = \"uniform sampler2D t2D;\\nvarying vec2 vUv;\\nvoid main() {\\n\\tgl_FragColor = texture2D( t2D, vUv );\\n\\t#ifdef DECODE_VIDEO_TEXTURE\\n\\t\\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\\n\\t#endif\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$f = \"varying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvWorldDirection = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n\\tgl_Position.z = gl_Position.w;\\n}\";\n\nconst fragment$f = \"#include \\nuniform float opacity;\\nvarying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvec3 vReflect = vWorldDirection;\\n\\t#include \\n\\tgl_FragColor = envColor;\\n\\tgl_FragColor.a *= opacity;\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$e = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvarying vec2 vHighPrecisionZW;\\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#ifdef USE_DISPLACEMENTMAP\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvHighPrecisionZW = gl_Position.zw;\\n}\";\n\nconst fragment$e = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvarying vec2 vHighPrecisionZW;\\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( fragCoordZ );\\n\\t#endif\\n}\";\n\nconst vertex$d = \"#define DISTANCE\\nvarying vec3 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#ifdef USE_DISPLACEMENTMAP\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition.xyz;\\n}\";\n\nconst fragment$d = \"#define DISTANCE\\nuniform vec3 referencePosition;\\nuniform float nearDistance;\\nuniform float farDistance;\\nvarying vec3 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tfloat dist = length( vWorldPosition - referencePosition );\\n\\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\\n\\tdist = saturate( dist );\\n\\tgl_FragColor = packDepthToRGBA( dist );\\n}\";\n\nconst vertex$c = \"varying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvWorldDirection = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$c = \"uniform sampler2D tEquirect;\\nvarying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldDirection );\\n\\tvec2 sampleUV = equirectUv( direction );\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$b = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvLineDistance = scale * lineDistance;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$b = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$a = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$a = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\t\\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$9 = \"#define LAMBERT\\nvarying vec3 vLightFront;\\nvarying vec3 vIndirectFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n\\tvarying vec3 vIndirectBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$9 = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\nvarying vec3 vIndirectFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n\\tvarying vec3 vIndirectBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vIndirectFront;\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include